ESOUI SVN TaosGroupUltimate

[/] [trunk/] [TaosGroupUltimate/] [libs/] [LibGPS/] [LibGPS.lua] - Blame information for rev 61

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 40 Taonnor-14572
-- LibGPS2 & its files © sirinsidiator                          --
2 Taonnor-14572
-- Distributed under The Artistic License 2.0 (see LICENSE)     --
3 Taonnor-14572
------------------------------------------------------------------
4 Taonnor-14572
 
5 Taonnor-14572
local LIB_NAME = "LibGPS2"
6 61 Taonnor-14572
local lib = LibStub:NewLibrary(LIB_NAME, 14)
7 40 Taonnor-14572
 
8 Taonnor-14572
if not lib then
9 Taonnor-14572
    return
10 Taonnor-14572
    -- already loaded and no upgrade necessary
11 Taonnor-14572
end
12 Taonnor-14572
 
13 Taonnor-14572
local LMP = LibStub("LibMapPing", true)
14 Taonnor-14572
if(not LMP) then
15 Taonnor-14572
    error(string.format("[%s] Cannot load without LibMapPing", LIB_NAME))
16 Taonnor-14572
end
17 Taonnor-14572
 
18 Taonnor-14572
local DUMMY_PIN_TYPE = LIB_NAME .. "DummyPin"
19 Taonnor-14572
local LIB_IDENTIFIER_FINALIZE = LIB_NAME .. "_Finalize"
20 Taonnor-14572
lib.LIB_EVENT_STATE_CHANGED = "OnLibGPS2MeasurementChanged"
21 Taonnor-14572
 
22 Taonnor-14572
local LOG_WARNING = "Warning"
23 Taonnor-14572
local LOG_NOTICE = "Notice"
24 Taonnor-14572
local LOG_DEBUG = "Debug"
25 Taonnor-14572
 
26 Taonnor-14572
local POSITION_MIN = 0.085
27 Taonnor-14572
local POSITION_MAX = 0.915
28 Taonnor-14572
 
29 Taonnor-14572
local TAMRIEL_MAP_INDEX = 1
30 Taonnor-14572
 
31 49 Taonnor-14572
local rootMaps = lib.rootMaps or {}
32 Taonnor-14572
lib.rootMaps = rootMaps
33 Taonnor-14572
 
34 40 Taonnor-14572
--lib.debugMode = 1 -- TODO
35 Taonnor-14572
lib.mapMeasurements = lib.mapMeasurements or {}
36 Taonnor-14572
local mapMeasurements = lib.mapMeasurements
37 Taonnor-14572
lib.mapStack = lib.mapStack or {}
38 Taonnor-14572
local mapStack = lib.mapStack
39 Taonnor-14572
lib.suppressCount = lib.suppressCount or 0
40 Taonnor-14572
 
41 Taonnor-14572
local MAP_PIN_TYPE_PLAYER_WAYPOINT = MAP_PIN_TYPE_PLAYER_WAYPOINT
42 Taonnor-14572
local currentWaypointX, currentWaypointY, currentWaypointMapId = 0, 0, nil
43 Taonnor-14572
local needWaypointRestore = false
44 Taonnor-14572
local orgSetMapToMapListIndex = nil
45 Taonnor-14572
local orgSetMapToPlayerLocation = nil
46 Taonnor-14572
local orgSetMapFloor = nil
47 Taonnor-14572
local orgProcessMapClick = nil
48 49 Taonnor-14572
local orgFunctions = {}
49 40 Taonnor-14572
local measuring = false
50 Taonnor-14572
 
51 Taonnor-14572
SLASH_COMMANDS["/libgpsdebug"] = function(value)
52 Taonnor-14572
    lib.debugMode = (tonumber(value) == 1)
53 Taonnor-14572
    df("[%s] debug mode %s", LIB_NAME, lib.debugMode and "enabled" or "disabled")
54 Taonnor-14572
end
55 Taonnor-14572
 
56 Taonnor-14572
local function LogMessage(type, message, ...)
57 Taonnor-14572
    if not lib.debugMode then return end
58 Taonnor-14572
    df("[%s] %s: %s", LIB_NAME, type, zo_strjoin(" ", message, ...))
59 Taonnor-14572
end
60 Taonnor-14572
 
61 Taonnor-14572
local function GetAddon()
62 Taonnor-14572
    local addOn
63 Taonnor-14572
    local function errornous() addOn = 'a' + 1 end
64 Taonnor-14572
    local function errorHandler(err) addOn = string.match(err, "'GetAddon'.+user:/AddOns/(.-:.-):") end
65 Taonnor-14572
    xpcall(errornous, errorHandler)
66 Taonnor-14572
    return addOn
67 Taonnor-14572
end
68 Taonnor-14572
 
69 Taonnor-14572
local function FinalizeMeasurement()
70 Taonnor-14572
    EVENT_MANAGER:UnregisterForUpdate(LIB_IDENTIFIER_FINALIZE)
71 Taonnor-14572
    while lib.suppressCount > 0 do
72 Taonnor-14572
        LMP:UnsuppressPing(MAP_PIN_TYPE_PLAYER_WAYPOINT)
73 Taonnor-14572
        lib.suppressCount = lib.suppressCount - 1
74 Taonnor-14572
    end
75 Taonnor-14572
    if needWaypointRestore then
76 Taonnor-14572
        LogMessage(LOG_DEBUG, "Update waypoint pin", LMP:GetMapPing(MAP_PIN_TYPE_PLAYER_WAYPOINT))
77 Taonnor-14572
        LMP:RefreshMapPin(MAP_PIN_TYPE_PLAYER_WAYPOINT)
78 Taonnor-14572
        needWaypointRestore = false
79 Taonnor-14572
    end
80 Taonnor-14572
    measuring = false
81 Taonnor-14572
    CALLBACK_MANAGER:FireCallbacks(lib.LIB_EVENT_STATE_CHANGED, measuring)
82 Taonnor-14572
end
83 Taonnor-14572
 
84 Taonnor-14572
local function HandlePingEvent(pingType, pingTag, x, y, isPingOwner)
85 Taonnor-14572
    if(not isPingOwner or pingType ~= MAP_PIN_TYPE_PLAYER_WAYPOINT or not measuring) then return end
86 Taonnor-14572
    -- we delay our handler until all events have been fired and so that other addons can react to it first in case they use IsMeasuring
87 Taonnor-14572
    EVENT_MANAGER:UnregisterForUpdate(LIB_IDENTIFIER_FINALIZE)
88 Taonnor-14572
    EVENT_MANAGER:RegisterForUpdate(LIB_IDENTIFIER_FINALIZE, 0, FinalizeMeasurement)
89 Taonnor-14572
end
90 Taonnor-14572
 
91 Taonnor-14572
local function GetPlayerPosition()
92 Taonnor-14572
    return GetMapPlayerPosition("player")
93 Taonnor-14572
end
94 Taonnor-14572
 
95 Taonnor-14572
local function GetPlayerWaypoint()
96 Taonnor-14572
    return LMP:GetMapPing(MAP_PIN_TYPE_PLAYER_WAYPOINT)
