I had a similar problem, needing to resolve zoneIndex within a city map within my addon.
I managed to get round it using a combination of a lookup, GetMapTileTexture and GetCurrentMapZoneIndex.
These two functions handle strings. Pattern matching from GetMapTileTexture and string keys used in the lookup.
Lua Code:
local function GetMapZone(path)
path = path or GetMapTileTexture()
path = string.lower(path)
local zone,subzone = string.match(path,"^.-/.-/(.-)/(.-)_")
if zone == nil and subzone == nil then
-- splits if path is actually a zone key
zone,subzone = string.match(path,"^(.-)/(.-)$")
end
return zone,subzone
end
local function GetMapZoneKey(zone,subzone)
if zone == nil and subzone == nil then
zone,subzone = GetMapZone()
elseif subzone == nil then
zone,subzone = GetMapZone(zone)
end
return table.concat({zone,"/",subzone}),zone,subzone
end
This function creates a lookup where you can lookup zone by zoneIndex, "zone/subzone" or "zone" or "subzone".
Lua Code:
local function CreateLocationsLookup(locations,func)
local lookup = {}
func = func or function(l) return l end
local item
for i,loc in ipairs(locations) do
item = func(loc)
lookup[loc.zoneIndex] = item
lookup[loc.key] = item
if lookup[loc.subzone] == nil then
lookup[loc.subzone] = item
elseif lookup[loc.zone] == nil then
lookup[loc.zone] = item
end
end
for i,loc in ipairs(locations) do
if lookup[loc.zone] == nil then
lookup[loc.zone] = lookup[loc.zoneIndex]
end
end
return lookup
end
Example location table for CreateLocationsLookup
Lua Code:
local _locationsList = {
[1] =
{
["zoneIndex"] = -2147483648,
["mapIndex"] = 1,
["tile"] = "art/maps/tamriel/tamriel_0.dds",
},
[2] =
{
["zoneIndex"] = 2,
["mapIndex"] = 2,
["tile"] = "art/maps/glenumbra/glenumbra_base_0.dds",
},
}
Function to resolve zones from lookup
Lua Code:
local function GetZoneLocation(lookup,zone,subzone)
local loc
if type(zone) == "number" then
loc = lookup[zone]
zone = nil
end
if loc == nil then
local key,zone,subzone = GetMapZoneKey(zone,subzone)
-- try by zone/subzone key first
loc = lookup[key]
-- subzone next to handle places like khenarthis roost
if loc == nil then
loc = lookup[subzone]
end
-- then zone to handle locations within main zones which cannot be matched by key e.g coldharbor's hollow city
if loc == nil then
loc = lookup[zone]
end
end
-- if zone cant be found then return tamriel
if loc == nil then
loc = lookup["tamriel"]
end
return loc
end
Usage example.
Lua Code:
local list = {} -- table of zones like example table.
local lookup = CreateLocationsLookup(list)
local loc = GetZoneLocation(lookup,GetCurrentMapZoneIndex())
Something that also got me was the map on player activate. It appears to change from the Tamriel map.
I handled it like below:
Lua Code:
addEvent(EVENT_PLAYER_ACTIVATED,function(eventCode)
local func = function()
local loc = GetZoneLocation(lookup,GetCurrentMapZoneIndex())
end
local idx = GetCurrentMapIndex()
-- handle the map changing from Tamriel
if idx == nil or idx == 1 then
local onChange
onChange = function()
func()
removeCallback(CALLBACK_ID_ON_WORLDMAP_CHANGED,onChange)
end
addCallback(CALLBACK_ID_ON_WORLDMAP_CHANGED,onChange)
else
func()
end
end)
Hope all of that makes sense
You can also see it in
LocationData.lua, and usage in
FasterTravel.lua in the addon.