1113 lines
30 KiB
Lua
1113 lines
30 KiB
Lua
poi_namefilter = {}
|
|
poi_categories = {}
|
|
|
|
local storage = minetest.get_mod_storage() -- initalize storage file of this mod. This can only happen here and should be always local
|
|
poi = {
|
|
|
|
points = {},
|
|
filter = {},
|
|
categories = {},
|
|
modpath = minetest.get_modpath(minetest.get_current_modname()),
|
|
modname = minetest.get_current_modname()
|
|
}
|
|
|
|
-- Load support for intllib.
|
|
local S
|
|
|
|
if(minetest.get_modpath("intllib")) then
|
|
S = dofile(poi.modpath .."/intllib.lua")
|
|
print("[MOD] " .. poi.modname .. ": translating in intllib-mode.")
|
|
|
|
else
|
|
S = minetest.get_translator(poi.modname)
|
|
print("[MOD] " .. poi.modname .. ": translating in minetest-mode.")
|
|
|
|
end -- if(minetest.get_modpath(
|
|
|
|
poi.get_translator = S
|
|
|
|
dofile(poi.modpath .. "/namefilter.lua") -- avoid servercrash loop if someone decided to rename the modfolder !
|
|
dofile(poi.modpath .. "/categories.lua")
|
|
|
|
-- Options for Print_Message
|
|
local log = 0
|
|
local green = '#00FF00'
|
|
local red = '#FF0000'
|
|
local orange = '#FF6700'
|
|
local none = 99
|
|
|
|
-- Options for Categories and Gui management
|
|
local call_list = {} -- important array to find jump station in lists reduced by categories
|
|
local lastchoice = "" -- last choosen destination from gui by single_click (android support and useful for extended gui in the future)
|
|
local selected_category = 0
|
|
local choosen_name = 0
|
|
local selected_point = ""
|
|
local drop_down = 0
|
|
local catlist = ""
|
|
|
|
|
|
minetest.register_privilege("poi", S("Player may set and manage Points of Interest."))
|
|
|
|
|
|
--[[
|
|
********************************************
|
|
*** Functions of POI ***
|
|
********************************************
|
|
--]]
|
|
|
|
-- Loads the List of POI's
|
|
function poi.openlist()
|
|
|
|
local load = storage:to_table()
|
|
poi.points = load.fields
|
|
|
|
end -- poi.openlist()
|
|
|
|
|
|
-- Writes the List of POI's
|
|
function poi.save()
|
|
|
|
storage:from_table({fields=poi.points})
|
|
|
|
end -- poi.save()
|
|
|
|
-- Helpfunctions for the List-Command
|
|
function poi.list_filter(name)
|
|
local list = ""
|
|
local index = 0
|
|
|
|
for key, value in pairs(poi.filter) do
|
|
list = list .. key .. ": " .. value .. "\n"
|
|
index = index + 1
|
|
|
|
end -- for key, value
|
|
|
|
poi.print(name, list, orange)
|
|
poi.print(name, index .. S(" Filter in List."), green)
|
|
|
|
end -- poi.list_filter()
|
|
|
|
function poi.list_categories(name)
|
|
local list = ""
|
|
local index = 0
|
|
|
|
for key, value in pairs(poi.categories) do
|
|
list = list .. key .. ": " .. value .. "\n"
|
|
index = index + 1
|
|
|
|
end -- for key,value
|
|
|
|
poi.print(name, list, orange) -- Send List to Player
|
|
poi.print(name, index .. S(" Categories in List."), green) -- Send List to Player
|
|
|
|
end -- poi.list_categories()
|
|
|
|
-- List the POI's with an optional Arg
|
|
function poi.list(name, option)
|
|
|
|
local list = ""
|
|
local all = false -- is option list all set?
|
|
local pos, cat
|
|
local idx = 0 -- a given Index with the option -i <number>
|
|
|
|
-- Check Options for the Command List
|
|
|
|
-- Lists only Filterwords
|
|
if string.find(string.lower(option), "-f") ~= nil then
|
|
poi.list_filter(name)
|
|
return true
|
|
|
|
end
|
|
|
|
-- Lists only the Categories
|
|
if string.find(string.lower(option), "-c") ~= nil then
|
|
poi.list_categories(name)
|
|
return true
|
|
end
|
|
|
|
-- List the full Entries of PoI's
|
|
if string.find(string.lower(option), "-a") ~= nil then
|
|
all = true
|
|
|
|
end
|
|
|
|
if string.find(string.lower(option), "-i") ~= nil then
|
|
idx = tonumber(string.sub(string.lower(option), string.find(string.lower(option), "-i") + 2, -1))
|
|
if(idx == nil) then -- Option wan't a Number, then try to find out the Categorie by Name
|
|
idx = poi.get_categorienumber(poi.trim(string.sub(string.lower(option), string.find(string.lower(option), "-i") + 2, -1)))
|
|
|
|
end
|
|
|
|
idx = idx or 0 -- Convert a invalid Number to 0
|
|
end
|
|
|
|
if (idx > 0) then
|
|
poi.print(name, S("Points of Interest in category ") .. poi.get_categoriename(idx) .. S(" are:"), green)
|
|
|
|
else
|
|
poi.print(name, poi.count() .. S(" Points of Interest are:"), green)
|
|
|
|
end -- if(idx > 0)
|
|
|
|
for key, value in poi.spairs(poi.points) do -- Build up the List
|
|
pos, cat = poi.split_pos_cat(value)
|
|
if(idx > 0) then
|
|
if(cat == idx) then
|
|
if all then
|
|
list = list .. key .. ": " .. pos .. "\n"
|
|
|
|
else
|
|
list = list .. key .. "\n"
|
|
|
|
end -- if all
|
|
|
|
end -- if (key == idx)
|
|
|
|
else -- if(idx > 0)
|
|
if all then
|
|
list = list .. key .. ": " .. pos .. S(" Category: ") .. poi.get_categoriename(cat) .. "\n"
|
|
|
|
else
|
|
list = list .. key .. "\n"
|
|
|
|
end -- if(all)
|
|
|
|
end -- if(key == idx)
|
|
|
|
end -- for key,value
|
|
|
|
poi.print(name, list, orange) -- Send List to Player
|
|
return true
|
|
|
|
end -- poi.list()
|
|
|
|
-- Set's a POI
|
|
function poi.set(name, poi_name)
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
local currpos = player:getpos(name)
|
|
local currdir = { pitch = player:get_look_vertical(), yaw = player:get_look_horizontal() }
|
|
local categorie, p_name
|
|
|
|
p_name, categorie = poi.split_option(poi_name)
|
|
|
|
-- Check Categorie, if Unknown then set it to General
|
|
if categorie == 0 then categorie = 1
|
|
end
|
|
|
|
if poi.exist(p_name) then -- Ups, Name exists
|
|
if(poi.get_categorie(p_name) ~= categorie) then -- ok, we want to change the Categorie
|
|
if(categorie == -1) then -- Invalid Categoriename?
|
|
poi.print(name, S("Given category doesn't exist."), red)
|
|
return false
|
|
|
|
end -- if(poi.get_categoriename())
|
|
|
|
local value = poi.points[p_name]
|
|
local pos, cat
|
|
pos, cat, dir = poi.split_pos_cat(poi.points[p_name])
|
|
poi.points[p_name] = poi.combine_pos_cat(pos, categorie, dir) -- Changes the Entry
|
|
poi.print(name, name .. S(" has changed the POI: ") .. p_name .. S(" at ") .. pos .. S(" category: ") .. poi.get_categoriename(cat) .. S(" to category: ") .. poi.get_categoriename(categorie) .. "\n", log)
|
|
poi.print(name, "POI: " .. p_name .. S(" at ") .. pos .. S(" in category: ") .. poi.get_categoriename(cat) .. S(" changed to category: ") .. poi.get_categoriename(categorie), green)
|
|
poi.save()
|
|
return true
|
|
|
|
else
|
|
poi.print(name, "PoI <" .. p_name .. S("> in category <") .. categorie .. " - " .. poi.get_categoriename(categorie) .. S("> already exists."), red)
|
|
return false -- Name exists, leave function
|
|
|
|
end -- if(poi.get_categorie)
|
|
|
|
end -- if poi.exist
|
|
|
|
if not poi.check_name(p_name) then
|
|
poi_name = poi.convertnil(poi_name) -- convert possible NIL
|
|
poi.print(name, S("Invalid or Forbidden Name <") .. p_name .. S("> for POI."), red)
|
|
return false
|
|
|
|
end -- if poi.check_name
|
|
|
|
if(categorie == -1) then -- Checks invalid Categoriename, then set it on new Entry to 1
|
|
poi.print(name, S("Warning: Unkown category, setting to category 1."), red)
|
|
categorie = 1
|
|
end
|
|
|
|
poi.points[p_name] = poi.combine_pos_cat(currpos, categorie, currdir)-- Insert the new Entry
|
|
poi.save() -- and write the new List
|
|
|
|
poi.print(name, name .. S(" has set the POI: ") .. p_name .. S(" at ") .. minetest.pos_to_string(currpos) .. S(" Categorie: ") .. "{" .. poi.get_categoriename(categorie) .. "}\n", log)
|
|
poi.print(name, "POI: " .. p_name .. S(" at ") .. minetest.pos_to_string(currpos) .. S(" in Categorie: ") .. poi.get_categoriename(categorie) .. S(" stored."), green)
|
|
return true
|
|
|
|
end -- poi.set()
|
|
|
|
-- Deletes a POI
|
|
function poi.delete(name, poi_name)
|
|
|
|
if(poi_name == nil or poi_name == "") then -- No PoI-Name given ..
|
|
|
|
poi.print(name, S("Name of the POI needed."), red)
|
|
return false -- can't delete a non-existing Entry, leave function
|
|
|
|
end
|
|
|
|
if poi.exist(poi_name) == false then
|
|
|
|
poi_name = poi.convertnil(poi_name) -- convert possible NIL
|
|
poi.print(name, "PoI <" .. poi_name .. S("> unknown to delete."), red)
|
|
return false -- can't delete a non-existing Entry, leave function
|
|
|
|
end -- if poi.exist
|
|
|
|
local list = ""
|
|
|
|
list = poi_name .. ": " .. poi.points[poi_name] -- Get the full Name of the PoI and save it in a temporary var
|
|
poi.points[poi_name] = nil -- and delete it
|
|
|
|
poi.print(name, name .. S(" has deleted POI-Name: ") .. list .. "\n", log)
|
|
poi.print(name, list .. S(" deleted."), red)
|
|
poi.save() -- Write the new list at the server
|
|
|
|
return true
|
|
|
|
end -- poi.delete()
|
|
|
|
-- Reload or Reset the List of PoI's and load it new
|
|
function poi.reload(name)
|
|
poi.points = nil -- Deletes the List of PoI's
|
|
poi.openlist() -- and Load it new
|
|
|
|
poi.print(name, S("POI-List reloaded."), red)
|
|
return true
|
|
|
|
end -- poi.reload()
|
|
|
|
-- Jumps to PoI
|
|
function poi.jump(name, poi_name)
|
|
|
|
if (poi.exist(poi_name) == false) then -- Unknown or not existing Point of Interest
|
|
poi_name = poi.convertnil(poi_name) -- convert possible NIL
|
|
poi.print(name, S("Unknown Point of Interest: ") .. poi_name .. ".", red)
|
|
return false -- POI not in List, leave function
|
|
|
|
end -- if poi.exist
|
|
|
|
local Position = poi.points[poi_name]
|
|
local direction
|
|
Position, _, direction = poi.split_pos_cat(Position) -- Extract the Position
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
lastchoice = "" -- set lastchoice back to zero
|
|
|
|
poi.play_soundeffect(name, "teleport") -- Play's a Sound
|
|
player:setpos(minetest.string_to_pos(Position)) -- Move Player to Point
|
|
if direction ~= nil then
|
|
player:set_look_vertical(direction.pitch)
|
|
player:set_look_horizontal(direction.yaw)
|
|
end
|
|
poi.print(name, S("You are moved to POI: ") .. poi_name .. ".", green)
|
|
return true
|
|
|
|
end -- poi.jump()
|
|
|
|
|
|
|
|
-- ***********************************
|
|
-- ***********************************
|
|
-- ** The Gui section starting here **
|
|
-- ***********************************
|
|
-- ***********************************
|
|
|
|
|
|
-- shows gui with all available PoIs
|
|
function poi.gui(player_name, showup, main)
|
|
local list = ""
|
|
local showcat = ""
|
|
local cat
|
|
local count = 0
|
|
local manageme = ""
|
|
|
|
|
|
|
|
for key, value in poi.spairs(poi.points) do -- Build up the List
|
|
cat = poi.get_categorie(key)
|
|
|
|
if not showup then
|
|
drop_down = 0
|
|
|
|
if list == "" then
|
|
|
|
list = key
|
|
|
|
else
|
|
|
|
list = list .. "," .. key
|
|
|
|
end
|
|
count = count +1
|
|
call_list[count] = key -- makes it easier to find jump point
|
|
else
|
|
drop_down = poi.get_categorienumber(showup)
|
|
--showcat = "label[0.6,0.4;Category is: "..showup.."]" -- show choosen categorie in gui ##not needed anymore
|
|
if poi.get_categorienumber(showup) == cat then
|
|
if list == "" then
|
|
|
|
list = key
|
|
|
|
else
|
|
|
|
list = list .. "," .. key
|
|
|
|
end
|
|
count = count +1
|
|
call_list[count] = key -- makes it easier to find jump point
|
|
end
|
|
end
|
|
|
|
end -- for key,value
|
|
|
|
if minetest.get_player_privs(player_name).poi then
|
|
manageme = "button[5,6.5;2,1;poimanager;" .. S("Manage PoI") .. "]"
|
|
end
|
|
|
|
if main then
|
|
minetest.show_formspec(player_name,"minetest_poi:thegui", -- The main gui for everyone with interact
|
|
"size[7,8]" ..
|
|
"label[0.4,0;> ".. S("Double-click on destination to teleport") .. " <]"..
|
|
--showcat..
|
|
"textlist[0.4,1;3,5;name;"..list..";selected_idx;false]"..
|
|
"label[0.6,6;".. count .. S(" points in list") .. "]" ..
|
|
"label[4.3,0.5; ".. S("Categories") .. " ]" ..
|
|
"dropdown[4,1;2,1;dname;"..catlist..";"..drop_down.."]"..
|
|
"button[0.4,6.5;1,1;poitelme;".. S("Go") .. "]" ..
|
|
"button[1.4,6.5;2,1;poishowall;" .. S("Show all") .. "]" ..manageme..
|
|
"button_exit[0.4,7.4;3.4,1;poiexit;" .. S("Quit") .. "]"
|
|
)
|
|
else
|
|
minetest.show_formspec(player_name,"minetest_poi:manager", -- The management gui for people with poi priv
|
|
"size[7,9]" ..
|
|
"textlist[0.4,0;3,5;maname;"..list..";"..choosen_name..";false]"..
|
|
"textlist[4,0;2,2;madname;"..catlist..";"..selected_category..";false]"..
|
|
"button[4,2.5;2,1;reload;" .. S("Reload") .. "]" ..
|
|
"button[4,3.5;2,1;validate;" .. S("Validate") .. "]"..
|
|
"field[0.3,5.4;7,1;managename; - ".. S("Enter Name").." -;"..selected_point.."]"..
|
|
"button[0.4,6;6,1;set;" .. S("Set Point or change category") .. "]"..
|
|
"button[0.4,7;2,1;rename;" .. S("Rename") .. "]"..
|
|
"button[2.4,7;2,1;move;" .. S("Move") .. "]"..
|
|
"image_button[5.4,7;1,1;minetest_poi_deleteme.png;delete;]"..
|
|
"button_exit[0.4,8;3,1;doexit;" .. S("Quit") .. "]"..
|
|
"button[3.4,8;3,1;goback;" .. S("Back") .. "]"
|
|
)
|
|
end
|
|
end -- poi.gui()
|
|
|
|
-- Callback for formspec
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname == "minetest_poi:thegui" and player then -- The form name and player must be online
|
|
|
|
|
|
local event = minetest.explode_textlist_event(fields.name) -- get values of what was clicked
|
|
|
|
|
|
if fields.poiexit then
|
|
lastchoice = nil
|
|
choosen_name = 0
|
|
selected_point = ""
|
|
return false
|
|
end
|
|
|
|
if fields.poishowall then
|
|
lastchoice = nil
|
|
poi.gui(player:get_player_name(), nil, true)
|
|
return false
|
|
end
|
|
|
|
if fields.poimanager then
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
return false
|
|
end
|
|
|
|
|
|
if fields.poitelme and lastchoice ~= "" then -- single click and go-Button is much easier for tablet users
|
|
poi.jump(player:get_player_name(), lastchoice)
|
|
return false
|
|
end
|
|
|
|
|
|
if (event.type == "CHG") and event.index then -- save the last choosen PoI by singleclick
|
|
lastchoice = call_list[event.index]
|
|
end
|
|
|
|
|
|
if fields.dname and fields.dname ~= "" then
|
|
poi.gui(player:get_player_name(), fields.dname, true)
|
|
end
|
|
|
|
|
|
if (event.type == "DCL") then -- DCL =doubleclick CHG = leftclick single by minetest definition
|
|
poi.jump(player:get_player_name(), call_list[event.index])
|
|
return false
|
|
end -- if event.type
|
|
|
|
|
|
|
|
end -- if formname
|
|
|
|
if formname == "minetest_poi:manager" and player then -- The form name and player must be online
|
|
|
|
local youaretheboss = minetest.get_player_privs(player:get_player_name()).server
|
|
local event = minetest.explode_textlist_event(fields.maname) -- get values of what was clicked in PoI
|
|
local catevent = minetest.explode_textlist_event(fields.madname) -- get values of what was clicked in Categories
|
|
|
|
if fields.goback then
|
|
selected_category = 0
|
|
choosen_name = 0
|
|
selected_point = ""
|
|
poi.gui(player:get_player_name(), nil, true)
|
|
return false
|
|
end
|
|
|
|
if fields.doexit then
|
|
selected_category = 0
|
|
choosen_name = 0
|
|
selected_point = ""
|
|
return false
|
|
end
|
|
|
|
if fields.reload then
|
|
poi.reload(player:get_player_name())
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
|
|
if fields.validate then
|
|
poi.validate(player:get_player_name())
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
|
|
if fields.delete then
|
|
if youaretheboss then -- Sorry I couldn't resist :D
|
|
poi.delete(player:get_player_name(),selected_point)
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
else
|
|
poi.print(player:get_player_name(),S(" >>> Sorry this button is for admin only, please use /poi_delete ")..selected_point,red)
|
|
end
|
|
end
|
|
|
|
if fields.move then
|
|
poi.move(player:get_player_name(),selected_point)
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
|
|
end
|
|
|
|
if fields.rename then
|
|
poi.rename(player:get_player_name(),selected_point..","..fields.managename)
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
|
|
if fields.managename then
|
|
choosen_name = 0
|
|
selected_point = fields.managename
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
|
|
if fields.set then
|
|
poi.set(player:get_player_name(), selected_point..","..selected_category)
|
|
selected_category = 0
|
|
choosen_name = 0
|
|
selected_point = ""
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
|
|
if (event.type == "CHG") and event.index then -- save the last choosen poi
|
|
selected_point = call_list[event.index]
|
|
choosen_name = event.index
|
|
selected_category = poi.get_categorie(selected_point)
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
|
|
if (catevent.type == "CHG") and catevent.index then -- save the last choosen category
|
|
selected_category = catevent.index
|
|
poi.gui(player:get_player_name(), nil, false)
|
|
end
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
-- *********************************
|
|
-- *********************************
|
|
-- ** The Gui section ending here **
|
|
-- *********************************
|
|
-- *********************************
|
|
|
|
-- Changes a POI-Position
|
|
function poi.move(name, poi_name)
|
|
|
|
if (poi.exist(poi_name) == false) then
|
|
poi_name = poi.convertnil(poi_name) -- convert possible NIL
|
|
poi.print(name, S("Unknown POI <") .. poi_name .. ">.", red)
|
|
return false
|
|
|
|
end -- if poi.exist
|
|
|
|
local exist = false
|
|
local player = minetest.get_player_by_name(name)
|
|
local currpos = player:getpos(name)
|
|
local currdir = { pitch = player:get_look_vertical(), yaw = player:get_look_horizontal() }
|
|
local oldpos, cat, dir = poi.split_pos_cat(poi.points[poi_name])
|
|
|
|
poi.points[poi_name] = poi.combine_pos_cat(currpos, cat, currdir) -- Write the Position new
|
|
poi.save() -- and write the List
|
|
|
|
poi.print(name, name .. S(" has moved the POI: ") .. poi_name .. S(" at ") .. oldpos .. S(" to Position: ") .. minetest.pos_to_string(currpos) .. "\n", log)
|
|
poi.print(name, "POI: " .. poi_name .. S(" at ") .. oldpos .. S(" moved to Position: ") .. minetest.pos_to_string(currpos) .."\n", green)
|
|
return true
|
|
|
|
end -- poi.move
|
|
|
|
-- Renames a POI
|
|
function poi.rename(name, poi_name)
|
|
local oldname, newname
|
|
|
|
if string.find(poi_name, ",") == nil then
|
|
poi.print(name, S("/poi_rename: No new name for Point given.") .. "\n", red)
|
|
return false
|
|
end
|
|
|
|
oldname = poi.trim(string.sub(poi_name,1, string.find(poi_name, ",")-1))
|
|
|
|
if not poi.exist(oldname) then
|
|
poi.print(name, S("Point to rename not found.") .. "\n", red)
|
|
return false
|
|
end
|
|
|
|
newname = poi.trim(string.sub(poi_name, string.find(poi_name, ",") + 1, -1))
|
|
|
|
if not poi.check_name(newname) then
|
|
poi.print(name, S("New name of POI is invalid.") .. "\n", red)
|
|
return false
|
|
end
|
|
|
|
if poi.exist(newname) then
|
|
poi.print(name, S("New name of POI already exists.") .. "\n", red)
|
|
return false
|
|
end
|
|
|
|
local old_position
|
|
old_position = poi.points[oldname] -- get the Positioni
|
|
poi.points[newname] = old_position -- and make a new entry
|
|
|
|
poi.points[oldname] = nil -- now deletes the old one
|
|
poi.save() -- saves the List
|
|
|
|
poi.print(name, name .. S(" has renamed POI-Name: ") .. oldname .. S(" to: ") .. newname .. S(" - Position: ") .. old_position .. "\n", log)
|
|
poi.print(name, S("POI-Name: ") .. oldname .. S(" renamed to ") .. newname .. S(" - Position: ") .. old_position .. "\n", green)
|
|
|
|
end -- poi.rename()
|
|
|
|
-- Check the PoI in the List? Return true if the Name exsists, else false
|
|
function poi.exist(poi_name)
|
|
local exist = true
|
|
|
|
if(poi_name == "" or poi_name == nil) then
|
|
exist = false
|
|
|
|
else
|
|
local Position = poi.points[poi_name]
|
|
if(Position == nil or Position == "") then
|
|
exist = false
|
|
|
|
end -- if Position == nil
|
|
|
|
end -- if poi_name ==
|
|
|
|
return exist
|
|
|
|
end -- poi.exist
|
|
|
|
-- Checks the List and deletes invalid Poi's
|
|
function poi.validate(name)
|
|
local count = 0 -- Value of invalid Entries
|
|
local invalid_cat = 0 -- Value of Entries without Categorie
|
|
local key, value
|
|
|
|
for key, value in pairs(poi.points) do
|
|
if not poi.check_name(key) then -- is the Name valid?
|
|
count = count + 1
|
|
poi.points[key] = nil
|
|
|
|
else
|
|
if value == nil then -- is the Position of the PoI valid?
|
|
count = count + 1
|
|
poi.points[key] = nil
|
|
|
|
else -- Yeahh, valid Entry, let us see the Categorie ...
|
|
|
|
if( not (string.find(poi.points[key], "{")) and not (string.find(poi.points[key], "}"))) then
|
|
-- Entry without Categorie found
|
|
invalid_cat = invalid_cat + 1
|
|
poi.points[key] = value .. "{1}" -- Set Categorie to 1
|
|
end -- if(string.find)
|
|
|
|
local pos, cat
|
|
pos, cat, dir = poi.split_pos_cat(poi.points[key])
|
|
if( (cat == nil) or (cat > poi.max_categories) or (cat <= 0) )then -- Invalid Categorienumber found
|
|
poi.points[key] = poi.combine_pos_cat(pos, 1, dir) -- Changes the Categorienumber to 1
|
|
invalid_cat = invalid_cat + 1
|
|
|
|
end -- if(cat ==)
|
|
|
|
end -- if value
|
|
|
|
end -- if check_name
|
|
|
|
end -- for key,value
|
|
|
|
if (count > 0) or (invalid_cat > 0) then
|
|
poi.print(name, name .. " has deleted with validate " .. count .. " PoI's.\n", log)
|
|
poi.print(name, name .. " has found " .. invalid_cat .. " Entries with an invalid Categorie.\n", log)
|
|
poi.print(name, count .. S(" invalid POIs found and deleted."), red)
|
|
poi.print(name, invalid_cat .. S(" POIs with an invalid category found and set to 1."), red)
|
|
poi.save()
|
|
|
|
else
|
|
poi.print(name, S("No invalid POI found.") .. "\n", green)
|
|
|
|
end
|
|
|
|
end -- poi.validate
|
|
|
|
--[[
|
|
********************************************
|
|
*** Helpfunctions ***
|
|
********************************************
|
|
--]]
|
|
|
|
-- Trims a String
|
|
function poi.trim(myString)
|
|
return (string.gsub(myString, "^%s*(.-)%s*$", "%1"))
|
|
|
|
end -- poi.trim()
|
|
|
|
|
|
-- builds the list of Categories for drop down menu in the gui
|
|
function poi.build_cat_list()
|
|
for key, value in pairs(poi_categories) do -- build the dropdown menu
|
|
|
|
if catlist == "" then
|
|
|
|
catlist = value
|
|
|
|
else
|
|
|
|
catlist = catlist .. "," .. value
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Checks the valid of the name
|
|
function poi.check_name(name)
|
|
if (name == "") or (name == nil) then
|
|
return false
|
|
|
|
end -- if name
|
|
|
|
local valid = true
|
|
|
|
for key, value in ipairs(poi.filter) do
|
|
if string.find(string.lower(name), string.lower(value)) ~= nil then
|
|
valid = false
|
|
end -- if string.find
|
|
|
|
end -- for key,value
|
|
|
|
return valid -- Name was in Filter?
|
|
|
|
end -- poi.check_name()
|
|
|
|
-- Count's the amount of Entries
|
|
function poi.count()
|
|
local count = 0
|
|
for _,key in pairs(poi.points) do
|
|
count = count + 1
|
|
|
|
end -- for _,key
|
|
|
|
return count
|
|
end -- poi.count
|
|
|
|
-- Returns a sorted Table
|
|
function poi.spairs(t, order)
|
|
-- collect the keys
|
|
local keys = {}
|
|
for k in pairs(t) do
|
|
keys[#keys+1] = k
|
|
end -- for k
|
|
|
|
-- if order function given, sort by it by passing the table and keys a, b,
|
|
-- otherwise just sort the keys
|
|
if order then
|
|
table.sort(keys, function(a,b) return order(t, a, b) end)
|
|
else
|
|
table.sort(keys)
|
|
end -- if order
|
|
|
|
-- return the iterator function
|
|
local i = 0
|
|
return function()
|
|
i = i + 1
|
|
if keys[i] then
|
|
return keys[i], t[keys[i]]
|
|
end -- if keys
|
|
|
|
end -- function()
|
|
|
|
end -- poi.spairs
|
|
|
|
-- Writes a Message in a specific color or Logs it
|
|
function poi.print(name, message, color)
|
|
|
|
error = error or none -- No Error given, set it to 99 (none)
|
|
|
|
-- Logs a Message
|
|
if(color == log) then
|
|
minetest.log("action","[POI] "..name .. " : " .. message)
|
|
return
|
|
|
|
else
|
|
if(color ~= none) then
|
|
minetest.chat_send_player(name, core.colorize(color, message))
|
|
return
|
|
|
|
else
|
|
minetest.chat_send_player(name, message)
|
|
return
|
|
|
|
end -- if(error ~=none)
|
|
|
|
end -- if(error == log)
|
|
|
|
end -- print_message()
|
|
|
|
-- Returns the Entryname and the Categorieindex from an given Option
|
|
function poi.split_option(poi_name)
|
|
local categorie, p_name
|
|
|
|
categorie = 1 -- Set's categorie to 1 per default
|
|
|
|
if(string.find(poi_name, ",") ~= nil) then
|
|
p_name = poi.trim(string.sub(poi_name,1, string.find(poi_name, ",")-1)) -- Extract only the Name
|
|
categorie = tonumber(poi.trim(string.sub(poi_name,string.find(poi_name, ",")+1,-1))) -- Extract the Number of Categorie
|
|
|
|
if(categorie == nil) then -- Categorie was not a Number, then check the name
|
|
categorie = poi.trim(string.sub(poi_name,string.find(poi_name, ",")+1,-1))
|
|
categorie = poi.get_categorienumber(categorie) -- Find the Categorienumber
|
|
if(categorie == nil) then -- Puuhhh, unknown Categorie
|
|
categorie = -1 -- ok, set it to 1
|
|
|
|
end -- if(categorie == nil) -- unknown Name
|
|
|
|
end -- if(categorie == nil)
|
|
|
|
else
|
|
p_name = poi_name -- No Categorie found, only a Name was given
|
|
|
|
end
|
|
|
|
return p_name, categorie
|
|
|
|
end -- poi.split_option()
|
|
|
|
-- Returns Coordinates, Categorieindex and direction from an Entry
|
|
-- direction may be nil, as earlier POIs didn't save this
|
|
function poi.split_pos_cat(position)
|
|
local pos, cat, dir
|
|
|
|
if( (string.find(position,"{")) and (string.find(position, "}"))) then
|
|
local posAndDir = string.sub(position, 1, string.find(position, "{") - 1) -- Extract the pos coords and direction angles
|
|
pos, dir = string.match(posAndDir, "(%([%d, .-]+%))[, ]*([%p%s%d]*)") -- split "(x,y,z), (p,y)" into "(x,y,z)" and "(p,y)". The pattern is a bit awkward because Lua doesn't support optional captures.
|
|
dir = poi.string_to_direction(dir) -- convert "(p,y)" to either nil or a table with pitch and yaw
|
|
cat = tonumber(string.sub(position, string.find(position, "{") + 1, string.find(position, "}") - 1)) -- Extract the Categorie
|
|
cat = cat or 1 -- Convert it in an invalid case to 1
|
|
|
|
else
|
|
|
|
-- No Categorie found
|
|
pos = position
|
|
cat = 1 -- Categorie general
|
|
dir = nil -- No direction specified
|
|
|
|
end -- if(string.find(position)
|
|
|
|
return pos, cat, dir
|
|
|
|
end -- poi.split_pos_cat()
|
|
|
|
|
|
function poi.combine_pos_cat(position, category, dir)
|
|
|
|
local dirStr = ""
|
|
if dir ~= nil and dir.pitch ~= null and dir.yaw ~= null then
|
|
dirStr = ", (" .. tonumber(dir.pitch) .. "," .. tonumber(dir.yaw) .. ")"
|
|
end
|
|
|
|
if type(position) == "table" then
|
|
position = minetest.pos_to_string(position)
|
|
end
|
|
|
|
return position .. dirStr .. "{" .. tonumber(category) .. "}"
|
|
end -- poi.combine_pos_cat()
|
|
|
|
|
|
-- return nil, or a table with pitch and yaw
|
|
function poi.string_to_direction(value)
|
|
if value == nil then
|
|
return nil
|
|
end
|
|
|
|
p = {}
|
|
p.pitch, p.yaw = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
|
if p.pitch and p.yaw then
|
|
p.pitch = tonumber(p.pitch)
|
|
p.yaw = tonumber(p.yaw)
|
|
return p
|
|
end
|
|
return nil
|
|
end -- poi.string_to_direction()
|
|
|
|
|
|
-- Get's a Categoriename by Index
|
|
function poi.get_categoriename(cat)
|
|
|
|
local categorie = "Unknown"
|
|
|
|
for key, value in pairs(poi.categories) do
|
|
if(key == cat) then
|
|
categorie = value
|
|
break
|
|
|
|
end -- if(key == cat)
|
|
|
|
end -- for key,value
|
|
|
|
return categorie
|
|
|
|
end -- get_categoriename()
|
|
|
|
-- Gets a Categorienumber by Name
|
|
function poi.get_categorienumber(name)
|
|
|
|
local categorie = nil
|
|
|
|
if(name == "" or name == nil) then
|
|
return categorie
|
|
|
|
end -- if(name)
|
|
|
|
name = string.lower(name)
|
|
|
|
for key, value in pairs(poi.categories) do
|
|
if(string.lower(value) == name) then
|
|
categorie = key
|
|
break
|
|
|
|
end -- if(string.lower)
|
|
|
|
end -- for key,value
|
|
|
|
return categorie
|
|
|
|
end -- poi.get_categorienumber()
|
|
|
|
|
|
-- Gets a Categorie of an Entry
|
|
function poi.get_categorie(poi_name)
|
|
local value, cat, pos
|
|
|
|
value = poi.points[poi_name]
|
|
pos, cat = poi.split_pos_cat(value)
|
|
|
|
return cat
|
|
|
|
end -- get_categorie()
|
|
|
|
function poi.count_categories()
|
|
local cat = 0
|
|
|
|
for key,value in pairs(poi.categories) do
|
|
cat = cat + 1
|
|
|
|
end -- for key,value
|
|
|
|
return cat
|
|
|
|
end -- count_categories()
|
|
|
|
function poi.play_soundeffect(name, soundname)
|
|
|
|
if(soundname == nil or soundname == "") then
|
|
soundname = "teleport"
|
|
|
|
end -- if(soundname)
|
|
|
|
minetest.sound_play("minetest_poi_" .. soundname, {
|
|
to_player = name,
|
|
loop = false,
|
|
})
|
|
|
|
--poi.print(name, name .. " has played the Sound: " .. poi.modpath .. "/sounds/minetest_poi_" .. soundname .. ".ogg.", log)
|
|
|
|
end -- poi.play_soundeffect()
|
|
|
|
function poi.convertnil(poi_name)
|
|
|
|
if(poi_name == nil) then
|
|
poi_name = " "
|
|
|
|
end
|
|
|
|
return poi_name
|
|
|
|
end -- poi.convertnil()
|
|
|
|
--[[
|
|
********************************************
|
|
*** Commands to Register ***
|
|
********************************************
|
|
--]]
|
|
|
|
minetest.register_chatcommand("poi_set", {
|
|
params = S("<poi_name, category[number]>"),
|
|
description = S("Sets a Point of Interest or changes the category of an existing point."),
|
|
privs = {poi = true},
|
|
func = function(name, poi_name)
|
|
|
|
poi.set(name, poi_name)
|
|
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_gui", {
|
|
params = "",
|
|
description = S("Shows POIs in a GUI."),
|
|
privs = {interact = true},
|
|
func = function(name)
|
|
|
|
poi.gui(name,nil,true)
|
|
|
|
end,
|
|
})
|
|
minetest.register_chatcommand("poi_list", {
|
|
params = S("<-a> <-c> <-f> <-i [Categorie[Number]]>"),
|
|
description = S("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"),
|
|
privs = {interact = true},
|
|
func = function(name, arg)
|
|
|
|
poi.list(name, arg)
|
|
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_delete", {
|
|
params = S("<POI-Name>"),
|
|
description = S("Deletes a Point of Interest."),
|
|
privs = {poi = true},
|
|
func = function(name, poi_name)
|
|
|
|
poi.delete(name, poi_name)
|
|
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_reload", {
|
|
params = "",
|
|
description = S("Reloads the list of POIs."),
|
|
privs = {poi = true},
|
|
func = function(name)
|
|
|
|
poi.reload(name)
|
|
|
|
end,
|
|
})
|
|
|
|
|
|
minetest.register_chatcommand("poi_jump", {
|
|
params = S("<POI-Name>"),
|
|
description = S("Jumps to the Position of the Point of Interest."),
|
|
privs = {interact = true},
|
|
func = function(name, poi_name)
|
|
|
|
poi.jump(name, poi_name)
|
|
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_move", {
|
|
params = S("<POI-Name>"),
|
|
description = S("Changes the Position of the Point of Interest."),
|
|
privs = {poi = true},
|
|
func = function(name, poi_name)
|
|
|
|
poi.move(name, poi_name)
|
|
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_rename", {
|
|
params = S("<POI Old Name>,<POI New Name>"),
|
|
description = S("Changes the Name of the Point of Interest."),
|
|
privs = {poi = true},
|
|
func = function(name, poi_name)
|
|
|
|
poi.rename(name, poi_name)
|
|
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_validate", {
|
|
params = "",
|
|
description = S("Validates the List of POIs."),
|
|
privs = {poi = true},
|
|
func = function(name)
|
|
|
|
poi.validate(name)
|
|
|
|
end,
|
|
})
|
|
|
|
|
|
-- add button to unified_inventory
|
|
if (minetest.get_modpath("unified_inventory")) then
|
|
unified_inventory.register_button("minetest_poi", {
|
|
type = "image",
|
|
image = "minetest_poi_button_32x32.png",
|
|
tooltip = S("Show Points of Interest"),
|
|
hide_lite=true,
|
|
action = function(player)
|
|
local player_name = player:get_player_name()
|
|
if not player_name then return end
|
|
if minetest.check_player_privs(player_name, {interact=true}) then
|
|
poi.gui(player_name,nil,true)
|
|
else
|
|
minetest.chat_send_player(player_name,core.colorize(red, S("You need the"))..core.colorize(green, S(" interact"))..core.colorize(red,S(" priv, please type"))..core.colorize(green,S(" /rules"))..core.colorize(red,S(" and search for the keyword")))
|
|
end
|
|
end,
|
|
})
|
|
end
|
|
|
|
--[[
|
|
********************************************
|
|
*** Start of the Mod ***
|
|
********************************************
|
|
--]]
|
|
|
|
poi.openlist() -- Initalize the List on Start
|
|
poi.filter = poi_namefilter
|
|
poi.categories = poi_categories
|
|
poi.max_categories = poi.count_categories()
|
|
poi.build_cat_list()
|
|
|
|
print("[MOD] " .. minetest.get_current_modname() .. " loaded.")
|