first commit

This commit is contained in:
Rainer 2025-08-22 02:06:00 +02:00
commit e2a1f8ac7d
23 changed files with 1646 additions and 0 deletions

80
README.md Normal file
View file

@ -0,0 +1,80 @@
# Points of Interest
A Mod for Minetest.
![Screenshot 1](textures/minetest_poi_screenshot.jpg)
This Mod adds PoI's, Point's of Interest to your World.
If you have set a PoI, you can everytime jump back to the PoI with a simple Chatcommand or easy with the GUI.
### /poi_list [-a] [-f] [-c] [-i <Number>]
Lists Points of Interest.<br>
Option -a: List all Points of Interest with Coordinates<br>
Option -f: Lists forbidden Chars or Names<br>
Option -c: Lists the Categories of PoI's<br>
Option -i <Number>: Lists all Entrys of the given Categorienumber or Categoriename<br>
### /poi_jump [Name]
Jumps to a Point of Interest.
### /poi_gui
Opens a simple GUI, where you can Double-Click the Points to Jump.
### This commands demands the Priv "poi":
### /poi_set [Name][, Categorie[number]]
Set's a new Point of Interest. You can't overwrite an existing POI.<br>
If you don't set a Categorienumber or Categoriename, it will given 1 by default.<br>
You can change the Categorie of an Point, if you set the Point with a different Categorienumber or Categoriename.<br>
This Action will be logged.
### /poi_delete [Name]
Deletes a Point of Interest. You can't delete an unknown POI.<br>
This Action will be logged.
### /poi_move [Name]
This command overwrites the Coordinates of the given POI with your current Coordinates.<br>
This Action will be logged.
### /poi_rename [Name1],[Name2]
This command renames an existing Point [Name1] of Interest to Point of Interest [Name2]. [Name2] can't have the name of an already existing Point.<br>
This Action will be logged.
### /poi_reload
If the List of POI's are in any kind corrupted, you can reload the List without a new Serverstart.
### /poi_validate
Checks the List of Entrys for invalid Names or Positions. If found an Entry, the command deletes it.<br>
This Function checks the Entries for a Categorienumber, if there is no, it sets to 1 per default.<br>
This Action will be logged.
As Admin, you can grant Privs for the Player.
## Privileges
### interact:<br>
/poi_jump [name]<br>
/poi_list [-a] [-f] [-c] [-i <Categorie[number>]]<br>
/poi_gui<br>
### poi:<br>
/poi_set [name][, Categorie[number]]<br>
/poi_delete [name]<br>
/poi_reload<br>
/poi_move [name]<br>
/poi_rename [name1], [name2]<br>
/poi_validate<br><br>
With this Privileg, you have access to the grafical POI-Manager:
![Screenshot 2](textures/minetest_poi_manager.jpg)
## Install
Move your Download to the Mods-Folder.
## Depends
none
## License
License: cc0-1.0

22
categories.lua Normal file
View file

@ -0,0 +1,22 @@
-- Load support for intllib.
S = poi.get_translator
--[[
**************************
** Categories for PoI **
**************************
--]]
poi_categories = {
S("General"),
S("Village"),
S("Building"),
S("Market"),
S("Landscape"),
S("Cave"),
S("Recreation"),
S("Bank"),
S("Post"),
S("Station"),
S("Street")
}

3
depends.txt Normal file
View file

@ -0,0 +1,3 @@
intllib?
unified_inventory?

217
init.lua Normal file
View file

@ -0,0 +1,217 @@
-- =================================================================
-- 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()

45
intllib.lua Normal file
View file

@ -0,0 +1,45 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

30
license.md Normal file
View file

@ -0,0 +1,30 @@
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
moral rights retained by the original author(s) and/or performer(s);
publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
rights protecting the extraction, dissemination, use and reuse of data in a Work;
database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.

373
locale/de_DE.pot Normal file
View file