97 Taonnor-14572
end
98 Taonnor-14572
 
99 Taonnor-14572
local function SetMeasurementWaypoint(x, y)
100 Taonnor-14572
    -- this waypoint stays invisible for others
101 Taonnor-14572
    lib.suppressCount = lib.suppressCount + 1
102 Taonnor-14572
    LMP:SuppressPing(MAP_PIN_TYPE_PLAYER_WAYPOINT)
103 Taonnor-14572
    LMP:SetMapPing(MAP_PIN_TYPE_PLAYER_WAYPOINT, MAP_TYPE_LOCATION_CENTERED, x, y)
104 Taonnor-14572
end
105 Taonnor-14572
 
106 Taonnor-14572
local function SetPlayerWaypoint(x, y)
107 Taonnor-14572
    LMP:SetMapPing(MAP_PIN_TYPE_PLAYER_WAYPOINT, MAP_TYPE_LOCATION_CENTERED, x, y)
108 Taonnor-14572
end
109 Taonnor-14572
 
110 Taonnor-14572
local function RemovePlayerWaypoint()
111 Taonnor-14572
    LMP:RemoveMapPing(MAP_PIN_TYPE_PLAYER_WAYPOINT)
112 Taonnor-14572
end
113 Taonnor-14572
 
114 Taonnor-14572
local function GetReferencePoints()
115 Taonnor-14572
    local x1, y1 = GetPlayerPosition()
116 Taonnor-14572
    local x2, y2 = GetPlayerWaypoint()
117 Taonnor-14572
    return x1, y1, x2, y2
118 Taonnor-14572
end
119 Taonnor-14572
 
120 Taonnor-14572
local function IsMapMeasured(mapId)
121 Taonnor-14572
    return (mapMeasurements[mapId or GetMapTileTexture()] ~= nil)
122 Taonnor-14572
end
123 Taonnor-14572
 
124 Taonnor-14572
local function StoreTamrielMapMeasurements()
125 Taonnor-14572
    -- no need to actually measure the world map
126 Taonnor-14572
    if (orgSetMapToMapListIndex(TAMRIEL_MAP_INDEX) ~= SET_MAP_RESULT_FAILED) then
127 49 Taonnor-14572
        local measurement = {
128 40 Taonnor-14572
            scaleX = 1,
129 Taonnor-14572
            scaleY = 1,
130 Taonnor-14572
            offsetX = 0,
131 Taonnor-14572
            offsetY = 0,
132 49 Taonnor-14572
            mapIndex = TAMRIEL_MAP_INDEX,
133 Taonnor-14572
            zoneIndex = GetCurrentMapZoneIndex()
134 40 Taonnor-14572
        }
135 49 Taonnor-14572
        mapMeasurements[GetMapTileTexture()] = measurement
136 Taonnor-14572
        rootMaps[TAMRIEL_MAP_INDEX] = measurement
137 40 Taonnor-14572
        return true
138 Taonnor-14572
    end
139 Taonnor-14572
 
140 Taonnor-14572
    return false
141 Taonnor-14572
end
142 Taonnor-14572
 
143 Taonnor-14572
local function CalculateMeasurements(mapId, localX, localY)
144 Taonnor-14572
    -- select the map corner farthest from the player position
145 Taonnor-14572
    local wpX, wpY = POSITION_MIN, POSITION_MIN
146 Taonnor-14572
    -- on some maps we cannot set the waypoint to the map border (e.g. Aurdion)
147 Taonnor-14572
    -- Opposite corner:
148 Taonnor-14572
    if (localX < 0.5) then wpX = POSITION_MAX end
149 Taonnor-14572
    if (localY < 0.5) then wpY = POSITION_MAX end
150 Taonnor-14572
 
151 Taonnor-14572
    SetMeasurementWaypoint(wpX, wpY)
152 Taonnor-14572
 
153 Taonnor-14572
    -- add local points to seen maps
154 Taonnor-14572
    local measurementPositions = {}
155 Taonnor-14572
    table.insert(measurementPositions, { mapId = mapId, pX = localX, pY = localY, wpX = wpX, wpY = wpY })
156 Taonnor-14572
 
157 Taonnor-14572
    -- switch to zone map in order to get the mapIndex for the current location
158 Taonnor-14572
    local x1, y1, x2, y2
159 Taonnor-14572
    while not(GetMapType() == MAPTYPE_ZONE and GetMapContentType() ~= MAP_CONTENT_DUNGEON) do
160 Taonnor-14572
        if (MapZoomOut() ~= SET_MAP_RESULT_MAP_CHANGED) then break end
161 Taonnor-14572
        -- collect measurements for all maps we come through on our way to the zone map
162 Taonnor-14572
        x1, y1, x2, y2 = GetReferencePoints()
163 Taonnor-14572
        table.insert(measurementPositions, { mapId = GetMapTileTexture(), pX = x1, pY = y1, wpX = x2, wpY = y2 })
164 Taonnor-14572
    end
165 Taonnor-14572
 
166 Taonnor-14572
    -- some non-zone maps like Eyevea zoom directly to the Tamriel map
167 Taonnor-14572
    local mapIndex = GetCurrentMapIndex() or TAMRIEL_MAP_INDEX
168 49 Taonnor-14572
    local zoneIndex = GetCurrentMapZoneIndex()
169 40 Taonnor-14572
 
170 Taonnor-14572
    -- switch to world map so we can calculate the global map scale and offset
171 Taonnor-14572
    if orgSetMapToMapListIndex(TAMRIEL_MAP_INDEX) == SET_MAP_RESULT_FAILED then
172 Taonnor-14572
        -- failed to switch to the world map
173 Taonnor-14572
        LogMessage(LOG_NOTICE, "Could not switch to world map")
174 Taonnor-14572
        return
175 Taonnor-14572
    end
176 Taonnor-14572
 
177 Taonnor-14572
    -- get the two reference points on the world map
178 Taonnor-14572
    x1, y1, x2, y2 = GetReferencePoints()
179 Taonnor-14572
 
180 Taonnor-14572
    -- calculate scale and offset for all maps that we saw
181 Taonnor-14572
    local scaleX, scaleY, offsetX, offsetY
182 Taonnor-14572
    for _, m in ipairs(measurementPositions) do
183 Taonnor-14572
        if (mapMeasurements[m.mapId]) then break end -- we always go up in the hierarchy so we can stop once a measurement already exists
184 Taonnor-14572
        LogMessage(LOG_DEBUG, "Store map measurement for", m.mapId:sub(10, -7))
185 Taonnor-14572
        scaleX = (x2 - x1) / (m.wpX - m.pX)
186 Taonnor-14572
        scaleY = (y2 - y1) / (m.wpY - m.pY)
187 Taonnor-14572
        offsetX = x1 - m.pX * scaleX
188 Taonnor-14572
        offsetY = y1 - m.pY * scaleY
189 Taonnor-14572
        if (math.abs(scaleX - scaleY) > 1e-3) then
