<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MudletPackage>
<MudletPackage version="1.001">
    <ScriptPackage>
        <Script isActive="yes" isFolder="no">
            <name>Mundos Perdidos mapa</name>
            <packageName></packageName>
            <script>-- Mundos Perdidos: mapa automatico para Mudlet (GMCP)
--
-- El MUD envia, al entrar en cada sala, el mensaje GMCP Room.Info con su numero, nombre,
-- zona, terreno, salidas y coordenadas (las del Atlas). Este script va dibujando el mapa
-- segun exploras.
--   * Doble clic en una sala del mapa: el personaje va caminando hasta ella.
--   * El mapa se abre con el boton "Map" de Mudlet (o se abre solo la primera vez).
--
-- ORIENTACION: con ESTE_A_LA_IZQUIERDA = true el mapa sale en espejo (este a la izquierda,
-- oeste a la derecha). Para que Mudlet dibuje bien las salidas, en ese modo se le dicen
-- "al reves" el este y el oeste, y al caminar con doble clic se vuelven a dar la vuelta.
-- Si cambias esta opcion con un mapa ya empezado, borra el mapa y vuelve a explorar.

local ESTE_A_LA_IZQUIERDA = false

mudlet = mudlet or {}
mudlet.mapper_script = true            -- avisa a Mudlet de que hay un script de mapa

mundosperdidos = mundosperdidos or {}
local F = mundosperdidos
F.pendientes = F.pendientes or {}      -- salidas hacia salas aun no visitadas

-- Colores por terreno (mismos que el Atlas): id de entorno de Mudlet y color RGB
local TERRENOS = {
  ["interior"]      = {301, 163, 150, 134},
  ["ciudad"]        = {302, 212, 173,  46},
  ["campo"]         = {303, 149, 197, 101},
  ["bosque"]        = {304,  58, 138,  85},
  ["colinas"]       = {305, 181, 183, 101},
  ["montanya"]      = {306, 141, 110,  92},
  ["agua"]          = {307,  99, 176, 234},
  ["agua profunda"] = {308,  36,  97, 173},
  ["sin uso"]       = {309, 154, 154, 154},
  ["aire"]          = {310, 205, 226, 243},
  ["desierto"]      = {311, 229, 196, 124},
}
for _, t in pairs(TERRENOS) do setCustomEnvColor(t[1], t[2], t[3], t[4], 255) end

-- En el Atlas la x crece hacia el OESTE. En Mudlet la x crece hacia la derecha.
local SIGNO_X = ESTE_A_LA_IZQUIERDA and 1 or -1
-- Direccion que se le dice a Mudlet (en espejo, este y oeste cambiados) y la vuelta
local A_MUDLET = ESTE_A_LA_IZQUIERDA and { e = "w", w = "e" } or {}
local DEL_MUDLET = ESTE_A_LA_IZQUIERDA and { e = "w", w = "e", east = "w", west = "e" } or {}
local function dir_mudlet(d) return A_MUDLET[d] or d end

-- Desplazamiento en Mudlet si una sala llega sin coordenadas (y crece hacia el norte)
local DELTA = { n = {0, 1, 0}, s = {0, -1, 0}, e = {1, 0, 0}, w = {-1, 0, 0}, u = {0, 0, 1}, d = {0, 0, -1} }

local function zona_id(nombre)
  if not nombre or nombre == "" then nombre = "Sin zona" end
  return getAreaTable()[nombre] or addAreaName(nombre)
end