@ -0,0 +1,373 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# acm <undertakers_help@yahoo.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-12-24 03:51+0100\n"
"PO-Revision-Date: 2019-11-21 17:59+0100\n"
"Last-Translator: acm <undertakers_help@yahoo.com>\n"
"Language-Team: German <kde-i18n-de@kde.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 19.08.3\n"
#: categories.lua
msgid "General"
msgstr "Allgemein"
#: categories.lua
msgid "Buildings"
msgstr "Gebäude"
#: categories.lua
msgid "Markets"
msgstr "Märkte"
#: categories.lua
msgid "Landscapes"
msgstr "Landschaften"
#: categories.lua
msgid "Caves"
msgstr "Höhlen"
#: categories.lua
msgid "Museums"
msgstr "Museen"
#: categories.lua
msgid "Education"
msgstr "Schulen"
#: categories.lua
msgid "Recreation"
msgstr "Freizeit"
#: init.lua
msgid "Player may set and manage Points of Interest."
msgstr "Spieler dürfen interessante Orte setzen und verwalten."
#: init.lua
msgid " Filter in List."
msgstr "Filter in Liste."
#: init.lua
msgid " Categories in List."
msgstr "Kategorien in Liste."
#: init.lua
msgid "Points of Interest in category "
msgstr "Interessanter Punkt in Kategorie "
#: init.lua
msgid " are:"
msgstr " sind:"
#: init.lua
msgid " Points of Interest are:"
msgstr " Interessante Punkte sind:"
#: init.lua
msgid " Category: "
msgstr " Kategorie: "
#: init.lua
msgid "Given category doesn't exist."
msgstr "Angegebene Kategorie existiert nicht."
#: init.lua
msgid " has changed the POI: "
msgstr " hat folgenden POI verändert: "
#: init.lua
msgid " at "
msgstr " bei "
#: init.lua
msgid " to category: "
msgstr " zur Kategorie: "
#: init.lua
msgid " in category: "
msgstr " in der Kategorie: "
#: init.lua
msgid " changed to category: "
msgstr " verändert zur Kategorie: "
#: init.lua
msgid "> in category <"
msgstr "> in Kategorie <"
#: init.lua
msgid "> already exists."
msgstr "> gibt es bereits."
#: init.lua
msgid "Invalid or Forbidden Name <"
msgstr " Ungültiger oder verbotener Name <"
#: init.lua
msgid "> for POI."
msgstr "> für POI."
#: init.lua
msgid "Warning: Unkown category, setting to category 1."
msgstr "Warnung: Unbekannte Kategorie, auf Kategorie 1 gesetzt."
#: init.lua
msgid " has set the POI: "
msgstr " hat den POI gesetzt: "
#: init.lua
msgid " stored."
msgstr " gespeichert."
#: init.lua
msgid "Name of the POI needed."
msgstr "Name des POI benötigt."
#: init.lua
msgid "> unknown to delete."
msgstr "> unbekannt um zu löschen."
#: init.lua
msgid " has deleted POI-Name: "
msgstr " hat folgenden POI gelöscht: "
#: init.lua
msgid " deleted."
msgstr " gelöscht."
#: init.lua
msgid "POI-List reloaded."
msgstr "POI-Liste neu geladen."
#: init.lua
msgid "Unknown Point of Interest: "
msgstr "Unbekannter interessanter Ort: "
#: init.lua
msgid "You are moved to POI: "
msgstr "Du wurdest zu folgendem POI teleportiert: "
#: init.lua
msgid "Manage_PoI]"
msgstr "Verwalte POI"
#: init.lua
msgid " Points in List]"
msgstr " Punkte in Liste]"
#: init.lua
msgid "Categories ]"
msgstr " Kategorien ]"
#: init.lua
msgid "Go]"
msgstr "Los]"
#: init.lua
msgid "ShowAll]"
msgstr "ZeigeAlles]"
#: init.lua
msgid "Quit]"
msgstr "Ende]"
#: init.lua
msgid "Doubleclick on destination to teleport"
msgstr "Doppelklick auf Ziel zum Teleportieren"
#: init.lua
msgid "Reload"
msgstr "Neu laden"
#: init.lua
msgid "Validate"
msgstr "Überprüfen"
#: init.lua
msgid "Set Point or change category"
msgstr "Erstelle Punkt oder ändere die Kategorie"
#: init.lua
msgid "Rename"
msgstr "Umbenennen"
#: init.lua
msgid "Move"
msgstr "Verschieben"
#: init.lua
msgid "Quit"
msgstr "Ende"
#: init.lua
msgid "Back"
msgstr "Zurück"
#: init.lua
msgid " >>> Sorry this button is for admin only, please use /poi_delete "
msgstr " Entschuldige, dieser Knopf ist nur für Admins, bitte verwende /poi_delete "
#: init.lua
msgid "Unknown POI <"
msgstr "Unbekannter POI <"
#: init.lua
msgid " has moved the POI: "
msgstr " hat folgenden POI verschoben: "
#: init.lua
msgid " to Position: "
msgstr " auf Position: "
#: init.lua
msgid " moved to Position: "
msgstr " verschoben zu Position: "
#: init.lua
msgid "/poi_rename: No new name for Point given."
msgstr "/poi_rename: Keinen neuen Namen für Punkt angegeben."
#: init.lua
msgid "Point to rename not found."
msgstr "Punkt zum Umbenennen nicht gefunden."
#: init.lua
msgid "New name of POI is invalid."
msgstr "Neuer Name für POI ist ungültig."
#: init.lua
msgid "New name of POI already exists."
msgstr "Neuer Name für POI existiert bereits."
#: init.lua
msgid " has renamed POI-Name: "
msgstr "hat folgenden POI umbenannt: "
#: init.lua
msgid " to: "
msgstr " zu: "
#: init.lua
msgid " - Position: "
msgstr " - Position: "
#: init.lua
msgid "POI-Name: "
msgstr "POI-Name: "
#: init.lua
msgid " renamed to "
msgstr " umbenannt zu "
#: init.lua
msgid " invalid POIs found and deleted."
msgstr " ungültige POIs gefunden und gelöscht."
#: init.lua
msgid " POIs with an invalid category found and set to 1."
msgstr " POIs mit ungültiger Kategorie gefunden und auf 1 gesetzt."
#: init.lua
msgid "No invalid POI found."
msgstr "Keinen ungültigen POI gefunden."
#: init.lua
msgid "<poi_name, category[number]>"
msgstr "<poi_name, Kategorie[nummer]>"
#: init.lua
msgid ""
"Sets a Point of Interest or changes the category of an existing point."
msgstr ""
"Erstellt einen interessanten Ort oder verändert die Kategorie eines"
" existierenden interessanten Ortes."
#: init.lua
msgid "Shows POIs in a GUI."
msgstr "Zeigt POIs in einer GUI"
#: init.lua
msgid "<-a> <-c> <-f> <-i [Categorie[Number]]>"
msgstr "<-a> <-c> <-f> <-i [Kategorie[Nummer]]>"
#: init.lua
msgid ""
"Shows Points of Interest.\n"
"Option -a shows Points of Interest with Coordinates.\n"
"Option -c shows you Categories.\n"
"Option -f shows you the Namefilter\n"
"Option -i <Categorie[number]]> shows only the Entries of the given "
"Categorienumber or Name"
msgstr ""
"Zeigt interessante Orte.\n"
"Option -a zeigt interessante Orte mit Koordinaten.\n"
"Option -c zeigt dir die Kategorien.\n"
"Option -f zeigt dir den Namensfilter\n"
"Option -i <Kategorie[nummer]]> zeigt nur die Einträge der gegebenen "
"Kategorienummer oder Name"
#: init.lua
msgid "<POI-Name>"
msgstr "<POI-Name>"
#: init.lua
msgid "Deletes a Point of Interest."
msgstr "Löscht einen interessanten Ort."
#: init.lua
msgid "Reloads the list of POIs."
msgstr "Lädt die Liste der POIs neu."
#: init.lua
msgid "Jumps to the Position of the Point of Interest."
msgstr "Springt zur Position des interessanten Ortes."
#: init.lua
msgid "Changes the Position of the Point of Interest."
msgstr "Verändert die Position des interessanten Ortes."
#: init.lua
msgid "<POI Old Name>,<POI New Name>"
msgstr "<POI alter Name>,<POI neuer Name>"
#: init.lua
msgid "Changes the Name of the Point of Interest."
msgstr "Verändert den Namen interessanten Ortes."
#: init.lua
msgid "Validates the List of POIs."
msgstr "Überprüft die Liste der POIs."
#: init.lua
msgid "Show Points of Interest"
msgstr "Zeige interessante Orte"
#: init.lua
msgid "You need the"
msgstr "Du brauchst das"
#: init.lua
msgid " interact"
msgstr " interact"
#: init.lua
msgid " priv, please type"
msgstr "-Privileg, bitte gib"
#: init.lua
msgid " /rules"
msgstr " /rules"
#: init.lua
msgid " and search for the keyword"
msgstr " ein und suche nach dem Schlüsselwort"