190 Taonnor-14572
            LogMessage(LOG_WARNING, "Current map measurement might be wrong", m.mapId:sub(10, -7), mapIndex, m.pX, m.pY, m.wpX, m.wpY, x1, y1, x2, y2, offsetX, offsetY, scaleX, scaleY)
191 Taonnor-14572
        end
192 Taonnor-14572
 
193 Taonnor-14572
        -- store measurements
194 Taonnor-14572
        mapMeasurements[m.mapId] = {
195 Taonnor-14572
            scaleX = scaleX,
196 Taonnor-14572
            scaleY = scaleY,
197 Taonnor-14572
            offsetX = offsetX,
198 Taonnor-14572
            offsetY = offsetY,
199 49 Taonnor-14572
            mapIndex = mapIndex,
200 Taonnor-14572
            zoneIndex = zoneIndex
201 40 Taonnor-14572
        }
202 Taonnor-14572
    end
203 Taonnor-14572
    return mapIndex
204 Taonnor-14572
end
205 Taonnor-14572
 
206 Taonnor-14572
local function StoreCurrentWaypoint()
207 Taonnor-14572
    currentWaypointX, currentWaypointY = GetPlayerWaypoint()
208 Taonnor-14572
    currentWaypointMapId = GetMapTileTexture()
209 Taonnor-14572
end
210 Taonnor-14572
 
211 Taonnor-14572
local function ClearCurrentWaypoint()
212 Taonnor-14572
    currentWaypointX, currentWaypointY = 0, 0, nil
213 Taonnor-14572
end
214 Taonnor-14572
 
215 49 Taonnor-14572
local function GetExtraMapMeasurement(extraMapIndex)
216 Taonnor-14572
    -- switch to the map
217 Taonnor-14572
    orgSetMapToMapListIndex(extraMapIndex)
218 Taonnor-14572
    local extraMapId = GetMapTileTexture()
219 Taonnor-14572
    if(not IsMapMeasured(extraMapId)) then
220 Taonnor-14572
        -- calculate the measurements of map without worrying about the waypoint
221 Taonnor-14572
        local mapIndex = CalculateMeasurements(extraMapId, GetPlayerPosition())
222 Taonnor-14572
        if (mapIndex ~= extraMapIndex) then
223 Taonnor-14572
            local name = GetMapInfo(extraMapIndex)
224 Taonnor-14572
            name = zo_strformat("<<C:1>>", name)
225 Taonnor-14572
            LogMessage(LOG_WARNING, "CalculateMeasurements returned different index while measuring ", name, " map. expected:", extraMapIndex, "actual:", mapIndex)
226 Taonnor-14572
            if (not IsMapMeasured(extraMapId)) then
227 Taonnor-14572
                LogMessage(LOG_WARNING, "Failed to measure ", name, " map.")
228 40 Taonnor-14572
                return
229 Taonnor-14572
            end
230 Taonnor-14572
        end
231 Taonnor-14572
    end
232 49 Taonnor-14572
    return mapMeasurements[extraMapId]
233 40 Taonnor-14572
end
234 Taonnor-14572
 
235 Taonnor-14572
local function RestoreCurrentWaypoint()
236 Taonnor-14572
    if(not currentWaypointMapId) then
237 Taonnor-14572
        LogMessage(LOG_DEBUG, "Called RestoreCurrentWaypoint without calling StoreCurrentWaypoint.")
238 Taonnor-14572
        return
239 Taonnor-14572
    end
240 Taonnor-14572
 
241 Taonnor-14572
    local wasSet = false
242 Taonnor-14572
    if (currentWaypointX ~= 0 or currentWaypointY ~= 0) then
243 Taonnor-14572
        -- calculate waypoint position on the worldmap
244 Taonnor-14572
        local measurements = mapMeasurements[currentWaypointMapId]
245 Taonnor-14572
        local x = currentWaypointX * measurements.scaleX + measurements.offsetX
246 Taonnor-14572
        local y = currentWaypointY * measurements.scaleY + measurements.offsetY
247 Taonnor-14572
 
248 49 Taonnor-14572
        for rootMapIndex, measurements in pairs(rootMaps) do
249 Taonnor-14572
            if not measurements then
250 Taonnor-14572
                measurements = GetExtraMapMeasurement(rootMapIndex)
251 Taonnor-14572
                rootMaps[rootMapIndex] = measurements
252 40 Taonnor-14572
            end
253 Taonnor-14572
            if(measurements) then
254 49 Taonnor-14572
                if(x > measurements.offsetX and x < (measurements.offsetX + measurements.scaleX) and
255 Taonnor-14572
                    y > measurements.offsetY and y < (measurements.offsetY + measurements.scaleY)) then
256 Taonnor-14572
                    if(orgSetMapToMapListIndex(rootMapIndex) ~= SET_MAP_RESULT_FAILED) then
257 Taonnor-14572
                        -- calculate waypoint coodinates within root map
258 Taonnor-14572
                        x = (x - measurements.offsetX) / measurements.scaleX
259 Taonnor-14572
                        y = (y - measurements.offsetY) / measurements.scaleY
260 40 Taonnor-14572
                        SetPlayerWaypoint(x, y)
261 Taonnor-14572
                        wasSet = true
262 49 Taonnor-14572
                        break
263 40 Taonnor-14572
                    end
264 Taonnor-14572
                end
265 Taonnor-14572
            end
266 Taonnor-14572
        end
267 49 Taonnor-14572
        if (not wasSet) then
268 Taonnor-14572
            LogMessage(LOG_DEBUG, "Cannot reset waypoint because it was outside of our reach")
269 Taonnor-14572
        end
270 40 Taonnor-14572
    end
271 Taonnor-14572
 
272 Taonnor-14572
    if(wasSet) then
273 Taonnor-14572
        LogMessage(LOG_DEBUG, "Waypoint was restored, request pin update")
274 Taonnor-14572
        needWaypointRestore = true -- we need to update the pin on the worldmap afterwards
275 Taonnor-14572
    else
276 Taonnor-14572
        RemovePlayerWaypoint()
277 Taonnor-14572
    end
278 Taonnor-14572
    ClearCurrentWaypoint()
279 Taonnor-14572
end
280 Taonnor-14572
 
281 49 Taonnor-14572
local function ConnectToWorldMap()
282 Taonnor-14572
    lib.panAndZoom = ZO_WorldMap_GetPanAndZoom()
283 Taonnor-14572
    lib.mapPinManager = ZO_WorldMap_GetPinManager()
284 Taonnor-14572
    if (_G[DUMMY_PIN_TYPE]) then return end
285 Taonnor-14572
    ZO_WorldMap_AddCustomPin(DUMMY_PIN_TYPE, function(pinManager) end , nil, { level = 0, size = 0, texture = "" })
286 Taonnor-14572
    ZO_WorldMap_SetCustomPinEnabled(_G[DUMMY_PIN_TYPE], false)
287 40 Taonnor-14572
end
288 Taonnor-14572
 
289 49 Taonnor-14572
local function HookSetMapToFunction(funcName)
290 Taonnor-14572
    local orgFunction = _G[funcName]
