diff --git a/MapUtils.lua b/MapUtils.lua
new file mode 100644
index 0000000..be2a9db
--- /dev/null
+++ b/MapUtils.lua
@@ -0,0 +1,139 @@
+local addonName, addon = ...
+local L = addon.L
+
+local astrolabe = DongleStub("Astrolabe-1.0")
+local mapdata = LibStub("LibMapData-1.0")
+
+local PI2 = math.pi * 2
+
+-- This file is an API abstraction over the mapping system in World of
+-- Warcraft, however it does not aim to be a complete abstraction. Instead, we
+-- merely provide those functions that are relevant to TomTom, and try to
+-- provide a way for the necessary data to be obtained without care for how it
+-- is obtained.
+
+local function getDirection(xd, yd)
+ if not xd or not yd then
+ return nil
+ end
+
+ local angle = math.atan2(xd, -yd)
+ if angle > 0 then
+ angle = PI2 - angle
+ else
+ angle = -angle
+ end
+
+ return angle
+end
+
+-- Calculates the distance (in yards) and angle (in radians) between two points
+-- on the map. This may be two points within the same map file, or two points
+-- on different maps. In the case that the points are on different maps and
+-- there's no 'distance' that quite makes sense, this function will simply
+-- return nil
+
+function addon:GetVector(sm, sf, sx, sy, dm, df, dx, dy)
+ if smap == dmap and sfloor == dfloor then
+ -- The waypoints are on the same map, so calculate directly using map data
+
+ if mapdata then
+ local dist, xd, yd = mapdata:Distance(sm, sf, sx, sy, dx, dy)
+ local angle = getDirection(xd, yd)
+
+ if dist and angle then
+ return dist, angle
+ end
+ elseif astrolabe then
+ local dist, xd, yd = astrolabe:ComputeDistance(sm, sf, sx, sy, dm, df, dx, dy)
+ local angle = GetDirection(xd, yd)
+ if dist and angle then
+ return dist, angle
+ end
+ else
+ error("No map data available for 'GetVector'")
+ end
+ else
+ -- The waypoints are on different maps
+
+ if mapdata then
+ local dist, xd, yd = mapdata:DistanceWithinContinent(sm, sf, sx, sy, dm, df, dx, dy)
+ local angle = GetDirection(xd, yd)
+ if dist and angle then
+ return dist, angle
+ end
+ elseif astrolabe then
+ local dist, xd, yd = astrolabe:ComputeDistance(sm, sf, sx, sy, dm, df, dx, dy)
+ local angle = GetDistance(xd, yd)
+ if dist and angle then
+ return dist, angle
+ end
+ else
+ error("No map data available for 'GetVector'")
+ end
+ end
+end
+
+-- Get the distance (in yards) and angle (in radians) from the player's current
+-- position to a position on the map.
+
+function addon:GetVectorFromCurrent(map, floor, x, y)
+
+ -- First we need to obtain the player's current position. Attempt, at all
+ -- costs to do this without changing the map zoom, as it shouldn't be
+ -- necessary.
+
+ local cmap, cfloor = GetCurrentMapAreaID()
+ local cx, cy = GetPlayerMapPosition("player")
+
+ if map and floor and x and y then
+ return self:GetVector(cmap, cfloor, cx, cy, map, floor, x, y)
+ end
+end
+
+-- This function returns the display name for a given map. If the name is not
+-- available, then "Unknown map: %d" is displayed
+function addon:GetMapDisplayName(map)
+ if mapdata then
+ local name = mapdata:MapLocalize(map)
+ return name or string.format("Unknown map: %d", map)
+ elseif astrolabe then
+ return string.format("Unknown map: %d", map)
+ end
+end
+
+-- This data is hardcoded, and should be able to be automatically obtained
+local continents = {
+ -- Map for cosmic (both ways)
+ [WORLDMAP_COSMIC_ID] = -1, -- Cosmic map (-1)
+
+ -- Map from mapId to continentIndex
+ [13] = 1, -- Kalimdor (1)
+ [14] = 2, -- Eastern Kingdoms (2)
+ [466] = 3, -- Outland (3)
+ [485] = 4, -- Northrend (4)
+ [751] = 5, -- Maelstrom (5)
+
+ -- Map from continentIndex to mapId
+ [1] = 13,
+ [2] = 14,
+ [3] = 466,
+ [4] = 485,
+ [5] = 751,
+}
+
+-- Returns if a given map file is a continent map
+function addon:IsContinentMap(map)
+ return not not continents[map]
+end
+
+-- Returns the continent map that 'owns' a given map. This does NOT return the
+-- continent index, but rather the continent map file.
+function addon:GetMapContinentMap(map)
+ if mapdata then
+ local cindex = mapdata:GetContinentFromMap(map)
+ local cmap = continents[cindex]
+ return cmap
+ elseif astrolabe then
+ end
+end
diff --git a/TomTomLite.lua b/TomTomLite.lua
index 6f3026e..110d7fa 100644
--- a/TomTomLite.lua
+++ b/TomTomLite.lua
@@ -6,7 +6,6 @@ local addonName, addon = ...
local L = addon.L
addon.callbacks = LibStub("CallbackHandler-1.0"):New(addon)
-addon.mapdata = LibStub("LibMapData-1.0")
addon.libwindow = LibStub("LibWindow-1.1")
-- Set up some tables to track waypoints
@@ -95,29 +94,8 @@ function addon:CreateCrazyArrow(name, parent)
-- Set up the OnUpdate handler
frame:SetScript("OnUpdate", function(self, elapsed)
- -- Get the current location
- local cmap = GetCurrentMapAreaID()
- local cx, cy = GetPlayerMapPosition("player")
local map, floor, x, y = unpack(self.waypoint)
- if not (cmap and cx and cy and map and floor and x and y) then
- -- This shouldn't happen, but bail out in this case
- return
- end
-
- -- If on the cosmic map, do nothing
- if cmap == -1 then
- return
- end
-
-
- local distance, xd, yd = addon.mapdata:DistanceWithinContinent(cmap, 0, cx, cy, map, floor, x, y)
-
- local angle = math.atan2(xd, yd)
- if angle > 0 then
- angle = PI2 - angle
- else
- angle = -angle
- end
+ local distance, angle = addon:GetVectorFromCurrent(map, floor, x, y)
local facing = GetPlayerFacing()
local faceangle = angle - facing
@@ -215,7 +193,7 @@ function addon:UpdateArrow()
if closest then
-- Set the crazy arrow to display this waypoint
local zone, floor, x, y = unpack(closest)
- local lzone = self.mapdata:MapLocalize(zone)
+ local lzone = self:GetMapDisplayName(zone)
self.arrow.waypoint = closest
self.arrow.title:SetText(closest.title or L["Unknown waypoint"])
@@ -233,7 +211,7 @@ function addon:UpdateQuestObjectives()
floor = floor or 0
-- Do not set any NEW waypoints if we're on the continent map
- if self.mapdata:IsContinentMap(map) then
+ if self:IsContinentMap(map) then
return
end
diff --git a/TomTomLite.toc b/TomTomLite.toc
index 345167b..ae036a0 100755
--- a/TomTomLite.toc
+++ b/TomTomLite.toc
@@ -17,6 +17,7 @@ libs\AceDB-3.0\AceDB-3.0.xml
libs\LibMapData-1.0\library.lua
libs\LibWindow-1.1.lua
+MapUtils.lua
Utils.lua
DatabaseDefaults.lua