gps/init.lua

368 lines
9.8 KiB
Lua

--
-- Mod GPS
--
-- Destinations set limit that a player can have on GPS
-- Definir limite de Destinos que um jogador pode ter no gps
local LIMITE = 3
-- Time (in seconds) between each check inventory to see if this with a GPS
-- Tempo (em segundos) entre cada verificacao de inventario para saber se esta com um gps
local TEMPO = 5
-- Tradutor de String
local S
if minetest.get_modpath("intllib") then
S = intllib.Getter()
else
S = function(s,a,...)if a==nil then return s end a={a,...}return s:gsub("(@?)@(%(?)(%d+)(%)?)",function(e,o,n,c)if e==""then return a[tonumber(n)]..(o==""and c or"")else return"@"..o..n..c end end) end
end
-- Verificar texto sem caracteres
check_null_valid_text = function(s)
if s == nil then return false end
for char in string.gmatch(s, ".") do
return true
end
return false
end
-- Caracteres validos
local valid_chars = {
-- Maiusculos
["A"] = true,
["B"] = true,
["C"] = true,
["D"] = true,
["E"] = true,
["F"] = true,
["G"] = true,
["H"] = true,
["I"] = true,
["J"] = true,
["K"] = true,
["L"] = true,
["M"] = true,
["N"] = true,
["O"] = true,
["P"] = true,
["Q"] = true,
["R"] = true,
["S"] = true,
["T"] = true,
["U"] = true,
["V"] = true,
["W"] = true,
["X"] = true,
["Y"] = true,
["Z"] = true,
-- Minusculos
["a"] = true,
["b"] = true,
["c"] = true,
["d"] = true,
["e"] = true,
["f"] = true,
["g"] = true,
["h"] = true,
["i"] = true,
["j"] = true,
["k"] = true,
["l"] = true,
["m"] = true,
["n"] = true,
["o"] = true,
["p"] = true,
["q"] = true,
["r"] = true,
["s"] = true,
["t"] = true,
["u"] = true,
["v"] = true,
["w"] = true,
["x"] = true,
["y"] = true,
["z"] = true,
-- Caracteres especiais
[" "] = true
}
-- Verificar nome do grupo
check_text = function(text)
-- Verifica comprimento
if string.len(text) > 30 or string.len(text) == 0 then
return false
end
-- Verifica se existe ao menos um caracter valido
if check_null_valid_text(text) == false then
return false
end
-- Verifica caracteres validos
local text_valido = ""
for char in string.gmatch(text, ".") do
if valid_chars[char] then
text_valido = text_valido .. char
end
end
if text ~= text_valido then
return false
end
return true
end
--
-----
--------
-- Banco de dados
local path = minetest.get_worldpath()
local pathbd = path .. "/gps"
-- Cria o diretorio caso nao exista ainda
local function mkdir(pathbd)
if minetest.mkdir then
minetest.mkdir(pathbd)
else
os.execute('mkdir "' .. pathbd .. '"')
end
end
mkdir(pathbd)
local registros = {}
-- Carregar na memoria dados de um jogador
local carregar_dados = function(name)
local input = io.open(pathbd .. "/gps_"..name, "r")
if input then
registros[name] = minetest.deserialize(input:read("*l"))
io.close(input)
return true
else
return false
end
end
-- Salvar registros de trabalhos
local salvar_dados = function(name)
local output = io.open(pathbd .. "/gps_"..name, "w")
output:write(minetest.serialize(registros[name]))
io.close(output)
end
-- Tirar dados de jogadores que sairem do servidor
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
registros[name] = nil
end)
-- Registra apenas novos jogadores
minetest.register_on_newplayer(function(player)
local name = player:get_player_name()
registros[name] = {
string = "",
destinos = {}
}
salvar_dados(name)
carregar_dados(player:get_player_name())
end)
-- Carrega dados de jogadores que conectam
minetest.register_on_joinplayer(function(player)
if carregar_dados(player:get_player_name()) == false then
local name = player:get_player_name()
registros[name] = {
string = "",
destinos = {}
}
salvar_dados(name)
carregar_dados(name)
end
end)
-- Fim
--------
-----
--
--
-----
--------
-- Craftitem
minetest.register_craftitem("gps:gps", { -- GPS
description = S("GPS"),
stack_max = 1,
inventory_image = "gps_item.png",
on_use = function(itemstack, user, pointed_thing)
local name = user:get_player_name()
local formspec = "size[5,4]"
.."bgcolor[#08080800]"
.."background[0,0;5,4;gps_bg.png;true]"
.."label[0.1,-0.1;"..S("Destinos").."]"
.."dropdown[0.1,0.4;5,1;destino;"..registros[name].string..";1]"
.."button_exit[0.1,1.1;1.7,1;ir;"..S("Localizar").."]"
.."button_exit[1.7,1.1;1.7,1;desligar;"..S("Desligar").."]"
.."button_exit[3.3,1.1;1.6,1;deletar;"..S("Deletar").."]"
.."field[0.3,2.9;5,1;nome_destino;"..S("Novo Destino")..";"..S("Nome Desse Lugar").."]"
.."button_exit[0,3.3;5,1;gravar;"..S("Gravar Novo Destino").."]"
minetest.show_formspec(name, "gps:gps", formspec)
end,
})
minetest.register_craft({ -- Receita de GPS
output = "gps:gps",
recipe = {
{"default:steel_ingot", "dye:orange", "default:steel_ingot"},
{"default:steel_ingot", "default:diamond", "default:steel_ingot"},
{"default:stick", "default:stick", "default:stick"}
}
})
-- Fim
--------
-----
--
-- Atualizar string
local atualizar_string = function(name)
registros[name].string = ""
local i = 0
for destino, pos in pairs(registros[name].destinos) do
if i > 0 then registros[name].string = registros[name].string .. "," end
registros[name].string = registros[name].string .. destino
i = i + 1
end
end
-- Variavel global de waypoints
local waypoints = {}
-- Verificar Waypoint
local temporizador = 0
minetest.register_globalstep(function(dtime)
temporizador = temporizador + dtime
if temporizador >= TEMPO then
local waypoints_validos = {}
for name, waypoint in pairs(waypoints) do
local player = minetest.get_player_by_name(name)
if not player or not player:get_inventory():contains_item(player:get_wield_list(), "gps:gps") then
if player then
player:hud_remove(waypoints[name])
minetest.chat_send_player(name, S("Precisa estar com o GPS para ir ao destino."))
end
else
waypoints_validos[name] = waypoints[name]
end
end
waypoints = waypoints_validos
temporizador = 0
end
end)
-- Adicionar Waypoint
local adicionar_waypoint = function(name, destino)
local player = minetest.get_player_by_name(name)
if waypoints[name] then
player:hud_remove(waypoints[name])
end
waypoints[name] = player:hud_add({
hud_elem_type = "waypoint",
name = destino,
number = "16747520",
world_pos = registros[name].destinos[destino]
})
end
-- Recebedor de campos
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname == "gps:gps" then
local name = player:get_player_name()
if fields.ir then
if registros[name].destinos[fields.destino] then
adicionar_waypoint(name, fields.destino)
minetest.chat_send_player(name, S("GPS Ativado. Destino @1 localizado.", fields.destino))
minetest.sound_play("gps_beep", {gain = 0.15, max_hear_distance = 3, object = player})
return true
else
minetest.chat_send_player(name, S("Nenhum destino encontrado. Defina novos destinos."))
return true
end
elseif fields.desligar then
if waypoints[name] then
player:hud_remove(waypoints[name])
end
minetest.chat_send_player(name, S("GPS desligado."))
return true
elseif fields.gravar then
if fields.nome_destino then
if not fields.nome_destino:find("{")
and not fields.nome_destino:find("}")
and not fields.nome_destino:find(",")
and not fields.nome_destino:find("\\")
and not fields.nome_destino:find("\"")
and check_text(fields.nome_destino) == true
then
if fields.nome_destino == "" then
minetest.chat_send_player(name, S("Nenhum nome definido para o lugar. Digite um nome."))
return true
end
-- verificar quantos ja tem
local total = 0
for destino, pos in pairs(registros[name].destinos) do
total = total + 1
end
if total >= LIMITE then
minetest.chat_send_player(name, S("Limite de @1 destinos no seu GPS. Delete algum dos ja existentes.", LIMITE))
return true
end
registros[name].destinos[fields.nome_destino] = player:getpos()
atualizar_string(name)
salvar_dados(name)
minetest.chat_send_player(name, S("Lugar @1 foi gravado no seu GPS.", fields.nome_destino))
-- Caso ja tenha e esteja ativo entao ajusta o waypoint visualizado
if tonumber(waypoints[name]) and player:hud_get(waypoints[name]) then
local def = player:hud_get(waypoints[name])
if def.name == fields.nome_destino then adicionar_waypoint(name, fields.nome_destino) end
end
return true
else
minetest.chat_send_player(name, S("Caracteres invalidos. Tente utilizar apenas letras e numeros no novo nome."))
return true
end
else
minetest.chat_send_player(name, S("Nenhum nome especificado para o novo lugar. Defina o nome desse lugar."))
return true
end
elseif fields.deletar then
if fields.destino and fields.destino ~= "" then
if tonumber(waypoints[name]) then
player:hud_remove(waypoints[name])
end
local destinos_restantes = {} -- realoca destinos na memoria
for destino, pos in pairs(registros[name].destinos) do
if destino ~= fields.destino then
destinos_restantes[destino] = pos
end
end
registros[name].destinos = destinos_restantes
atualizar_string(name)
salvar_dados(name)
minetest.chat_send_player(name, S("Destino @1 deletado.", fields.destino))
return true
else
minetest.chat_send_player(name, S("Nenhum destino para deletar."))
return true
end
end
end
end)
-- Tira waypoint quando o jogador morre
minetest.register_on_dieplayer(function(player)
if waypoints[player:get_player_name()] then
player:hud_remove(waypoints[name])
end
end)