291 Taonnor-14572
    orgFunctions[funcName] = orgFunction
292 Taonnor-14572
    local function NewFunction(...)
293 Taonnor-14572
        local result = orgFunction(...)
294 40 Taonnor-14572
        if(result ~= SET_MAP_RESULT_MAP_FAILED and not IsMapMeasured()) then
295 49 Taonnor-14572
            LogMessage(LOG_DEBUG, funcName)
296 40 Taonnor-14572
 
297 49 Taonnor-14572
            local success, mapResult = lib:CalculateMapMeasurements(false)
298 Taonnor-14572
            if(mapResult ~= SET_MAP_RESULT_CURRENT_MAP_UNCHANGED) then
299 Taonnor-14572
                result = mapResult
300 Taonnor-14572
            end
301 Taonnor-14572
            orgFunction(...)
302 40 Taonnor-14572
        end
303 Taonnor-14572
        -- All stuff is done before anyone triggers an "OnWorldMapChanged" event due to this result
304 Taonnor-14572
        return result
305 Taonnor-14572
    end
306 49 Taonnor-14572
    _G[funcName] = NewFunction
307 40 Taonnor-14572
end
308 Taonnor-14572
 
309 Taonnor-14572
local function HookSetMapToPlayerLocation()
310 Taonnor-14572
    orgSetMapToPlayerLocation = SetMapToPlayerLocation
311 49 Taonnor-14572
    orgFunctions["SetMapToPlayerLocation"] = orgSetMapToPlayerLocation
312 40 Taonnor-14572
    local function NewSetMapToPlayerLocation(...)
313 Taonnor-14572
        if not DoesUnitExist("player") then return SET_MAP_RESULT_MAP_FAILED end
314 Taonnor-14572
        local result = orgSetMapToPlayerLocation(...)
315 Taonnor-14572
        if(result ~= SET_MAP_RESULT_MAP_FAILED and not IsMapMeasured()) then
316 Taonnor-14572
            LogMessage(LOG_DEBUG, "SetMapToPlayerLocation")
317 Taonnor-14572
 
318 49 Taonnor-14572
            local success, mapResult = lib:CalculateMapMeasurements(false)
319 Taonnor-14572
            if(mapResult ~= SET_MAP_RESULT_CURRENT_MAP_UNCHANGED) then
320 Taonnor-14572
                result = mapResult
321 Taonnor-14572
            end
322 40 Taonnor-14572
            orgSetMapToPlayerLocation(...)
323 Taonnor-14572
        end
324 Taonnor-14572
        -- All stuff is done before anyone triggers an "OnWorldMapChanged" event due to this result
325 Taonnor-14572
        return result
326 Taonnor-14572
    end
327 Taonnor-14572
    SetMapToPlayerLocation = NewSetMapToPlayerLocation
328 Taonnor-14572
end
329 Taonnor-14572
 
330 Taonnor-14572
local function HookSetMapToMapListIndex()
331 Taonnor-14572
    orgSetMapToMapListIndex = SetMapToMapListIndex
332 49 Taonnor-14572
    orgFunctions["SetMapToMapListIndex"] = orgSetMapToMapListIndex
333 40 Taonnor-14572
    local function NewSetMapToMapListIndex(mapIndex)
334 Taonnor-14572
        local result = orgSetMapToMapListIndex(mapIndex)
335 Taonnor-14572
        if(result ~= SET_MAP_RESULT_MAP_FAILED and not IsMapMeasured()) then
336 Taonnor-14572
            LogMessage(LOG_DEBUG, "SetMapToMapListIndex")
337 Taonnor-14572
 
338 49 Taonnor-14572
            local success, mapResult = lib:CalculateMapMeasurements(false)
339 Taonnor-14572
            if(mapResult ~= SET_MAP_RESULT_CURRENT_MAP_UNCHANGED) then
340 Taonnor-14572
                result = mapResult
341 Taonnor-14572
            end
342 40 Taonnor-14572
            orgSetMapToMapListIndex(mapIndex)
343 Taonnor-14572
        end
344 Taonnor-14572
 
345 Taonnor-14572
        -- All stuff is done before anyone triggers an "OnWorldMapChanged" event due to this result
346 Taonnor-14572
        return result
347 Taonnor-14572
    end
348 Taonnor-14572
    SetMapToMapListIndex = NewSetMapToMapListIndex
349 Taonnor-14572
end
350 Taonnor-14572
 
351 Taonnor-14572
local function HookProcessMapClick()
352 Taonnor-14572
    orgProcessMapClick = ProcessMapClick
353 49 Taonnor-14572
    orgFunctions["ProcessMapClick"] = orgProcessMapClick
354 40 Taonnor-14572
    local function NewProcessMapClick(...)
355 Taonnor-14572
        local result = orgProcessMapClick(...)
356 Taonnor-14572
        if(result ~= SET_MAP_RESULT_MAP_FAILED and not IsMapMeasured()) then
357 Taonnor-14572
            LogMessage(LOG_DEBUG, "ProcessMapClick")
358 49 Taonnor-14572
            local success, mapResult = lib:CalculateMapMeasurements(true)
359 Taonnor-14572
            if(mapResult ~= SET_MAP_RESULT_CURRENT_MAP_UNCHANGED) then
360 Taonnor-14572
                result = mapResult
361 Taonnor-14572
            end
362 40 Taonnor-14572
            -- Returning is done via clicking already
363 Taonnor-14572
        end
364 Taonnor-14572
        return result
365 Taonnor-14572
    end
366 Taonnor-14572
    ProcessMapClick = NewProcessMapClick
367 Taonnor-14572
end
368 Taonnor-14572
 
369 Taonnor-14572
local function HookSetMapFloor()
370 Taonnor-14572
    orgSetMapFloor = SetMapFloor
371 49 Taonnor-14572
    orgFunctions["SetMapFloor"] = orgSetMapFloor
372 40 Taonnor-14572
    local function NewSetMapFloor(...)
373 Taonnor-14572
        local result = orgSetMapFloor(...)
374 Taonnor-14572
        if result ~= SET_MAP_RESULT_MAP_FAILED and not IsMapMeasured() then
375 Taonnor-14572
            LogMessage(LOG_DEBUG, "SetMapFloor")
376 49 Taonnor-14572
            local success, mapResult = lib:CalculateMapMeasurements(true)
377 Taonnor-14572
            if(mapResult ~= SET_MAP_RESULT_CURRENT_MAP_UNCHANGED) then
378 Taonnor-14572
                result = mapResult
379 Taonnor-14572
            end
380 40 Taonnor-14572
            orgSetMapFloor(...)
381 Taonnor-14572
        end
382 Taonnor-14572
        return result
383 Taonnor-14572
    end
384 Taonnor-14572
    SetMapFloor = NewSetMapFloor
385 Taonnor-14572
end
386 Taonnor-14572
 
387 Taonnor-14572
local function Initialize() -- wait until we have defined all functions
388 Taonnor-14572
    --- Unregister handler from older libGPS ( < 3)