105
locale/poi.de.tr Normal file
View file

@ -0,0 +1,105 @@
# textdomain: poi
### categories.lua ###
Buildings=Gebäude
Caves=Höhlen
Education=Schulen
# textdomain: poi
General=Allgemein
Landscapes=Landschaften
Markets=Märkte
Museums=Museen
Recreation=Freizeit
### findtext.lua ###
bar=bar
foo=foo
### init.lua ###
- Position: = - Position:
/rules= /rules
>>> Sorry this button is for admin only, please use /poi_delete = >>> Entschuldige, dieser Knopf ist nur für Admins, bitte verwende /poi_delete
Category: = Kategorie:
Categories in List.= Kategorien in Liste.
Filter in List.=Filter in Liste.
POIs with an invalid category found and set to 1.= POIs mit ungültiger Kategorie gefunden und auf 1 gesetzt.
Points of Interest are:= Interessante Punkte sind:
and search for the keyword= und suche nach dem Schlüsselwort
are:= sind:
at = bei
changed to category: = verändert zur Kategorie:
deleted.= gelöscht.
has changed the POI: = hat folgenden POI verändert:
has deleted POI-Name: = hat folgenden POI gelöscht:
has moved the POI: = hat folgenden POI verschoben:
has renamed POI-Name: =hat folgenden POI umbenannt:
has set the POI: = hat den POI gesetzt:
in category: = in der Kategorie:
interact= interact
invalid POIs found and deleted.= ungültige POIs gefunden und gelöscht.
moved to Position: = verschoben zu Position:
points in list= Punkte in Liste
priv, please type= priv, bitte gib
renamed to = umbenannt zu
stored.= gespeichert.
to category: = zur Kategorie:
to Position: = auf Position: =
to: = zu:
/poi_rename: No new name for Point given.=/poi_rename: Keinen neuen Namen für Punkt angegeben.
<-a> <-c> <-f> <-i [Categorie[Number]]>=<-a> <-c> <-f> <-i [Kategorie[Nummer]]>
<POI Old Name>,<POI New Name>=<POI alter Name>,<POI neuer Name>
<POI-Name>=<POI-Name>
<poi_name, category[number]>=<poi_name, Kategorie[nummer]>
> already exists.=> gibt es bereits.
> for POI.=> für POI.
> in category <=> in Kategorie <
> unknown to delete.=> unbekannt um zu löschen.
Back=Zurück
Categories=Kategorien
Changes the Name of the Point of Interest.=Verändert den Namen interessanten Ortes.
Changes the Position of the Point of Interest.=Verändert die Position des interessanten Ortes.
Deletes a Point of Interest.=Löscht einen interessanten Ort.
Double-click on destination to teleport=Doppelklick auf Ziel zum Teleportieren
Enter Name=Namen eingeben
Given category doesn't exist.=Angegebene Kategorie existiert nicht.
Go=Los
New name of POI is invalid.=Neuer Name für POI ist ungültig.
Invalid or Forbidden Name <= Ungültiger oder verbotener Name <
Jumps to the Position of the Point of Interest.=Springt zur Position des interessanten Ortes.
Reloads the list of POIs.=Lädt die Liste der POIs neu.
Manage PoI=Verwalte POI
Move=Verschieben
Name of the POI needed.=Name des POI benötigt.
New name of POI already exists.=Neuer Name für POI existiert bereits.
No invalid POI found.=Keinen ungültigen POI gefunden.
POI-List reloaded.=POI-Liste neu geladen.
Player may set and manage Points of Interest.=Spieler dürfen interessante Orte setzen und verwalten.
POI-Name: =POI-Name:
Point to rename not found.=Punkt zum Umbenennen nicht gefunden.
Points of Interest in category =Interessanter Punkt in Kategorie
Quit=Ende
Reload=Neu laden
Rename=Umbenennen
Set Point or change category=Erstelle Punkt oder ändere die Kategorie
Sets a Point of Interest or changes the category of an existing point.=Erstellt einen interessanten Ort oder verändert die Kategorie eines existierenden interessanten Ortes.
Show Points of Interest=Zeige interessante Orte
Show all=Zeige Alles
Shows POIs in a GUI.=Zeigt POIs in einer GUI
Shows Points of Interest.@nOption -a shows Points of Interest with Coordinates.@nOption -c shows you Categories.@nOption -f shows you the Namefilter@nOption -i <Categorie[number]> shows only the Entries of the given Categorienumber or Name=Zeigt interessante Orte.@nOption -a zeigt interessante Orte mit Koordinaten.@nOption -c zeigt die Kategorien.@nOption -f zeigt den Namensfilter.@nOption -i <Kategorie[nummer]> zeigt nur die Einträge der Kategorienummer oder Name
Unknown POI <=Unbekannter POI <
Unknown Point of Interest: =Unbekannter interessanter Ort:
Validate=Überprüfen
Validates the List of POIs.=Überprüft die Liste der POIs.
Warning: Unkown category, setting to category 1.=Warnung: Unbekannte Kategorie, auf Kategorie 1 gesetzt.
You are moved to POI: =Du wurdest zu folgendem POI teleportiert:
You need the=Du brauchst