function F.sala()
  local r = gmcp.Room and gmcp.Room.Info
  if not r or not r.num then return end
  local id = tonumber(r.num)

  if not roomExists(id) then
    addRoom(id)
    setRoomArea(id, zona_id(r.area))
    if r.coords then
      setRoomCoordinates(id, SIGNO_X * r.coords.x, -r.coords.y, r.coords.z)
    elseif F.anterior and roomExists(F.anterior) and F.dir and DELTA[dir_mudlet(F.dir)] then
      local x, y, z = getRoomCoordinates(F.anterior)
      local d = DELTA[dir_mudlet(F.dir)]
      setRoomCoordinates(id, x + d[1], y + d[2], z + d[3])
    else
      setRoomCoordinates(id, 0, 0, 0)
    end
    -- salidas de otras salas que esperaban a esta
    for _, p in ipairs(F.pendientes[id] or {}) do
      if roomExists(p[1]) then setExit(p[1], id, p[2]) end
    end
    F.pendientes[id] = nil
  end

  setRoomName(id, r.name or "")
  local t = TERRENOS[r.environment] or TERRENOS["interior"]
  setRoomEnv(id, t[1])

  for dir, destino in pairs(r.exits or {}) do
    destino = tonumber(destino)
    local dm = dir_mudlet(dir)
    if roomExists(destino) then
      setExit(id, destino, dm)
    else
      setExitStub(id, dm, true)
      F.pendientes[destino] = F.pendientes[destino] or {}
      table.insert(F.pendientes[destino], {id, dm})
    end
  end

  -- direccion por la que se ha llegado (para colocar salas sin coordenadas)
  F.dir = nil
  if F.salidas_ant then
    for dir, destino in pairs(F.salidas_ant) do
      if tonumber(destino) == id then F.dir = dir end
    end
  end
  F.anterior, F.salidas_ant = id, r.exits

  if not F.abierto then
    F.abierto = true
    pcall(openMapWidget)
  end
  centerview(id)
end

-- Doble clic en una sala del mapa: Mudlet calcula el camino y llama a esta funcion.
-- Las direcciones de Mudlet se pasan a los comandos del MUD (deshaciendo el espejo).
local ORDEN = { n = "norte", s = "sur", e = "este", w = "oeste", u = "arriba", d = "abajo",
                north = "norte", south = "sur", east = "este", west = "oeste", up = "arriba", down = "abajo" }
function doSpeedWalk()
  for _, d in ipairs(speedWalkDir) do
    local real = DEL_MUDLET[d] or d
    send(ORDEN[real] or real, false)
  end
end

-- "mapa borrar": borra el mapa dibujado (para empezar de cero)
function F.borrar_mapa()
  if type(deleteMap) == "function" then
    deleteMap()
  else
    for id in pairs(getRooms()) do deleteRoom(id) end
  end
  F.pendientes, F.anterior, F.salidas_ant = {}, nil, nil
  updateMap()
  cecho("\n&lt;green&gt;[Mundos Perdidos] Mapa borrado. Camina y se volvera a dibujar.\n")
end
if F.alias_borrar then killAlias(F.alias_borrar) end
F.alias_borrar = tempAlias("^mapa borrar$", F.borrar_mapa)

-- "mapa": abre la ventana del mapa (por si se ha cerrado)
if F.alias_abrir then killAlias(F.alias_abrir) end
F.alias_abrir = tempAlias("^mapa$", function()
  openMapWidget()
  if F.anterior then centerview(F.anterior) end
end)

-- El paquete antiguo ("FReaKMUD mapa") dibujaba tambien y estropeaba las salidas: se apaga
local function apagar_paquete_antiguo()
  if freakmud and freakmud.manejador then
    killAnonymousEventHandler(freakmud.manejador)
    freakmud.manejador = nil
    cecho("\n&lt;yellow&gt;[Mundos Perdidos] Desactivado el paquete antiguo 'FReaKMUD mapa'. Desinstalalo en Paquetes.\n")
  end
end
apagar_paquete_antiguo()
tempTimer(2, apagar_paquete_antiguo)   -- por si el antiguo se carga despues que este

-- El mapeador que Mudlet trae de serie (generic_mapper) tambien dibuja, a su manera: avisar
if type(getPackages) == "function" and table.contains(getPackages(), "generic_mapper") then
  cecho("\n&lt;yellow&gt;[Mundos Perdidos] Tienes instalado 'generic_mapper', el mapeador de serie de Mudlet: " ..
        "dibuja a la vez que este y lia el mapa. Quitalo en Paquetes (Remove) y escribe 'mapa borrar'.\n")
end

if F.manejador then killAnonymousEventHandler(F.manejador) end
F.manejador = registerAnonymousEventHandler("gmcp.Room.Info", F.sala)
cecho("\n&lt;green&gt;[Mundos Perdidos] Mapa automatico activado" ..
      (ESTE_A_LA_IZQUIERDA and " (este a la izquierda)" or "") .. ": explora y el mapa se dibuja solo.\n")
</script>
            <eventHandlerList />
        </Script>
    </ScriptPackage>
</MudletPackage>