389 Taonnor-14572
    EVENT_MANAGER:UnregisterForEvent("LibGPS2_SaveWaypoint", EVENT_PLAYER_DEACTIVATED)
390 Taonnor-14572
    EVENT_MANAGER:UnregisterForEvent("LibGPS2_RestoreWaypoint", EVENT_PLAYER_ACTIVATED)
391 Taonnor-14572
 
392 Taonnor-14572
    --- Unregister handler from older libGPS ( <= 5.1)
393 Taonnor-14572
    EVENT_MANAGER:UnregisterForEvent(LIB_NAME .. "_Init", EVENT_PLAYER_ACTIVATED)
394 49 Taonnor-14572
    --- Unregister handler from older libGPS, as it is now managed by LibMapPing ( >= 6)
395 Taonnor-14572
    EVENT_MANAGER:UnregisterForEvent(LIB_NAME .. "_UnmuteMapPing", EVENT_MAP_PING)
396 40 Taonnor-14572
 
397 Taonnor-14572
    if (lib.Unload) then
398 Taonnor-14572
        -- Undo action from older libGPS ( >= 5.2)
399 Taonnor-14572
        lib:Unload()
400 49 Taonnor-14572
        if (lib.suppressCount > 0) then
401 Taonnor-14572
            if lib.debugMode then zo_callLater(function() LogMessage(LOG_WARNING, "There is a measure in progress before loading is completed.") end, 2000) end
402 Taonnor-14572
            FinalizeMeasurement()
403 Taonnor-14572
        end
404 61 Taonnor-14572
    end
405 40 Taonnor-14572
 
406 Taonnor-14572
    --- Register new Unload
407 Taonnor-14572
    function lib:Unload()
408 49 Taonnor-14572
        for funcName, func in pairs(orgFunctions) do
409 Taonnor-14572
            _G[funcName] = func
410 Taonnor-14572
        end
411 40 Taonnor-14572
 
412 Taonnor-14572
        LMP:UnregisterCallback("AfterPingAdded", HandlePingEvent)
413 Taonnor-14572
        LMP:UnregisterCallback("AfterPingRemoved", HandlePingEvent)
414 49 Taonnor-14572
 
415 Taonnor-14572
        rootMaps, mapMeasurements, mapStack = nil, nil, nil
416 40 Taonnor-14572
    end
417 Taonnor-14572
 
418 49 Taonnor-14572
    ConnectToWorldMap()
419 40 Taonnor-14572
 
420 49 Taonnor-14572
    HookSetMapToFunction("SetMapToQuestCondition")
421 Taonnor-14572
    HookSetMapToFunction("SetMapToQuestStepEnding")
422 Taonnor-14572
    HookSetMapToFunction("SetMapToQuestZone")
423 40 Taonnor-14572
    HookSetMapToPlayerLocation()
424 Taonnor-14572
    HookSetMapToMapListIndex()
425 Taonnor-14572
    HookProcessMapClick()
426 Taonnor-14572
    HookSetMapFloor()
427 Taonnor-14572
 
428 Taonnor-14572
    StoreTamrielMapMeasurements()
429 49 Taonnor-14572
 
430 Taonnor-14572
    local function addRootMap(zoneId)
431 Taonnor-14572
        local mapIndex = GetMapIndexByZoneId(zoneId)
432 Taonnor-14572
        if mapIndex then rootMaps[mapIndex] = false end
433 Taonnor-14572
    end
434 Taonnor-14572
    addRootMap(347) -- Coldhabour
435 Taonnor-14572
    addRootMap(980) -- Clockwork City
436 Taonnor-14572
    -- Any future extra dimension map here
437 Taonnor-14572
 
438 40 Taonnor-14572
    SetMapToPlayerLocation() -- initial measurement so we can get back to where we are currently
439 Taonnor-14572
 
440 Taonnor-14572
    LMP:RegisterCallback("AfterPingAdded", HandlePingEvent)
441 Taonnor-14572
    LMP:RegisterCallback("AfterPingRemoved", HandlePingEvent)
442 Taonnor-14572
end
443 Taonnor-14572
 
444 Taonnor-14572
------------------------ public functions ----------------------
445 Taonnor-14572
 
446 Taonnor-14572
--- Returns true as long as the player exists.
447 Taonnor-14572
function lib:IsReady()
448 Taonnor-14572
    return DoesUnitExist("player")
449 Taonnor-14572
end
450 Taonnor-14572
 
451 Taonnor-14572
--- Returns true if the library is currently doing any measurements.
452 Taonnor-14572
function lib:IsMeasuring()
453 Taonnor-14572
    return measuring
454 Taonnor-14572
end
455 Taonnor-14572
 
456 Taonnor-14572
--- Removes all cached measurement values.
457 Taonnor-14572
function lib:ClearMapMeasurements()
458 Taonnor-14572
    mapMeasurements = { }
459 Taonnor-14572
end
460 Taonnor-14572
 
461 Taonnor-14572
--- Removes the cached measurement values for the map that is currently active.
462 Taonnor-14572
function lib:ClearCurrentMapMeasurements()
463 Taonnor-14572
    local mapId = GetMapTileTexture()
464 Taonnor-14572
    mapMeasurements[mapId] = nil
465 Taonnor-14572
end
466 Taonnor-14572
 
467 Taonnor-14572
--- Returns a table with the measurement values for the active map or nil if the measurements could not be calculated for some reason.
468 Taonnor-14572
--- The table contains scaleX, scaleY, offsetX, offsetY and mapIndex.
469 Taonnor-14572
--- scaleX and scaleY are the dimensions of the active map on the Tamriel map.
470 Taonnor-14572
--- offsetX and offsetY are the offset of the top left corner on the Tamriel map.
471 Taonnor-14572
--- mapIndex is the mapIndex of the parent zone of the current map.
472 Taonnor-14572
function lib:GetCurrentMapMeasurements()
473 Taonnor-14572
    local mapId = GetMapTileTexture()
474 Taonnor-14572
    if (not mapMeasurements[mapId]) then
475 Taonnor-14572
        -- try to calculate the measurements if they are not yet available
476 Taonnor-14572
        lib:CalculateMapMeasurements()
477 Taonnor-14572
    end
478 Taonnor-14572
    return mapMeasurements[mapId]
479 Taonnor-14572
end
480 Taonnor-14572
 
481 49 Taonnor-14572
--- Returns the mapIndex and zoneIndex of the parent zone for the currently set map.
482 Taonnor-14572
--- return[1] number - The mapIndex of the parent zone
483 Taonnor-14572
--- return[2] number - The zoneIndex of the parent zone
484 Taonnor-14572
function lib:GetCurrentMapParentZoneIndices()
485 Taonnor-14572
    local measurements = lib:GetCurrentMapMeasurements()
486 Taonnor-14572
    local mapIndex = measurements.mapIndex
487 Taonnor-14572
    if(not measurements.zoneIndex) then
488 Taonnor-14572
        lib:PushCurrentMap()
489 Taonnor-14572
        SetMapToMapListIndex(mapIndex)