309
locale/template.pot Normal file
View file

@ -0,0 +1,309 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-21 22:34+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: categories.lua
msgid "General"
msgstr ""
#: categories.lua
msgid "Buildings"
msgstr ""
#: categories.lua
msgid "Markets"
msgstr ""
#: categories.lua
msgid "Landscapes"
msgstr ""
#: categories.lua
msgid "Caves"
msgstr ""
#: categories.lua
msgid "Museums"
msgstr ""
#: categories.lua
msgid "Education"
msgstr ""
#: categories.lua
msgid "Recreation"
msgstr ""
#: init.lua
msgid "Player may set and manage Points of Interest."
msgstr ""
#: init.lua
msgid " Filter in List."
msgstr ""
#: init.lua
msgid " Categories in List."
msgstr ""
#: init.lua
msgid "Point's of Interest in Categorie "
msgstr ""
#: init.lua
msgid " are:"
msgstr ""
#: init.lua
msgid " Point's of Interest are:"
msgstr ""
#: init.lua
msgid " Categorie: "
msgstr ""
#: init.lua
msgid "Given Categorie don't exists."
msgstr ""
#: init.lua
msgid " has changed the POI: "
msgstr ""
#: init.lua
msgid " at "
msgstr ""
#: init.lua
msgid " to Categorie: "
msgstr ""
#: init.lua
msgid " in Categorie: "
msgstr ""
#: init.lua
msgid " changed to Categorie: "
msgstr ""
#: init.lua
msgid "> in Categorie <"
msgstr ""
#: init.lua
msgid "> already exists."
msgstr ""
#: init.lua
msgid "Invalid or Forbidden Name <"
msgstr ""
#: init.lua
msgid "> for PoI."
msgstr ""
#: init.lua
msgid "Warning: Unkown Categorie, set to Categorie 1."
msgstr ""
#: init.lua
msgid " has set the POI: "
msgstr ""
#: init.lua
msgid " stored."
msgstr ""
#: init.lua
msgid "Name of the PoI needed."
msgstr ""
#: init.lua
msgid "> unknown to delete."
msgstr ""
#: init.lua
msgid " has deleted POI-Name: "
msgstr ""
#: init.lua
msgid " deleted."
msgstr ""
#: init.lua
msgid "POI-List reloaded."
msgstr ""
#: init.lua
msgid "Unknown Point of Interest: "
msgstr ""
#: init.lua
msgid "You are moved to POI: "
msgstr ""
#: init.lua
msgid " >>> Sorry this button is for admin only, please use /poi_delete "
msgstr ""
#: init.lua
msgid "Unknown PoI <"
msgstr ""
#: init.lua
msgid " has moved the POI: "
msgstr ""
#: init.lua
msgid " to Position: "
msgstr ""
#: init.lua
msgid " moved to Position: "
msgstr ""
#: init.lua
msgid "/poi_rename: No new Name for Point given."
msgstr ""
#: init.lua
msgid "Point to rename not found."
msgstr ""
#: init.lua
msgid "Invalid new Pointname."
msgstr ""
#: init.lua
msgid "New Pointname already exists."
msgstr ""
#: init.lua
msgid " has renamed POI-Name: "
msgstr ""
#: init.lua
msgid " to: "
msgstr ""
#: init.lua
msgid " - Position: "
msgstr ""
#: init.lua
msgid "PoI-Name: "
msgstr ""
#: init.lua
msgid " renamed to "
msgstr ""
#: init.lua
msgid " invalid PoI's found and deleted."
msgstr ""
#: init.lua
msgid " PoI's with an invalid Categorie found and set to 1."
msgstr ""
#: init.lua
msgid "No invalid PoI found."
msgstr ""
#: init.lua
msgid "<poi_name, Categorie[number]>"
msgstr ""
#: init.lua
msgid ""
"Set's a Point of Interest or changes the Categorie of an existing Point."
msgstr ""
#: init.lua
msgid "Shows PoIs in a GUI."
msgstr ""
#: init.lua
msgid "<-a> <-c> <-f> <-i [Categorie[Number]]>"
msgstr ""
#: init.lua
msgid ""
"Shows Point's of Interest.\n"
"Option -a shows Point's of Interest with Coordinates.\n"
"Option -c shows you Categories.\n"
"Option -f shows you the Namefilter\n"
"Option -i <Categorie[number]]> shows only the Entries of the given "
"Categorienumber or Name"
msgstr ""
#: init.lua
msgid "<POI-Name>"
msgstr ""
#: init.lua
msgid "Deletes a Point of Interest."
msgstr ""
#: init.lua
msgid "Loads the List of POI's new."
msgstr ""
#: init.lua
msgid "Jumps to the Position of the Point of Interest."
msgstr ""
#: init.lua
msgid "Changes the Position of the Point of Interest."
msgstr ""
#: init.lua
msgid "<POI Old Name>,<POI New Name>"
msgstr ""
#: init.lua
msgid "Changes the Name of the Point of Interest."
msgstr ""
#: init.lua
msgid "Validates the List of PoI's."
msgstr ""
#: init.lua
msgid "Show Points of Interest"
msgstr ""
#: init.lua
msgid "You need the"
msgstr ""
#: init.lua
msgid " interact"
msgstr ""
#: init.lua
msgid " priv, please type"
msgstr ""
#: init.lua
msgid " /rules"
msgstr ""
#: init.lua
msgid " and search for the keyword"
msgstr ""

