vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[ |
2 | Name: Astrolabe |
||
3 | Revision: $Rev: 19 $ |
||
4 | $Date: 2006-11-26 09:36:31 +0100 (So, 26 Nov 2006) $ |
||
5 | Author(s): Esamynn (jcarrothers@gmail.com) |
||
6 | Inspired By: Gatherer by Norganna |
||
7 | MapLibrary by Kristofer Karlsson (krka@kth.se) |
||
8 | Website: http://esamynn.wowinterface.com/ |
||
9 | Documentation: |
||
10 | SVN: |
||
11 | Description: |
||
12 | This is a library for the World of Warcraft UI system to place |
||
13 | icons accurately on both the Minimap and the Worldmaps accurately |
||
14 | and maintain the accuracy of those positions. |
||
15 | |||
16 | License: |
||
17 | |||
18 | Copyright (C) 2006 James Carrothers |
||
19 | |||
20 | This library is free software; you can redistribute it and/or |
||
21 | modify it under the terms of the GNU Lesser General Public |
||
22 | License as published by the Free Software Foundation; either |
||
23 | version 2.1 of the License, or (at your option) any later version. |
||
24 | |||
25 | This library is distributed in the hope that it will be useful, |
||
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
28 | Lesser General Public License for more details. |
||
29 | |||
30 | You should have received a copy of the GNU Lesser General Public |
||
31 | License along with this library; if not, write to the Free Software |
||
32 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
33 | ]] |
||
34 | |||
35 | local LIBRARY_VERSION_MAJOR = "Astrolabe-0.2" |
||
36 | local LIBRARY_VERSION_MINOR = "$Revision: 19 $" |
||
37 | if not AceLibrary then error(LIBRARY_VERSION_MAJOR .. " requires AceLibrary.") end |
||
38 | if not AceLibrary:IsNewVersion(LIBRARY_VERSION_MAJOR, LIBRARY_VERSION_MINOR) then return end |
||
39 | Astrolabe = {}; |
||
40 | WorldMapSize, MinimapSize = {}, {} |
||
41 | local initSizes |
||
42 | -------------------------------------------------------------------------------------------------------------- |
||
43 | -- Working Tables and Config Constants |
||
44 | -------------------------------------------------------------------------------------------------------------- |
||
45 | Astrolabe.LastPlayerPosition = {}; |
||
46 | Astrolabe.MinimapIcons = {}; |
||
47 | Astrolabe.MinimapUpdateTime = 0.2; |
||
48 | Astrolabe.UpdateTimer = 0.2; |
||
49 | Astrolabe.ForceNextUpdate = false; |
||
50 | Astrolabe.minimapOutside = false; |
||
51 | local twoPi = math.pi * 2; |
||
52 | -------------------------------------------------------------------------------------------------------------- |
||
53 | -- General Uility Functions |
||
54 | -------------------------------------------------------------------------------------------------------------- |
||
55 | local function getContPosition( zoneData, z, x, y ) |
||
56 | --Fixes nil error |
||
57 | if z < 0 then |
||
58 | z = 1; |
||
59 | end |
||
60 | if ( z ~= 0 ) then |
||
61 | zoneData = zoneData[z]; |
||
62 | x = x * zoneData.width + zoneData.xOffset; |
||
63 | y = y * zoneData.height + zoneData.yOffset; |
||
64 | else |
||
65 | x = x * zoneData.width; |
||
66 | y = y * zoneData.height; |
||
67 | end |
||
68 | return x, y; |
||
69 | end |
||
70 | |||
71 | function Astrolabe:ComputeDistance( c1, z1, x1, y1, c2, z2, x2, y2 ) |
||
72 | z1 = z1 or 0; |
||
73 | z2 = z2 or 0; |
||
74 | |||
75 | local dist, xDelta, yDelta; |
||
76 | if ( c1 == c2 and z1 == z2 ) then |
||
77 | -- points in the same zone |
||
78 | local zoneData = WorldMapSize[c1]; |
||
79 | if ( z1 ~= 0 ) then |
||
80 | zoneData = zoneData[z1]; |
||
81 | end |
||
82 | if zoneData == nil then |
||
83 | return 0, 0, 0; -- temporary fix, todo: log this |
||
84 | end |
||
85 | xDelta = (x2 - x1) * zoneData.width; |
||
86 | yDelta = (y2 - y1) * zoneData.height; |
||
87 | elseif ( c1 == c2 ) then |
||
88 | -- points on the same continent |
||
89 | local zoneData = WorldMapSize[c1]; |
||
90 | if zoneData == nil then |
||
91 | return 0, 0, 0; -- temporary fix, todo: log this |
||
92 | end |
||
93 | x1, y1 = getContPosition(zoneData, z1, x1, y1); |
||
94 | x2, y2 = getContPosition(zoneData, z2, x2, y2); |
||
95 | xDelta = (x2 - x1); |
||
96 | yDelta = (y2 - y1); |
||
97 | elseif ( c1 and c2 ) then |
||
98 | local cont1 = WorldMapSize[c1]; |
||
99 | local cont2 = WorldMapSize[c2]; |
||
100 | if cont1 == nil or cont2 == nil then |
||
101 | return 0, 0, 0; -- temporary fix, todo: log this |
||
102 | end |
||
103 | if ( cont1.parentContinent == cont2.parentContinent ) then |
||
104 | if ( c1 ~= cont1.parentContinent ) then |
||
105 | x1, y1 = getContPosition(cont1, z1, x1, y1); |
||
106 | x1 = x1 + cont1.xOffset; |
||
107 | y1 = y1 + cont1.yOffset; |
||
108 | end |
||
109 | if ( c2 ~= cont2.parentContinent ) then |
||
110 | x2, y2 = getContPosition(cont2, z2, x2, y2); |
||
111 | x2 = x2 + cont2.xOffset; |
||
112 | y2 = y2 + cont2.yOffset; |
||
113 | end |
||
114 | xDelta = x2 - x1; |
||
115 | yDelta = y2 - y1; |
||
116 | end |
||
117 | end |
||
118 | if ( xDelta and yDelta ) then |
||
119 | dist = sqrt(xDelta*xDelta + yDelta*yDelta); |
||
120 | end |
||
121 | return dist, xDelta, yDelta; |
||
122 | end |
||
123 | |||
124 | function Astrolabe:TranslateWorldMapPosition( C, Z, xPos, yPos, nC, nZ ) |
||
125 | Z = Z or 0; |
||
126 | nZ = nZ or 0; |
||
127 | if ( nC < 0 ) then |
||
128 | return; |
||
129 | end |
||
130 | --Fixes nil error. |
||
131 | if(C < 0) then |
||
132 | C=2; |
||
133 | end |
||
134 | if(nC < 0) then |
||
135 | nC = 2; |
||
136 | end |
||
137 | local zoneData; |
||
138 | if ( C == nC and Z == nZ ) then |
||
139 | return xPos, yPos; |
||
140 | elseif ( C == nC ) then |
||
141 | -- points on the same continent |
||
142 | zoneData = WorldMapSize[C]; |
||
143 | xPos, yPos = getContPosition(zoneData, Z, xPos, yPos); |
||
144 | if ( nZ ~= 0 and zoneData[nZ] ~= nil) then |
||
145 | zoneData = zoneData[nZ]; |
||
146 | xPos = xPos - zoneData.xOffset; |
||
147 | yPos = yPos - zoneData.yOffset; |
||
148 | end |
||
149 | elseif (C and nC) and (WorldMapSize[C].parentContinent == WorldMapSize[nC].parentContinent) then |
||
150 | -- different continents, same world |
||
151 | zoneData = WorldMapSize[C]; |
||
152 | local parentContinent = zoneData.parentContinent; |
||
153 | xPos, yPos = getContPosition(zoneData, Z, xPos, yPos); |
||
154 | if ( C ~= parentContinent ) then |
||
155 | -- translate up to world map if we aren't there already |
||
156 | xPos = xPos + zoneData.xOffset; |
||
157 | yPos = yPos + zoneData.yOffset; |
||
158 | zoneData = WorldMapSize[parentContinent]; |
||
159 | end |
||
160 | if ( nC ~= parentContinent ) then |
||
161 | --translate down to the new continent |
||
162 | zoneData = WorldMapSize[nC]; |
||
163 | xPos = xPos - zoneData.xOffset; |
||
164 | yPos = yPos - zoneData.yOffset; |
||
165 | if ( nZ ~= 0 and zoneData[nZ] ~= nil) then |
||
166 | zoneData = zoneData[nZ]; |
||
167 | xPos = xPos - zoneData.xOffset; |
||
168 | yPos = yPos - zoneData.yOffset; |
||
169 | end |
||
170 | end |
||
171 | else |
||
172 | return; |
||
173 | end |
||
174 | return (xPos / zoneData.width), (yPos / zoneData.height); |
||
175 | end |
||
176 | |||
177 | Astrolabe_LastX = 0; |
||
178 | Astrolabe_LastY = 0; |
||
179 | Astrolabe_LastZ = 0; |
||
180 | Astrolabe_LastC = 0; |
||
181 | function Astrolabe:GetCurrentPlayerPosition() |
||
182 | local x, y = GetPlayerMapPosition("player") |
||
183 | if (x <= 0 and y <= 0) then |
||
184 | if not WorldMapFrame:IsVisible() then |
||
185 | SetMapToCurrentZone() |
||
186 | x, y = GetPlayerMapPosition("player") |
||
187 | if (x <= 0 and y <= 0) then |
||
188 | SetMapZoom(GetCurrentMapContinent()) |
||
189 | x, y = GetPlayerMapPosition("player") |
||
190 | if (x <= 0 and y <= 0) then |
||
191 | return |
||
192 | end |
||
193 | end |
||
194 | else |
||
195 | return Astrolabe_LastC, Astrolabe_LastZ, Astrolabe_LastX, Astrolabe_LastY |
||
196 | end |
||
197 | end |
||
198 | local C, Z = GetCurrentMapContinent(), GetCurrentMapZone() |
||
199 | local playerCont, playerZone = C, Z |
||
200 | if (playerZone == 0) then |
||
201 | playerZone = Astrolabe_LastZ |
||
202 | end |
||
203 | if (playerCont == 0) then |
||
204 | playerCont = Astrolabe_LastC |
||
205 | end |
||
206 | if (not WorldMapSize[playerCont]) then |
||
207 | playerCont, playerZone = 0, 0 |
||
208 | end |
||
209 | if (playerCont > 0 and not WorldMapSize[playerCont][playerZone]) then |
||
210 | playerZone = 0 |
||
211 | end |
||
212 | local nX, nY = self:TranslateWorldMapPosition(C, Z, x, y, playerCont, playerZone) |
||
213 | Astrolabe_LastX = nX |
||
214 | Astrolabe_LastY = nY |
||
215 | Astrolabe_LastC = playerCont |
||
216 | Astrolabe_LastZ = playerZone |
||
217 | return Astrolabe_LastC, Astrolabe_LastZ, Astrolabe_LastX, Astrolabe_LastY; |
||
218 | end |
||
219 | -------------------------------------------------------------------------------------------------------------- |
||
220 | -- Working Table Cache System |
||
221 | -------------------------------------------------------------------------------------------------------------- |
||
222 | local tableCache = {}; |
||
223 | tableCache["__mode"] = "v"; |
||
224 | setmetatable(tableCache, tableCache); |
||
225 | local function GetWorkingTable( icon ) |
||
226 | if ( tableCache[icon] ) then |
||
227 | return tableCache[icon]; |
||
228 | else |
||
229 | local T = {}; |
||
230 | tableCache[icon] = T; |
||
231 | return T; |
||
232 | end |
||
233 | end |
||
234 | -------------------------------------------------------------------------------------------------------------- |
||
235 | -- Minimap Icon Placement |
||
236 | -------------------------------------------------------------------------------------------------------------- |
||
237 | function Astrolabe:PlaceIconOnMinimap( icon, continent, zone, xPos, yPos ) |
||
238 | -- check argument types |
||
239 | self:argCheck(icon, 2, "table"); |
||
240 | self:assert(icon.SetPoint and icon.ClearAllPoints, "Usage Message"); |
||
241 | self:argCheck(continent, 3, "number"); |
||
242 | self:argCheck(zone, 4, "number", "nil"); |
||
243 | self:argCheck(xPos, 5, "number"); |
||
244 | self:argCheck(yPos, 6, "number"); |
||
245 | local lastPosition = self.LastPlayerPosition; |
||
246 | local lC, lZ, lx, ly = lastPosition[1], lastPosition[2], lastPosition[3], lastPosition[4]; |
||
247 | if (not lC) or (not lZ) or (not lx) or (not ly) then |
||
248 | lastPosition[1], lastPosition[2], lastPosition[3], lastPosition[4] = nil, nil, nil, nil; |
||
249 | lastPosition[1], lastPosition[2], lastPosition[3], lastPosition[4] = Astrolabe:GetCurrentPlayerPosition(); |
||
250 | lC, lZ, lx, ly = lastPosition[1], lastPosition[2], lastPosition[3], lastPosition[4]; |
||
251 | end |
||
252 | local dist, xDist, yDist = self:ComputeDistance(lC, lZ, lx, ly, continent, zone, xPos, yPos); |
||
253 | if not ( dist ) then |
||
254 | --icon's position has no meaningful position relative to the player's current location |
||
255 | return -1; |
||
256 | end |
||
257 | local iconData = self.MinimapIcons[icon]; |
||
258 | if not ( iconData ) then |
||
259 | iconData = GetWorkingTable(icon); |
||
260 | self.MinimapIcons[icon] = iconData; |
||
261 | end |
||
262 | iconData.continent = continent; |
||
263 | iconData.zone = zone; |
||
264 | iconData.xPos = xPos; |
||
265 | iconData.yPos = yPos; |
||
266 | iconData.dist = dist; |
||
267 | iconData.xDist = xDist; |
||
268 | iconData.yDist = yDist; |
||
269 | --show the new icon and force a placement update on the next screen draw |
||
270 | icon:Show() |
||
271 | self.ForceNextUpdate = true |
||
272 | self.UpdateTimer = self.MinimapUpdateTime |
||
273 | self:UpdateMinimapIconPositions(); |
||
274 | return 0; |
||
275 | end |
||
276 | |||
277 | function Astrolabe:RemoveIconFromMinimap( icon ) |
||
278 | if not ( self.MinimapIcons[icon] ) then |
||
279 | return 1; |
||
280 | end |
||
281 | self.MinimapIcons[icon] = nil; |
||
282 | icon:Hide(); |
||
283 | return 0; |
||
284 | end |
||
285 | |||
286 | function Astrolabe:RemoveAllMinimapIcons() |
||
287 | local minimapIcons = self.MinimapIcons |
||
288 | for k, v in pairs(minimapIcons) do |
||
289 | minimapIcons[k] = nil; |
||
290 | k:Hide(); |
||
291 | end |
||
292 | end |
||
293 | |||
294 | function Astrolabe:isMinimapInCity() |
||
295 | local tempzoom = 0; |
||
296 | self.minimapOutside = true; |
||
297 | if (GetCVar("minimapZoom") == GetCVar("minimapInsideZoom")) then |
||
298 | if (GetCVar("minimapInsideZoom")+0 >= 3) then |
||
299 | Minimap:SetZoom(Minimap:GetZoom() - 1); |
||
300 | tempzoom = 1; |
||
301 | else |
||
302 | Minimap:SetZoom(Minimap:GetZoom() + 1); |
||
303 | tempzoom = -1; |
||
304 | end |
||
305 | end |
||
306 | if (GetCVar("minimapInsideZoom")+0 == Minimap:GetZoom()) then self.minimapOutside = false; end |
||
307 | Minimap:SetZoom(Minimap:GetZoom() + tempzoom); |
||
308 | end |
||
309 | |||
310 | local function placeIconOnMinimap( minimap, minimapZoom, mapWidth, mapHeight, icon, dist, xDist, yDist ) |
||
311 | local mapDiameter; |
||
312 | if ( Astrolabe.minimapOutside ) then |
||
313 | mapDiameter = MinimapSize.outdoor[minimapZoom]; |
||
314 | else |
||
315 | mapDiameter = MinimapSize.indoor[minimapZoom]; |
||
316 | end |
||
317 | local mapRadius = mapDiameter / 2; |
||
318 | local xScale = mapDiameter / mapWidth; |
||
319 | local yScale = mapDiameter / mapHeight; |
||
320 | local iconDiameter = ((icon:GetWidth() / 2) -3) * xScale; -- LaYt +3 |
||
321 | icon:ClearAllPoints(); |
||
322 | local signx,signy =1,1; |
||
323 | -- Adding square map support by LaYt |
||
324 | if (Squeenix or (simpleMinimap_Skins and simpleMinimap_Skins:GetShape() == "square") or (pfUI and pfUI.minimap)) then |
||
325 | if (xDist<0) then signx=-1; end |
||
326 | if (yDist<0) then signy=-1; end |
||
327 | if (math.abs(xDist) > (mapWidth/2*xScale) or math.abs(yDist) > (mapHeight/2*yScale)) then |
||
328 | local xRatio,yRatio = 1,1; |
||
329 | if ( yDist ~= 0 ) then |
||
330 | xRatio = math.min( math.abs(xDist) / math.abs(yDist), 1 ); |
||
331 | end |
||
332 | if ( xDist ~= 0 ) then |
||
333 | yRatio = math.min( math.abs(yDist) / math.abs(xDist) , 1 ); |
||
334 | end |
||
335 | xDist = (mapWidth/2*xScale - iconDiameter/2)*signx*xRatio; |
||
336 | yDist = (mapHeight/2*yScale - iconDiameter/2)*signy*yRatio; |
||
337 | end |
||
338 | elseif ( (dist + iconDiameter) > mapRadius ) then |
||
339 | -- position along the outside of the Minimap |
||
340 | local factor = (mapRadius - iconDiameter) / dist; |
||
341 | xDist = xDist * factor; |
||
342 | yDist = yDist * factor; |
||
343 | end |
||
344 | icon:SetPoint("CENTER", minimap, "CENTER", xDist/xScale, -yDist/yScale); |
||
345 | end |
||
346 | |||
347 | local lastZoom; |
||
348 | function Astrolabe:UpdateMinimapIconPositions() |
||
349 | local C, Z, x, y = self:GetCurrentPlayerPosition(); |
||
350 | if not ( C and Z and x and y ) then |
||
351 | self.processingFrame:Hide(); |
||
352 | end |
||
353 | local Minimap = Minimap; |
||
354 | local lastPosition = self.LastPlayerPosition; |
||
355 | local lC, lZ, lx, ly = lastPosition[1], lastPosition[2], lastPosition[3], lastPosition[4]; |
||
356 | local currentZoom = Minimap:GetZoom(); |
||
357 | local zoomChanged = lastZoom ~= Minimap:GetZoom() |
||
358 | lastZoom = currentZoom; |
||
359 | if zoomChanged then |
||
360 | Astrolabe.MinimapUpdateTime = (6 - Minimap:GetZoom()) * 0.05 |
||
361 | end |
||
362 | if ( (lC == C and lZ == Z and lx == x and ly == y)) then |
||
363 | -- player has not moved since the last update |
||
364 | if (zoomChanged or self.ForceNextUpdate ) then |
||
365 | local mapWidth = Minimap:GetWidth(); |
||
366 | local mapHeight = Minimap:GetHeight(); |
||
367 | for icon, data in pairs(self.MinimapIcons) do |
||
368 | placeIconOnMinimap(Minimap, currentZoom, mapWidth, mapHeight, icon, data.dist, data.xDist, data.yDist); |
||
369 | end |
||
370 | self.ForceNextUpdate = false; |
||
371 | end |
||
372 | else |
||
373 | local dist, xDelta, yDelta = self:ComputeDistance(lC, lZ, lx, ly, C, Z, x, y); |
||
374 | if not dist or not xDelta or not yDelta then return; end |
||
375 | local mapWidth = Minimap:GetWidth(); |
||
376 | local mapHeight = Minimap:GetHeight(); |
||
377 | for icon, data in pairs(self.MinimapIcons) do |
||
378 | local xDist = data.xDist - xDelta; |
||
379 | local yDist = data.yDist - yDelta; |
||
380 | local dist = sqrt(xDist*xDist + yDist*yDist); |
||
381 | placeIconOnMinimap(Minimap, currentZoom, mapWidth, mapHeight, icon, dist, xDist, yDist); |
||
382 | data.dist = dist; |
||
383 | data.xDist = xDist; |
||
384 | data.yDist = yDist; |
||
385 | end |
||
386 | lastPosition[1] = C; |
||
387 | lastPosition[2] = Z; |
||
388 | lastPosition[3] = x; |
||
389 | lastPosition[4] = y; |
||
390 | end |
||
391 | end |
||
392 | |||
393 | function Astrolabe:CalculateMinimapIconPositions() |
||
394 | local C, Z, x, y = self:GetCurrentPlayerPosition(); |
||
395 | if not ( C and Z and x and y ) then |
||
396 | self.processingFrame:Hide(); |
||
397 | end |
||
398 | local currentZoom = Minimap:GetZoom(); |
||
399 | lastZoom = currentZoom; |
||
400 | local Minimap = Minimap; |
||
401 | local mapWidth = Minimap:GetWidth(); |
||
402 | local mapHeight = Minimap:GetHeight(); |
||
403 | for icon, data in pairs(self.MinimapIcons) do |
||
404 | local dist, xDist, yDist = self:ComputeDistance(C, Z, x, y, data.continent, data.zone, data.xPos, data.yPos); |
||
405 | placeIconOnMinimap(Minimap, currentZoom, mapWidth, mapHeight, icon, dist, xDist, yDist); |
||
406 | data.dist = dist; |
||
407 | data.xDist = xDist; |
||
408 | data.yDist = yDist; |
||
409 | end |
||
410 | local lastPosition = self.LastPlayerPosition; |
||
411 | lastPosition[1] = C; |
||
412 | lastPosition[2] = Z; |
||
413 | lastPosition[3] = x; |
||
414 | lastPosition[4] = y; |
||
415 | end |
||
416 | |||
417 | function Astrolabe:GetDistanceToIcon( icon ) |
||
418 | local data = Astrolabe.MinimapIcons[icon]; |
||
419 | if ( data ) then |
||
420 | return data.dist, data.xDist, data.yDist; |
||
421 | end |
||
422 | end |
||
423 | |||
424 | function Astrolabe:GetDirectionToIcon( icon ) |
||
425 | local data = Astrolabe.MinimapIcons[icon]; |
||
426 | if ( data ) then |
||
427 | local dir = atan2(data.xDist, -(data.yDist)) |
||
428 | if ( dir > 0 ) then |
||
429 | return twoPi - dir; |
||
430 | else |
||
431 | return -dir; |
||
432 | end |
||
433 | end |
||
434 | end |
||
435 | -------------------------------------------------------------------------------------------------------------- |
||
436 | -- World Map Icon Placement |
||
437 | -------------------------------------------------------------------------------------------------------------- |
||
438 | function Astrolabe:PlaceIconOnWorldMap( worldMapFrame, icon, continent, zone, xPos, yPos ) |
||
439 | -- check argument types |
||
440 | self:argCheck(worldMapFrame, 2, "table"); |
||
441 | self:assert(worldMapFrame.GetWidth and worldMapFrame.GetHeight, "Usage Message"); |
||
442 | self:argCheck(icon, 3, "table"); |
||
443 | self:assert(icon.SetPoint and icon.ClearAllPoints, "Usage Message"); |
||
444 | self:argCheck(continent, 4, "number"); |
||
445 | self:argCheck(zone, 5, "number", "nil"); |
||
446 | self:argCheck(xPos, 6, "number"); |
||
447 | self:argCheck(yPos, 7, "number"); |
||
448 | local C, Z = GetCurrentMapContinent(), GetCurrentMapZone(); |
||
449 | local nX, nY = self:TranslateWorldMapPosition(continent, zone, xPos, yPos, C, Z); |
||
450 | if ( nX and nY and (0 < nX and nX <= 1) and (0 < nY and nY <= 1) ) then |
||
451 | icon:ClearAllPoints(); |
||
452 | icon:SetPoint("CENTER", worldMapFrame, "TOPLEFT", nX * worldMapFrame:GetWidth(), -nY * worldMapFrame:GetHeight()); |
||
453 | end |
||
454 | return nX, nY; |
||
455 | end |
||
456 | -------------------------------------------------------------------------------------------------------------- |
||
457 | -- Handler Scripts |
||
458 | -------------------------------------------------------------------------------------------------------------- |
||
459 | function Astrolabe:OnEvent( frame, event ) |
||
460 | if ( event == "MINIMAP_UPDATE_ZOOM" ) then |
||
461 | Astrolabe:isMinimapInCity() |
||
462 | -- re-calculate all Minimap Icon positions |
||
463 | if ( frame:IsVisible() ) then |
||
464 | self:CalculateMinimapIconPositions(); |
||
465 | end |
||
466 | elseif ( event == "PLAYER_LEAVING_WORLD" ) then |
||
467 | frame:Hide(); |
||
468 | self:RemoveAllMinimapIcons(); --dump all minimap icons |
||
469 | elseif ( event == "PLAYER_ENTERING_WORLD" or event == "ZONE_CHANGED_NEW_AREA" ) then |
||
470 | Astrolabe:isMinimapInCity() |
||
471 | frame:Show(); |
||
472 | end |
||
473 | end |
||
474 | |||
475 | function Astrolabe:OnUpdate( frame, elapsed ) |
||
476 | local updateTimer = self.UpdateTimer - elapsed; |
||
477 | if ( updateTimer > 0 ) then |
||
478 | self.UpdateTimer = updateTimer; |
||
479 | return; |
||
480 | end |
||
481 | self.UpdateTimer = self.MinimapUpdateTime; |
||
482 | self:UpdateMinimapIconPositions(); |
||
483 | end |
||
484 | |||
485 | function Astrolabe:OnShow( frame ) |
||
486 | self:CalculateMinimapIconPositions(); |
||
487 | end |
||
488 | -------------------------------------------------------------------------------------------------------------- |
||
489 | -- Library Registration |
||
490 | -------------------------------------------------------------------------------------------------------------- |
||
491 | local function activate( self, oldLib, oldDeactivate ) |
||
492 | Astrolabe = self; |
||
493 | local frame = self.processingFrame; |
||
494 | if not ( frame ) then |
||
495 | frame = CreateFrame("Frame"); |
||
496 | self.processingFrame = frame; |
||
497 | end |
||
498 | frame:SetParent("Minimap"); |
||
499 | frame:Hide(); |
||
500 | frame:UnregisterAllEvents(); |
||
501 | frame:RegisterEvent("MINIMAP_UPDATE_ZOOM"); |
||
502 | frame:RegisterEvent("PLAYER_LEAVING_WORLD"); |
||
503 | frame:RegisterEvent("PLAYER_ENTERING_WORLD"); |
||
504 | frame:RegisterEvent("ZONE_CHANGED_NEW_AREA"); |
||
505 | frame:SetScript("OnEvent", function() |
||
506 | self:OnEvent(this, event); |
||
507 | end |
||
508 | ); |
||
509 | frame:SetScript("OnUpdate", |
||
510 | function( frame, elapsed ) |
||
511 | self:OnUpdate(frame, 1/GetFramerate()); |
||
512 | end |
||
513 | ); |
||
514 | frame:SetScript("OnShow", |
||
515 | function( frame ) |
||
516 | self:OnShow(frame); |
||
517 | end |
||
518 | ); |
||
519 | if not ( self.ContinentList ) then |
||
520 | self.ContinentList = { GetMapContinents() }; |
||
521 | for C in pairs(self.ContinentList) do |
||
522 | local zones = { GetMapZones(C) }; |
||
523 | self.ContinentList[C] = zones; |
||
524 | for Z, N in ipairs(zones) do |
||
525 | SetMapZoom(C, Z); |
||
526 | zones[Z] = {mapFile = GetMapInfo(), mapName = N} |
||
527 | end |
||
528 | end |
||
529 | end |
||
530 | initSizes() |
||
531 | frame:Show(); |
||
532 | end |
||
533 | -------------------------------------------------------------------------------------------------------------- |
||
534 | -- Data |
||
535 | -------------------------------------------------------------------------------------------------------------- |
||
536 | -- diameter of the Minimap in game yards at |
||
537 | -- the various possible zoom levels |
||
538 | MinimapSize = { |
||
539 | indoor = { |
||
540 | [0] = 300, -- scale |
||
541 | [1] = 240, -- 1.25 |
||
542 | [2] = 180, -- 5/3 |
||
543 | [3] = 120, -- 2.5 |
||
544 | [4] = 80, -- 3.75 |
||
545 | [5] = 50, -- 6 |
||
546 | }, |
||
547 | outdoor = { |
||
548 | [0] = 466 + 2/3, -- scale |
||
549 | [1] = 400, -- 7/6 |
||
550 | [2] = 333 + 1/3, -- 1.4 |
||
551 | [3] = 266 + 2/6, -- 1.75 |
||
552 | [4] = 200, -- 7/3 |
||
553 | [5] = 133 + 1/3, -- 3.5 |
||
554 | }, |
||
555 | } |
||
556 | -- distances across and offsets of the world maps |
||
557 | -- in game yards |
||
558 | -- from classic client data, except for values commented on |
||
559 | local initDone = false |
||
560 | function initSizes() |
||
561 | if initDone then return end |
||
562 | initDone = true |
||
563 | WorldMapSize = { |
||
564 | -- World Map of Azeroth |
||
565 | [0] = { |
||
566 | parentContinent = 0, |
||
567 | height = 29687.90575403711, -- as in Questie |
||
568 | width = 44531.82907938571, -- as in Questie |
||
569 | }, |
||
570 | -- Kalimdor |
||
571 | [1] = { |
||
572 | parentContinent = 0, |
||
573 | height = 24533.2001953125, |
||
574 | width = 36799.810546875, |
||
575 | xOffset = -8310.0, -- as in Questie |
||
576 | yOffset = 1815.0, -- as in Questie |
||
577 | zoneData = { |
||
578 | Ashenvale = { |
||
579 | height = 3843.749877929687, |
||
580 | width = 5766.66638183594, |
||
581 | xOffset = 15366.59973144531, |
||
582 | yOffset = 8126.98388671875, |
||
583 | }, |
||
584 | Aszhara = { |
||
585 | height = 3381.2498779296902, |
||
586 | width = 5070.8327636718695, |
||
587 | xOffset = 20343.68286132813, |
||
588 | yOffset = 7458.23388671875, |
||
589 | }, |
||
590 | Barrens = { |
||
591 | height = 6756.24987792969, |
||
592 | width = 10133.3330078125, |
||
593 | xOffset = 14443.68310546875, |
||
594 | yOffset = 11187.40051269531, |
||
595 | }, |
||
596 | Darkshore = { |
||
597 | height = 4366.66650390625, |
||
598 | width = 6549.9997558593805, |
||
599 | xOffset = 14124.93310546875, |
||
600 | yOffset = 4466.5673828125, |
||
601 | }, |
||
602 | Darnassis = { |
||
603 | height = 705.7294921875, |
||
604 | width = 1058.33325195312, |
||
605 | xOffset = 14128.23681640625, |
||
606 | yOffset = 2561.583984375, |
||
607 | }, |
||
608 | Desolace = { |
||
609 | height = 2997.916564941411, |
||
610 | width = 4495.8330078125, |
||
611 | xOffset = 12833.2666015625, |
||
612 | yOffset = 12347.817077636719, |
||
613 | }, |
||
614 | Durotar = { |
||
615 | height = 3524.9998779296902, |
||
616 | width = 5287.49963378906, |
||
617 | xOffset = 19029.09948730469, |
||
618 | yOffset = 10991.56713867187, |
||
619 | }, |
||
620 | Dustwallow = { |
||
621 | height = 3499.99975585937, |
||
622 | width = 5250.000061035156, |
||
623 | xOffset = 18041.599548339844, |
||
624 | yOffset = 14833.23364257813, |
||
625 | }, |
||
626 | Felwood = { |
||
627 | height = 3833.33325195312, |
||
628 | width = 5749.99963378906, |
||
629 | xOffset = 15424.93298339844, |
||
630 | yOffset = 5666.5673828125, |
||
631 | }, |
||
632 | Feralas = { |
||
633 | height = 4633.3330078125, |
||
634 | width = 6949.9997558593805, |
||
635 | xOffset = 11624.93310546875, |
||
636 | yOffset = 15166.56689453125, |
||
637 | }, |
||
638 | Moonglade = { |
||
639 | height = 1539.5830078125, |
||
640 | width = 2308.33325195313, |
||
641 | xOffset = 18447.849609375, |
||
642 | yOffset = 4308.234375, |
||
643 | }, |
||
644 | Mulgore = { |
||
645 | height = 3424.999847412109, |
||
646 | width = 5137.49987792969, |
||
647 | xOffset = 15018.68298339844, |
||
648 | yOffset = 13072.81704711914, |
||
649 | }, |
||
650 | Ogrimmar = { |
||
651 | height = 935.41662597657, |
||
652 | width = 1402.6044921875, |
||
653 | xOffset = 20747.20068359375, |
||
654 | yOffset = 10526.02319335937, |
||
655 | }, |
||
656 | Silithus = { |
||
657 | height = 2322.916015625, |
||
658 | width = 3483.333984375, |
||
659 | xOffset = 14529.099609375, |
||
660 | yOffset = 18758.234375, |
||
661 | }, |
||
662 | StonetalonMountains = { |
||
663 | height = 3256.2498168945312, |
||
664 | width = 4883.33312988282, |
||
665 | xOffset = 13820.76635742187, |
||
666 | yOffset = 9883.23388671875, |
||
667 | }, |
||
668 | Tanaris = { |
||
669 | height = 4600.0, |
||
670 | width = 6899.999526977539, |
||
671 | xOffset = 17285.34959411621, |
||
672 | yOffset = 18674.900390625, |
||
673 | }, |
||
674 | Teldrassil = { |
||
675 | height = 3393.75, |
||
676 | width = 5091.66650390626, |
||
677 | xOffset = 13252.01635742187, |
||
678 | yOffset = 968.650390625, |
||
679 | }, |
||
680 | ThousandNeedles = { |
||
681 | height = 2933.3330078125, |
||
682 | width = 4399.999694824219, |
||
683 | xOffset = 17499.93292236328, |
||
684 | yOffset = 16766.56689453125, |
||
685 | }, |
||
686 | ThunderBluff = { |
||
687 | height = 695.833312988286, |
||
688 | width = 1043.749938964844, |
||
689 | xOffset = 16549.932983398438, |
||
690 | yOffset = 13649.900329589844, |
||
691 | }, |
||
692 | UngoroCrater = { |
||
693 | height = 2466.66650390625, |
||
694 | width = 3699.9998168945312, |
||
695 | xOffset = 16533.26629638672, |
||
696 | yOffset = 18766.56689453125, |
||
697 | }, |
||
698 | Winterspring = { |
||
699 | height = 4733.3332519531195, |
||
700 | width = 7099.999847412109, |
||
701 | xOffset = 17383.26626586914, |
||
702 | yOffset = 4266.5673828125, |
||
703 | }, |
||
704 | }, |
||
705 | }, |
||
706 | -- Eastern Kingdoms |
||
707 | [2] = { |
||
708 | parentContinent = 0, |
||
709 | height = 23466.60009765625, |
||
710 | width = 35199.900390625, |
||
711 | xOffset = 16625.0, -- guessed |
||
712 | yOffset = 2470.0, -- guessed |
||
713 | zoneData = { |
||
714 | Alterac = { |
||
715 | height = 1866.666656494141, |
||
716 | width = 2799.999938964841, |
||
717 | xOffset = 15216.666687011719, |
||
718 | yOffset = 5966.60009765625, |
||
719 | }, |
||
720 | Arathi = { |
||
721 | height = 2399.99992370606, |
||
722 | width = 3599.999877929687, |
||
723 | xOffset = 16866.666625976562, |
||
724 | yOffset = 7599.93342590332, |
||
725 | }, |
||
726 | Badlands = { |
||
727 | height = 1658.33349609375, |
||
728 | width = 2487.5, |
||
729 | xOffset = 18079.16650390625, |
||
730 | yOffset = 13356.18310546875, |
||
731 | }, |
||
732 | BlastedLands = { |
||
733 | height = 2233.333984375, |
||
734 | width = 3349.9998779296902, |
||
735 | xOffset = 17241.66662597656, |
||
736 | yOffset = 18033.26611328125, |
||
737 | }, |
||
738 | BurningSteppes = { |
||
739 | height = 1952.08349609375, |
||
740 | width = 2929.166595458989, |
||
741 | xOffset = 16266.66665649414, |
||
742 | yOffset = 14497.849609375, |
||
743 | }, |
||
744 | DeadwindPass = { |
||
745 | height = 1666.6669921875, |
||
746 | width = 2499.999938964849, |
||
747 | xOffset = 16833.33331298828, |
||
748 | yOffset = 17333.26611328125, |
||
749 | }, |
||
750 | DunMorogh = { |
||
751 | height = 3283.33325195312, |
||
752 | width = 4924.9997558593805, |
||
753 | xOffset = 14197.91674804687, |
||
754 | yOffset = 11343.68334960938, |
||
755 | }, |
||
756 | Duskwood = { |
||
757 | height = 1800.0, |
||
758 | width = 2699.999938964841, |
||
759 | xOffset = 15166.666687011719, |
||
760 | yOffset = 17183.26611328125, |
||
761 | }, |
||
762 | EasternPlaguelands = { |
||
763 | height = 2581.24975585938, |
||
764 | width = 3870.83349609375, |
||
765 | xOffset = 18185.41650390625, |
||
766 | yOffset = 3666.60034179687, |
||
767 | }, |
||
768 | Elwynn = { |
||
769 | height = 2314.5830078125, |
||
770 | width = 3470.83325195312, |
||
771 | xOffset = 14464.58337402344, |
||
772 | yOffset = 15406.18310546875, |
||
773 | }, |
||
774 | Hilsbrad = { |
||
775 | height = 2133.33325195313, |
||
776 | width = 3199.9998779296902, |
||
777 | xOffset = 14933.33337402344, |
||
778 | yOffset = 7066.60009765625, |
||
779 | }, |
||
780 | Hinterlands = { |
||
781 | height = 2566.6666259765598, |
||
782 | width = 3850.0, |
||
783 | xOffset = 17575.0, |
||
784 | yOffset = 5999.93347167969, |
||
785 | }, |
||
786 | Ironforge = { |
||
787 | height = 527.6044921875, |
||
788 | width = 790.625061035154, |
||
789 | xOffset = 16713.591369628906, |
||
790 | yOffset = 12035.84130859375, |
||
791 | }, |
||
792 | LochModan = { |
||
793 | height = 1839.5830078125, |
||
794 | width = 2758.3331298828098, |
||
795 | xOffset = 17993.74987792969, |
||
796 | yOffset = 11954.10009765625, |
||
797 | }, |
||
798 | Redridge = { |
||
799 | height = 1447.916015625, |
||
800 | width = 2170.83325195312, |
||
801 | xOffset = 17570.83325195313, |
||
802 | yOffset = 16041.60009765625, |
||
803 | }, |
||
804 | SearingGorge = { |
||
805 | height = 1487.49951171875, |
||
806 | width = 2231.249847412109, |
||
807 | xOffset = 16322.91665649414, |
||
808 | yOffset = 13566.60009765625, |
||
809 | }, |
||
810 | Silverpine = { |
||
811 | height = 2799.9998779296902, |
||
812 | width = 4199.9997558593805, |
||
813 | xOffset = 12550.00024414062, |
||
814 | yOffset = 5799.93347167969, |
||
815 | }, |
||
816 | Stormwind = { |
||
817 | height = 896.3544921875, |
||
818 | width = 1344.2708053588917, |
||
819 | xOffset = 14619.02856445312, |
||
820 | yOffset = 15745.45068359375, |
||
821 | }, |
||
822 | Stranglethorn = { |
||
823 | height = 4254.166015625, |
||
824 | width = 6381.2497558593805, |
||
825 | xOffset = 13779.16674804687, |
||
826 | yOffset = 18635.35009765625, |
||
827 | }, |
||
828 | SwampOfSorrows = { |
||
829 | height = 1529.1669921875, |
||
830 | width = 2293.75, |
||
831 | xOffset = 18222.91650390625, |
||
832 | yOffset = 17087.43310546875, |
||
833 | }, |
||
834 | Tirisfal = { |
||
835 | height = 3012.499816894536, |
||
836 | width = 4518.74987792969, |
||
837 | xOffset = 12966.66674804687, |
||
838 | yOffset = 3629.10034179687, |
||
839 | }, |
||
840 | Undercity = { |
||
841 | height = 640.10412597656, |
||
842 | width = 959.3750305175781, |
||
843 | xOffset = 15126.807373046875, |
||
844 | yOffset = 5588.65478515625, |
||
845 | }, |
||
846 | WesternPlaguelands = { |
||
847 | height = 2866.666534423828, |
||
848 | width = 4299.999908447271, |
||
849 | xOffset = 15583.33334350586, |
||
850 | yOffset = 4099.93359375, |
||
851 | }, |
||
852 | Westfall = { |
||
853 | height = 2333.3330078125, |
||
854 | width = 3499.9998168945312, |
||
855 | xOffset = 12983.33349609375, |
||
856 | yOffset = 16866.60009765625, |
||
857 | }, |
||
858 | Wetlands = { |
||
859 | height = 2756.25, |
||
860 | width = 4135.416687011719, |
||
861 | xOffset = 16389.58331298828, |
||
862 | yOffset = 9614.5166015625, |
||
863 | }, |
||
864 | }, |
||
865 | }, |
||
866 | } |
||
867 | local zeroData = { xOffset = 0, height = 0, yOffset = 0, width = 0 }; |
||
868 | for continent, zones in pairs(Astrolabe.ContinentList) do |
||
869 | local mapData = WorldMapSize[continent]; |
||
870 | for index, zData in pairs(zones) do |
||
871 | if not ( mapData.zoneData[zData.mapFile] ) then |
||
872 | --WE HAVE A PROBLEM!!! |
||
873 | -- Disabled because TBC zones were removed |
||
874 | --ChatFrame1:AddMessage("Astrolabe is missing data for "..select(index, GetMapZones(continent)).."."); |
||
875 | mapData.zoneData[zData.mapFile] = zeroData; |
||
876 | end |
||
877 | mapData[index] = mapData.zoneData[zData.mapFile]; |
||
878 | mapData[index].mapName = zData.mapName |
||
879 | mapData.zoneData[zData.mapFile] = nil; |
||
880 | end |
||
881 | end |
||
882 | end |
||
883 | |||
884 | AceLibrary:Register(Astrolabe, LIBRARY_VERSION_MAJOR, LIBRARY_VERSION_MINOR, activate) |