490 Taonnor-14572
        measurements.zoneIndex = GetCurrentMapZoneIndex()
491 Taonnor-14572
        lib:PopCurrentMap()
492 Taonnor-14572
    end
493 Taonnor-14572
    local zoneIndex = measurements.zoneIndex
494 Taonnor-14572
    return mapIndex, zoneIndex
495 Taonnor-14572
end
496 Taonnor-14572
 
497 40 Taonnor-14572
--- Calculates the measurements for the current map and all parent maps.
498 Taonnor-14572
--- This method does nothing if there is already a cached measurement for the active map.
499 Taonnor-14572
--- return[1] boolean - True, if a valid measurement was calculated
500 Taonnor-14572
--- return[2] SetMapResultCode - Specifies if the map has changed or failed during measurement (independent of the actual result of the measurement)
501 Taonnor-14572
function lib:CalculateMapMeasurements(returnToInitialMap)
502 Taonnor-14572
    -- cosmic map cannot be measured (GetMapPlayerWaypoint returns 0,0)
503 Taonnor-14572
    if (GetMapType() == MAPTYPE_COSMIC) then return false, SET_MAP_RESULT_CURRENT_MAP_UNCHANGED end
504 Taonnor-14572
 
505 Taonnor-14572
    -- no need to take measurements more than once
506 Taonnor-14572
    local mapId = GetMapTileTexture()
507 Taonnor-14572
    if (mapMeasurements[mapId] or mapId == "") then return false end
508 Taonnor-14572
 
509 Taonnor-14572
    if (lib.debugMode) then
510 Taonnor-14572
        LogMessage("Called from", GetAddon(), "for", mapId)
511 Taonnor-14572
    end
512 Taonnor-14572
 
513 Taonnor-14572
    -- get the player position on the current map
514 Taonnor-14572
    local localX, localY = GetPlayerPosition()
515 Taonnor-14572
    if (localX == 0 and localY == 0) then
516 Taonnor-14572
        -- cannot take measurements while player position is not initialized
517 Taonnor-14572
        return false, SET_MAP_RESULT_CURRENT_MAP_UNCHANGED
518 Taonnor-14572
    end
519 Taonnor-14572
 
520 Taonnor-14572
    returnToInitialMap = (returnToInitialMap ~= false)
521 Taonnor-14572
 
522 Taonnor-14572
    measuring = true
523 Taonnor-14572
    CALLBACK_MANAGER:FireCallbacks(lib.LIB_EVENT_STATE_CHANGED, measuring)
524 Taonnor-14572
 
525 Taonnor-14572
    -- check some facts about the current map, so we can reset it later
526 Taonnor-14572
    -- local oldMapIsZoneMap, oldMapFloor, oldMapFloorCount
527 Taonnor-14572
    if returnToInitialMap then
528 Taonnor-14572
        lib:PushCurrentMap()
529 Taonnor-14572
    end
530 Taonnor-14572
 
531 Taonnor-14572
    local hasWaypoint = LMP:HasMapPing(MAP_PIN_TYPE_PLAYER_WAYPOINT)
532 Taonnor-14572
    if(hasWaypoint) then StoreCurrentWaypoint() end
533 Taonnor-14572
 
534 Taonnor-14572
    local mapIndex = CalculateMeasurements(mapId, localX, localY)
535 Taonnor-14572
 
536 Taonnor-14572
    -- Until now, the waypoint was abused. Now the waypoint must be restored or removed again (not from Lua only).
537 Taonnor-14572
    if(hasWaypoint) then
538 Taonnor-14572
        RestoreCurrentWaypoint()
539 Taonnor-14572
    else
540 Taonnor-14572
        RemovePlayerWaypoint()
541 Taonnor-14572
    end
542 Taonnor-14572
 
543 Taonnor-14572
    if (returnToInitialMap) then
544 Taonnor-14572
        local result = lib:PopCurrentMap()
545 Taonnor-14572
        return true, result
546 Taonnor-14572
    end
547 Taonnor-14572
 
548 Taonnor-14572
    return true, (mapId == GetMapTileTexture()) and SET_MAP_RESULT_CURRENT_MAP_UNCHANGED or SET_MAP_RESULT_MAP_CHANGED
549 Taonnor-14572
end
550 Taonnor-14572
 
551 Taonnor-14572
--- Converts the given map coordinates on the current map into coordinates on the Tamriel map.
552 Taonnor-14572
--- Returns x and y on the world map and the mapIndex of the parent zone
553 Taonnor-14572
--- or nil if the measurements of the active map are not available.
554 Taonnor-14572
function lib:LocalToGlobal(x, y)
555 Taonnor-14572
    local measurements = lib:GetCurrentMapMeasurements()
556 Taonnor-14572
    if (measurements) then
557 Taonnor-14572
        x = x * measurements.scaleX + measurements.offsetX
558 Taonnor-14572
        y = y * measurements.scaleY + measurements.offsetY
559 Taonnor-14572
        return x, y, measurements.mapIndex
560 Taonnor-14572
    end
561 Taonnor-14572
end
562 Taonnor-14572
 
563 Taonnor-14572
--- Converts the given global coordinates into a position on the active map.
564 Taonnor-14572
--- Returns x and y on the current map or nil if the measurements of the active map are not available.
565 Taonnor-14572
function lib:GlobalToLocal(x, y)
566 Taonnor-14572
    local measurements = lib:GetCurrentMapMeasurements()
567 Taonnor-14572
    if (measurements) then
568 Taonnor-14572
        x = (x - measurements.offsetX) / measurements.scaleX
569 Taonnor-14572
        y = (y - measurements.offsetY) / measurements.scaleY
570 Taonnor-14572
        return x, y
571 Taonnor-14572
    end
572 Taonnor-14572
end
573 Taonnor-14572
 
574 Taonnor-14572
--- Converts the given map coordinates on the specified zone map into coordinates on the Tamriel map.
575 Taonnor-14572
--- This method is useful if you want to convert global positions from the old LibGPS version into the new format.
576 Taonnor-14572
--- Returns x and y on the world map and the mapIndex of the parent zone
577 Taonnor-14572
--- or nil if the measurements of the zone map are not available.
578 Taonnor-14572
function lib:ZoneToGlobal(mapIndex, x, y)
579 Taonnor-14572
    lib:GetCurrentMapMeasurements()
580 Taonnor-14572
    -- measurement done in here:
581 Taonnor-14572
    SetMapToMapListIndex(mapIndex)
582 Taonnor-14572
    x, y, mapIndex = lib:LocalToGlobal(x, y)
583 Taonnor-14572
    return x, y, mapIndex
584 Taonnor-14572
end
585 Taonnor-14572
 
586 Taonnor-14572
--- This function zooms and pans to the specified position on the active map.
587 Taonnor-14572
function lib:PanToMapPosition(x, y)
588 Taonnor-14572
    -- if we don't have access to the mapPinManager we cannot do anything
589 49 Taonnor-14572
    if (not self.mapPinManager) then return end
590 Taonnor-14572
    local mapPinManager = self.mapPinManager