105
locale/template.txt Normal file
View file

@ -0,0 +1,105 @@
# textdomain: poi
### categories.lua ###
Buildings=
Caves=
Education=
# textdomain: poi
General=
Landscapes=
Markets=
Museums=
Recreation=
### findtext.lua ###
bar=
foo=
### init.lua ###
- Position: =
/rules=
>>> Sorry this button is for admin only, please use /poi_delete =
Categorie: =
Categories in List.=
Filter in List.=
PoI's with an invalid Categorie found and set to 1.=
Point's of Interest are:=
and search for the keyword=
are:=
at =
changed to Categorie: =
deleted.=
has changed the POI: =
has deleted POI-Name: =
has moved the POI: =
has renamed POI-Name: =
has set the POI: =
in Categorie: =
interact=
invalid PoI's found and deleted.=
moved to Position: =
points in list=
priv, please type=
renamed to =
stored.=
to Categorie: =
to Position: =
to: =
/poi_rename: No new Name for Point given.=
<-a> <-c> <-f> <-i [Categorie[Number]]>=
<POI Old Name>,<POI New Name>=
<POI-Name>=
<poi_name, Categorie[number]>=
> already exists.=
> for PoI.=
> in Categorie <=
> unknown to delete.=
Back=
Categories=
Changes the Name of the Point of Interest.=
Changes the Position of the Point of Interest.=
Deletes a Point of Interest.=
Double-click on destination to teleport=
Enter Name=
Given Categorie don't exists.=
Go=
Invalid new Pointname.=
Invalid or Forbidden Name <=
Jumps to the Position of the Point of Interest.=
Loads the List of POI's new.=
Manage PoI=
Move=
Name of the PoI needed.=
New Pointname already exists.=
No invalid PoI found.=
POI-List reloaded.=
Player may set and manage Points of Interest.=
PoI-Name: =
Point to rename not found.=
Point's of Interest in Categorie =
Quit=
Reload=
Rename=
Set Point or change Categorie=
Set's a Point of Interest or changes the Categorie of an existing Point.=
Show Points of Interest=
Show all=
Shows PoIs in a GUI.=
Shows Point's of Interest.@nOption -a shows Point's of Interest with Coordinates.@nOption -c shows you Categories.@nOption -f shows you the Namefilter@nOption -i <Categorie[number]> shows only the Entries of the given Categorienumber or Name=
Unknown PoI <=
Unknown Point of Interest: =
Validate=
Validates the List of PoI's.=
Warning: Unkown Categorie, set to Categorie 1.=
You are moved to POI: =
You need the=

