View Single Post
07/27/15, 12:35 PM   #18
XanDDemoX
AddOn Author - Click to view addons
Join Date: May 2015
Posts: 28
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:
  1. local function GetMapZone(path)
  2.     path = path or GetMapTileTexture()
  3.     path = string.lower(path)
  4.     local zone,subzone = string.match(path,"^.-/.-/(.-)/(.-)_")
  5.     if zone == nil and subzone == nil then
  6.         -- splits if path is actually a zone key
  7.         zone,subzone = string.match(path,"^(.-)/(.-)$")
  8.     end
  9.     return zone,subzone
  10. end
  11.  
  12. local function GetMapZoneKey(zone,subzone)
  13.     if zone == nil and subzone == nil then
  14.         zone,subzone = GetMapZone()
  15.     elseif subzone == nil then
  16.         zone,subzone = GetMapZone(zone)
  17.     end
  18.     return table.concat({zone,"/",subzone}),zone,subzone
  19. end

This function creates a lookup where you can lookup zone by zoneIndex, "zone/subzone" or "zone" or "subzone".

Lua Code:
  1. local function CreateLocationsLookup(locations,func)
  2.     local lookup = {}
  3.     func = func or function(l) return l end
  4.     local item
  5.     for i,loc in ipairs(locations) do
  6.         item = func(loc)
  7.        
  8.         lookup[loc.zoneIndex] = item
  9.         lookup[loc.key] = item
  10.  
  11.         if lookup[loc.subzone] == nil then
  12.             lookup[loc.subzone] = item
  13.         elseif lookup[loc.zone] == nil then
  14.             lookup[loc.zone] = item
  15.         end
  16.        
  17.     end
  18.    
  19.     for i,loc in ipairs(locations) do
  20.         if lookup[loc.zone] == nil then
  21.             lookup[loc.zone] = lookup[loc.zoneIndex]
  22.         end
  23.     end
  24.    
  25.     return lookup
  26. end

Example location table for CreateLocationsLookup

Lua Code:
  1. local _locationsList = {
  2.     [1] =
  3.     {
  4.         ["zoneIndex"] = -2147483648,
  5.         ["mapIndex"] = 1,
  6.         ["tile"] = "art/maps/tamriel/tamriel_0.dds",
  7.     },
  8.     [2] =
  9.     {
  10.         ["zoneIndex"] = 2,
  11.         ["mapIndex"] = 2,
  12.         ["tile"] = "art/maps/glenumbra/glenumbra_base_0.dds",
  13.     },
  14. }

Function to resolve zones from lookup

Lua Code:
  1. local function GetZoneLocation(lookup,zone,subzone)
  2.     local loc
  3.    
  4.     if type(zone) == "number" then
  5.         loc = lookup[zone]
  6.         zone = nil
  7.     end
  8.     if loc == nil then
  9.         local key,zone,subzone = GetMapZoneKey(zone,subzone)
  10.        
  11.         -- try by zone/subzone key first
  12.         loc = lookup[key]
  13.         -- subzone next to handle places like khenarthis roost
  14.         if loc == nil then
  15.             loc = lookup[subzone]
  16.         end
  17.         -- then zone to handle locations within main zones which cannot be matched by key e.g coldharbor's hollow city
  18.         if loc == nil then
  19.             loc = lookup[zone]
  20.         end
  21.     end
  22.  
  23.     -- if zone cant be found then return tamriel
  24.     if loc == nil then
  25.         loc = lookup["tamriel"]
  26.     end
  27.    
  28.     return loc
  29. end


Usage example.

Lua Code:
  1. local list = {} -- table of zones like example table.
  2.  
  3. local lookup = CreateLocationsLookup(list)
  4.  
  5. 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:
  1. addEvent(EVENT_PLAYER_ACTIVATED,function(eventCode)
  2.                
  3.         local func = function()
  4.                         local loc = GetZoneLocation(lookup,GetCurrentMapZoneIndex())
  5.         end
  6.        
  7.         local idx = GetCurrentMapIndex()
  8.        
  9.         -- handle the map changing from Tamriel
  10.         if idx == nil or idx == 1 then
  11.             local onChange
  12.             onChange = function()
  13.                 func()
  14.                 removeCallback(CALLBACK_ID_ON_WORLDMAP_CHANGED,onChange)
  15.             end
  16.             addCallback(CALLBACK_ID_ON_WORLDMAP_CHANGED,onChange)
  17.         else
  18.             func()
  19.         end
  20.  
  21.     end)

Hope all of that makes sense You can also see it in LocationData.lua, and usage in FasterTravel.lua in the addon.

Last edited by XanDDemoX : 07/27/15 at 12:40 PM.