591 40 Taonnor-14572
    -- create dummy pin
592 Taonnor-14572
    local pin = mapPinManager:CreatePin(_G[DUMMY_PIN_TYPE], "libgpsdummy", x, y)
593 Taonnor-14572
 
594 49 Taonnor-14572
    self.panAndZoom:PanToPin(pin)
595 40 Taonnor-14572
 
596 Taonnor-14572
    -- cleanup
597 Taonnor-14572
    mapPinManager:RemovePins(DUMMY_PIN_TYPE)
598 Taonnor-14572
end
599 Taonnor-14572
 
600 Taonnor-14572
local function FakeZO_WorldMap_IsMapChangingAllowed() return true end
601 Taonnor-14572
local function FakeSetMapToMapListIndex() return SET_MAP_RESULT_MAP_CHANGED end
602 Taonnor-14572
local FakeCALLBACK_MANAGER = { FireCallbacks = function() end }
603 Taonnor-14572
 
604 Taonnor-14572
--- This function sets the current map as player chosen so it won't switch back to the previous map.
605 Taonnor-14572
function lib:SetPlayerChoseCurrentMap()
606 Taonnor-14572
    -- replace the original functions
607 Taonnor-14572
    local oldIsChangingAllowed = ZO_WorldMap_IsMapChangingAllowed
608 Taonnor-14572
    ZO_WorldMap_IsMapChangingAllowed = FakeZO_WorldMap_IsMapChangingAllowed
609 Taonnor-14572
 
610 Taonnor-14572
    local oldSetMapToMapListIndex = SetMapToMapListIndex
611 Taonnor-14572
    SetMapToMapListIndex = FakeSetMapToMapListIndex
612 Taonnor-14572
 
613 Taonnor-14572
    local oldCALLBACK_MANAGER = CALLBACK_MANAGER
614 Taonnor-14572
    CALLBACK_MANAGER = FakeCALLBACK_MANAGER
615 Taonnor-14572
 
616 Taonnor-14572
    -- make our rigged call to set the player chosen flag
617 Taonnor-14572
    ZO_WorldMap_SetMapByIndex()
618 Taonnor-14572
 
619 Taonnor-14572
    -- cleanup
620 Taonnor-14572
    ZO_WorldMap_IsMapChangingAllowed = oldIsChangingAllowed
621 Taonnor-14572
    SetMapToMapListIndex = oldSetMapToMapListIndex
622 Taonnor-14572
    CALLBACK_MANAGER = oldCALLBACK_MANAGER
623 Taonnor-14572
end
624 Taonnor-14572
 
625 61 Taonnor-14572
--- Sets the best matching root map: Tamriel, Cold Harbour or Clockwork City and what ever will come.
626 Taonnor-14572
--- Returns SET_MAP_RESULT_FAILED, SET_MAP_RESULT_MAP_CHANGED depending on the result of the API calls.
627 Taonnor-14572
function lib:SetMapToRootMap(x, y)
628 Taonnor-14572
    local result = SET_MAP_RESULT_FAILED
629 Taonnor-14572
    for rootMapIndex, measurements in pairs(rootMaps) do
630 Taonnor-14572
        if (not measurements) then
631 Taonnor-14572
            measurements = GetExtraMapMeasurement(rootMapIndex)
632 Taonnor-14572
            rootMaps[rootMapIndex] = measurements
633 Taonnor-14572
            result = SET_MAP_RESULT_MAP_CHANGED
634 Taonnor-14572
        end
635 Taonnor-14572
        if (measurements) then
636 Taonnor-14572
            if (x > measurements.offsetX and x < (measurements.offsetX + measurements.scaleX) and
637 Taonnor-14572
                y > measurements.offsetY and y < (measurements.offsetY + measurements.scaleY)) then
638 Taonnor-14572
                if (orgSetMapToMapListIndex(rootMapIndex) ~= SET_MAP_RESULT_FAILED) then
639 Taonnor-14572
                    return SET_MAP_RESULT_MAP_CHANGED
640 Taonnor-14572
                end
641 Taonnor-14572
            end
642 Taonnor-14572
        end
643 Taonnor-14572
    end
644 Taonnor-14572
    return result
645 Taonnor-14572
end
646 Taonnor-14572
 
647 40 Taonnor-14572
--- Repeatedly calls ProcessMapClick on the given global position starting on the Tamriel map until nothing more would happen.
648 Taonnor-14572
--- Returns SET_MAP_RESULT_FAILED, SET_MAP_RESULT_MAP_CHANGED or SET_MAP_RESULT_CURRENT_MAP_UNCHANGED depending on the result of the API calls.
649 Taonnor-14572
function lib:MapZoomInMax(x, y)
650 61 Taonnor-14572
    local result = lib:SetMapToRootMap(x, y)
651 40 Taonnor-14572
 
652 Taonnor-14572
    if (result ~= SET_MAP_RESULT_FAILED) then
653 61 Taonnor-14572
        local localX, localY = lib:GlobalToLocal(x, y)
654 40 Taonnor-14572
 
655 Taonnor-14572
        while WouldProcessMapClick(localX, localY) do
656 Taonnor-14572
            result = orgProcessMapClick(localX, localY)
657 Taonnor-14572
            if (result == SET_MAP_RESULT_FAILED) then break end
658 Taonnor-14572
            localX, localY = lib:GlobalToLocal(x, y)
659 Taonnor-14572
        end
660 Taonnor-14572
    end
661 Taonnor-14572
 
662 Taonnor-14572
    return result
663 Taonnor-14572
end
664 Taonnor-14572
 
665 Taonnor-14572
--- Stores information about how we can back to this map on a stack.
666 49 Taonnor-14572
-- There is no panAndZoom:GetCurrentOffset(), yet
667 Taonnor-14572
local function CalculateContainerAnchorOffsets()
668 Taonnor-14572
    local containerCenterX, containerCenterY = ZO_WorldMapContainer:GetCenter()
669 Taonnor-14572
    local scrollCenterX, scrollCenterY = ZO_WorldMapScroll:GetCenter()
670 Taonnor-14572
    return containerCenterX - scrollCenterX, containerCenterY - scrollCenterY
671 Taonnor-14572
end
672 40 Taonnor-14572
function lib:PushCurrentMap()
673 49 Taonnor-14572
    local wasPlayerLocation, targetMapTileTexture, currentMapFloor, currentMapFloorCount, currentMapIndex, zoom, offsetX, offsetY
674 40 Taonnor-14572
    currentMapIndex = GetCurrentMapIndex()
675 49 Taonnor-14572
    wasPlayerLocation = DoesCurrentMapMatchMapForPlayerLocation()
676 40 Taonnor-14572
    targetMapTileTexture = GetMapTileTexture()
677 Taonnor-14572
    currentMapFloor, currentMapFloorCount = GetMapFloorInfo()
678 49 Taonnor-14572
    zoom = self.panAndZoom:GetCurrentZoom()
679 Taonnor-14572
    offsetX, offsetY = CalculateContainerAnchorOffsets()
680 40 Taonnor-14572
 