8
mod.conf Normal file
View file

@ -0,0 +1,8 @@
name = poi
description = A mod for Tourguides and Tourists in Minetest.
optional_depends = intllib,unified_inventory
release = 12359
author = Clyde
title = Points of Interest

16
namefilter.lua Normal file
View file

@ -0,0 +1,16 @@
--[[
**************************
** Namefilter for PoI **
**************************
All Filters will be convertet to lowercase
--]]
poi_namefilter = {
"/", -- Filter to not start Commands
"{", -- Filter for Categorie
"}", -- Filter for Categorie
"\"\"", -- Like an empty Name ""
"," -- Separator for Rename, Categories
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

142
tools/findtext.lua Normal file
View file

@ -0,0 +1,142 @@
#! /usr/bin/env lua
local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
local function err(fmt, ...)
io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
os.exit(1)
end
local output
local inputs = { }
local lang
local author
local i = 1
local function usage()
print([[
Usage: ]]..me..[[ [OPTIONS] FILE...
Extract translatable strings from the given FILE(s).
Available options:
-h,--help Show this help screen and exit.
-o,--output X Set output file (default: stdout).
-a,--author X Set author.
-l,--lang X Set language name.
]])
os.exit(0)
end
while i <= #arg do
local a = arg[i]
if (a == "-h") or (a == "--help") then
usage()
elseif (a == "-o") or (a == "--output") then
i = i + 1
if i > #arg then
err("missing required argument to `%s'", a)
end
output = arg[i]
elseif (a == "-a") or (a == "--author") then
i = i + 1
if i > #arg then
err("missing required argument to `%s'", a)
end
author = arg[i]
elseif (a == "-l") or (a == "--lang") then
i = i + 1
if i > #arg then
err("missing required argument to `%s'", a)
end
lang = arg[i]
elseif a:sub(1, 1) ~= "-" then
table.insert(inputs, a)
else
err("unrecognized option `%s'", a)
end
i = i + 1
end
if #inputs == 0 then
err("no input files")
end
local outfile = io.stdout
local function printf(fmt, ...)
outfile:write(fmt:format(...))
end
if output then
local e
outfile, e = io.open(output, "w")
if not outfile then
err("error opening file for writing: %s", e)
end
end
if author or lang then
outfile:write("\n")
end
if lang then
printf("# Language: %s\n", lang)
end
if author then
printf("# Author: %s\n", author)
end
if author or lang then
outfile:write("\n")
end
local escapes = {
["\n"] = "\\n",
["="] = "\\=",
["\\"] = "\\\\",
}
local function escape(s)
return s:gsub("[\\\n=]", escapes)
end
local messages = { }
for _, file in ipairs(inputs) do
local infile, e = io.open(file, "r")
if infile then
for line in infile:lines() do
for s in line:gmatch('S%("([^"]*)"') do
table.insert(messages, s)
end
end
infile:close()
else
io.stderr:write(("%s: WARNING: error opening file: %s\n"):format(me, e))
end
end
table.sort(messages)
local last_msg
for _, msg in ipairs(messages) do
if msg ~= last_msg then
printf("%s =\n", escape(msg))
end
last_msg = msg
end
if output then
outfile:close()
end
--[[
TESTS:
S("foo") S("bar")
S("bar")
S("foo")
]]

131
tools/updatetext.lua Normal file
View file

@ -0,0 +1,131 @@
#! /usr/bin/env lua
local basedir = ""
if arg[0]:find("[/\\]") then
basedir = arg[0]:gsub("(.*[/\\]).*$", "%1"):gsub("\\", "/")
end
if basedir == "" then basedir = "./" end
-- Required by load_strings()
function string.trim(s) -- luacheck: ignore
return s:gsub("^%s*(.-)%s*$", "%1")
end
dofile(basedir.."/../lib.lua")
local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
local function err(fmt, ...)
io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
os.exit(1)
end
local output, outfile, template
local catalogs = { }
local function usage()
print([[
Usage: ]]..me..[[ [OPTIONS] TEMPLATE CATALOG...
Update a catalog with new strings from a template.
Available options:
-h,--help Show this help screen and exit.
-o,--output X Set output file (default: stdout).
Messages in the template that are not on the catalog are added to the
catalog at the end.
This tool also checks messages that are in the catalog but not in the
template, and reports such lines. It's up to the user to remove such
lines, if so desired.
]])
os.exit(0)
end
local i = 1
while i <= #arg do
local a = arg[i]
if (a == "-h") or (a == "--help") then
usage()
elseif (a == "-o") or (a == "--output") then
i = i + 1
if i > #arg then
err("missing required argument to `%s'", a)
end
output = arg[i]
elseif a:sub(1, 1) ~= "-" then
if not template then
template = a
else
table.insert(catalogs, a)
end
else
err("unrecognized option `%s'", a)
end
i = i + 1
end
if not template then
err("no template specified")
elseif #catalogs == 0 then
err("no catalogs specified")
end
local f, e = io.open(template, "r")
if not f then
err("error opening template: %s", e)
end
local escapes = { ["\n"] = "\\n", ["="] = "\\=", ["\\"] = "\\\\", }
local function escape(s)
return s:gsub("[\\\n=]", escapes)
end
if output then
outfile, e = io.open(output, "w")
if not outfile then
err("error opening file for writing: %s", e)
end
end
local template_msgs = intllib.load_strings(template)
for _, file in ipairs(catalogs) do
print("Processing: "..file)
local catalog_msgs = intllib.load_strings(file)
local dirty_lines = { }
if catalog_msgs then
-- Add new entries from template.
for k in pairs(template_msgs) do
if not catalog_msgs[k] then
print("NEW: "..k)
table.insert(dirty_lines, escape(k).." =")
end
end
-- Check for old messages.
for k, v in pairs(catalog_msgs) do
if not template_msgs[k] then
print("OLD: "..k)
table.insert(dirty_lines, "OLD: "..escape(k).." = "..escape(v))
end
end
if #dirty_lines > 0 then
local outf
outf, e = io.open(file, "a+")
if outf then
outf:write("\n")
for _, line in ipairs(dirty_lines) do
outf:write(line)
outf:write("\n")
end
outf:close()
else
io.stderr:write(("%s: WARNING: cannot write: %s\n"):format(me, e))
end
end
else
io.stderr:write(("%s: WARNING: could not load catalog\n"):format(me))
end
end

33
tools/xgettext.bat Normal file
View file

@ -0,0 +1,33 @@
@echo off
setlocal
set me=%~n0
rem # Uncomment the following line if gettext is not in your PATH.
rem # Value must be absolute and end in a backslash.
rem set gtprefix=C:\path\to\gettext\bin\
if "%1" == "" (
echo Usage: %me% FILE... 1>&2
exit 1
)
set xgettext=%gtprefix%xgettext.exe
set msgmerge=%gtprefix%msgmerge.exe
md locale > nul 2>&1
echo Generating template... 1>&2
echo %xgettext% --from-code=UTF-8 -kS -kNS:1,2 -k_ -o locale/template.pot %*
%xgettext% --from-code=UTF-8 -kS -kNS:1,2 -k_ -o locale/template.pot %*
if %ERRORLEVEL% neq 0 goto done
cd locale
for %%f in (*.po) do (
echo Updating %%f... 1>&2
%msgmerge% --update %%f template.pot
)
echo DONE! 1>&2
:done

27
tools/xgettext.sh Normal file
View file

@ -0,0 +1,27 @@
#! /bin/bash
me=$(basename "${BASH_SOURCE[0]}");
if [[ $# -lt 1 ]]; then
echo "Usage: $me FILE..." >&2;
exit 1;
fi
mkdir -p locale;
echo "Generating template..." >&2;
xgettext --from-code=UTF-8 \
--keyword=S \
--keyword=NS:1,2 \
--keyword=N_ \
--add-comments='Translators:' \
--add-location=file \
-o locale/template.pot \
"$@" \
|| exit;
find locale -name '*.po' -type f | while read -r file; do
echo "Updating $file..." >&2;
msgmerge --update "$file" locale/template.pot;
done
echo "DONE!" >&2;