681 49 Taonnor-14572
    mapStack[#mapStack + 1] = { wasPlayerLocation, targetMapTileTexture, currentMapFloor, currentMapFloorCount, currentMapIndex, zoom, offsetX, offsetY }
682 40 Taonnor-14572
end
683 Taonnor-14572
 
684 Taonnor-14572
--- Switches to the map that was put on the stack last.
685 Taonnor-14572
--- Returns SET_MAP_RESULT_FAILED, SET_MAP_RESULT_MAP_CHANGED or SET_MAP_RESULT_CURRENT_MAP_UNCHANGED depending on the result of the API calls.
686 Taonnor-14572
function lib:PopCurrentMap()
687 Taonnor-14572
    local result = SET_MAP_RESULT_FAILED
688 Taonnor-14572
    local data = table.remove(mapStack, #mapStack)
689 Taonnor-14572
    if(not data) then
690 Taonnor-14572
        LogMessage(LOG_DEBUG, "PopCurrentMap failed. No data on map stack.")
691 Taonnor-14572
        return result
692 Taonnor-14572
    end
693 Taonnor-14572
 
694 49 Taonnor-14572
    local wasPlayerLocation, targetMapTileTexture, currentMapFloor, currentMapFloorCount, currentMapIndex, zoom, offsetX, offsetY = unpack(data)
695 40 Taonnor-14572
    local currentTileTexture = GetMapTileTexture()
696 Taonnor-14572
    if(currentTileTexture ~= targetMapTileTexture) then
697 Taonnor-14572
        if(wasPlayerLocation) then
698 Taonnor-14572
            result = orgSetMapToPlayerLocation()
699 Taonnor-14572
 
700 Taonnor-14572
        elseif(currentMapIndex ~= nil and currentMapIndex > 0) then -- set to a zone map
701 Taonnor-14572
            result = orgSetMapToMapListIndex(currentMapIndex)
702 Taonnor-14572
 
703 Taonnor-14572
        else -- here is where it gets tricky
704 Taonnor-14572
            local target = mapMeasurements[targetMapTileTexture]
705 Taonnor-14572
            if(not target) then -- always just return to player map if we cannot restore the previous map.
706 Taonnor-14572
                LogMessage(LOG_DEBUG, string.format("No measurement for \"%s\". Returning to player location.", targetMapTileTexture))
707 Taonnor-14572
                return orgSetMapToPlayerLocation()
708 Taonnor-14572
            end
709 Taonnor-14572
 
710 Taonnor-14572
            -- switch to the parent zone
711 Taonnor-14572
            if(target.mapIndex == TAMRIEL_MAP_INDEX) then -- zone map has no mapIndex (e.g. Eyevea or Hew's Bane on first PTS patch for update 9)
712 Taonnor-14572
                -- switch to the tamriel map just in case
713 Taonnor-14572
                result = orgSetMapToMapListIndex(TAMRIEL_MAP_INDEX)
714 Taonnor-14572
                if(result == SET_MAP_RESULT_FAILED) then return result end
715 Taonnor-14572
                -- get global coordinates of target map center
716 Taonnor-14572
                local x = target.offsetX + (target.scaleX / 2)
717 Taonnor-14572
                local y = target.offsetY + (target.scaleY / 2)
718 Taonnor-14572
                if(not WouldProcessMapClick(x, y)) then
719 Taonnor-14572
                    LogMessage(LOG_DEBUG, string.format("Cannot process click at %s/%s on map \"%s\" in order to get to \"%s\". Returning to player location instead.", tostring(x), tostring(y), GetMapTileTexture(), targetMapTileTexture))
720 Taonnor-14572
                    return orgSetMapToPlayerLocation()
721 Taonnor-14572
                end
722 Taonnor-14572
                result = orgProcessMapClick(x, y)
723 Taonnor-14572
                if(result == SET_MAP_RESULT_FAILED) then return result end
724 Taonnor-14572
            else
725 Taonnor-14572
                result = orgSetMapToMapListIndex(target.mapIndex)
726 Taonnor-14572
                if(result == SET_MAP_RESULT_FAILED) then return result end
727 Taonnor-14572
            end
728 Taonnor-14572
 
729 Taonnor-14572
            -- switch to the sub zone
730 Taonnor-14572
            currentTileTexture = GetMapTileTexture()
731 Taonnor-14572
            if(currentTileTexture ~= targetMapTileTexture) then
732 Taonnor-14572
                -- determine where on the zone map we have to click to get to the sub zone map
733 Taonnor-14572
                -- get global coordinates of target map center
734 Taonnor-14572
                local x = target.offsetX + (target.scaleX / 2)
735 Taonnor-14572
                local y = target.offsetY + (target.scaleY / 2)
736 Taonnor-14572
                -- transform to local coordinates
737 Taonnor-14572
                local current = mapMeasurements[currentTileTexture]
738 Taonnor-14572
                if(not current) then
739 Taonnor-14572
                    LogMessage(LOG_DEBUG, string.format("No measurement for \"%s\". Returning to player location.", currentTileTexture))
740 Taonnor-14572
                    return orgSetMapToPlayerLocation()
741 Taonnor-14572
                end
742 Taonnor-14572
 
743 Taonnor-14572
                x = (x - current.offsetX) / current.scaleX
744 Taonnor-14572
                y = (y - current.offsetY) / current.scaleY
745 Taonnor-14572
 
746 Taonnor-14572
                if(not WouldProcessMapClick(x, y)) then
747 Taonnor-14572
                    LogMessage(LOG_DEBUG, string.format("Cannot process click at %s/%s on map \"%s\" in order to get to \"%s\". Returning to player location instead.", tostring(x), tostring(y), GetMapTileTexture(), targetMapTileTexture))
748 Taonnor-14572
                    return orgSetMapToPlayerLocation()
749 Taonnor-14572
                end
750 Taonnor-14572
                result = orgProcessMapClick(x, y)
751 Taonnor-14572
                if(result == SET_MAP_RESULT_FAILED) then return result end
752 Taonnor-14572
            end
753 Taonnor-14572
 
754 Taonnor-14572
            -- switch to the correct floor (e.g. Elden Root)
755 Taonnor-14572
            if (currentMapFloorCount > 0) then
756 Taonnor-14572
                result = orgSetMapFloor(currentMapFloor)
757 Taonnor-14572
            end
758 49 Taonnor-14572
            if (result ~= SET_MAP_RESULT_FAILED) then
759 Taonnor-14572
                lib.panAndZoom:SetCurrentZoom(zoom)
760 Taonnor-14572
                lib.panAndZoom:SetCurrentOffset(offsetX, offsetY)
761 Taonnor-14572
            end
762 61 Taonnor-14572
        end
763 40 Taonnor-14572
    else
764 Taonnor-14572
        result = SET_MAP_RESULT_CURRENT_MAP_UNCHANGED
765 Taonnor-14572
    end
766 Taonnor-14572
 
767 Taonnor-14572
    return result
768 Taonnor-14572
end
769 Taonnor-14572
 
770 Taonnor-14572
Initialize()