-
Notifications
You must be signed in to change notification settings - Fork 16
/
Display.lua
839 lines (757 loc) · 22.7 KB
/
Display.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
local GatherMate = LibStub("AceAddon-3.0"):GetAddon("GatherMate2")
local Display = GatherMate:NewModule("Display","AceEvent-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("GatherMate2")
-- Current minimap pin set
local minimapPins, minimapPinCount = {}, 0
-- Current worldmap pin set
local worldmapPins = {}
-- table for UIDropdownMenu info
local info = {}
-- cache of pins
local pinCache = {}
-- last x,y of the player.
-- total number of pins we have created
local lastXY, lastYY, pinCount = 0, 0, 0
-- reference to the pin generating the UIDropDown
local pinClickedOn
-- our current zone
local zone = -1
-- cache of table insert functions
local next, pairs = next, pairs
-- minimap rotation
local rotateMinimap = GetCVar("rotateMinimap") == "1"
-- shape of the minimap
local minimapShape
-- diameter of the minimap
local mapRadius, minimapWidth, minimapHeight, minimapScale, lastFacing, lastZoom
local minimapStrata, minimapFrameLevel
-- math function cache
local math_sin, math_cos, max = math.sin, math.cos, math.max
local sin, cos
-- API function cache
local GetProfessionInfo = GetProfessionInfo
local format = string.format
local trackingCircle, nodeTextures
local db
local Minimap = Minimap
local nodeRange = 2
local forceNextUpdate
local trackShow = {}
local profession_to_skill = {}
local have_prof_skill = {}
local active_tracking = {}
local tracking_spells = {}
local continentZoneList = {
[12] = true, -- Kalimdor
[13] = true, -- Azeroth
[101] = true, -- Outlands
[113] = true, -- Northrend
[424] = true, -- Pandaria
[572] = true, -- Draenor
[619] = true, -- Broken Isles
[875] = true, -- Zandalar
[876] = true, -- Kul Tiras
[1550] = true, -- Shadowlands
[1978] = true, -- Dragon Isles
[2274] = true, -- Khaz Algar
}
--[[
recycle a pin
]]
local function recyclePin(pin)
pin:Hide()
pin.coords = nil
pin.nodeType = nil
pin.zone = nil
pin.title = nil
pin.worldmap = false
pin.nodeID = 0
pin.keep = nil
pinCache[pin] = true
end
--[[
clear a set of pins
]]
local function clearpins(t)
for k,v in pairs(t) do
recyclePin(v)
t[k] = nil
end
end
--[[
Delete a pin from the DB, then call update to refresh both minimap and world map
]]
local function deletePin(button,pin)
GatherMate:RemoveNodeByID(pin.zone, pin.nodeType, pin.coords)
Display:UpdateWorldMap(true)
Display:UpdateMiniMap(true)
end
--[[
Pin OnEnter
]]
local tooltip_template = "|c%02x%02x%02x%02x%s|r"
local mouseoveredPins = {}
local checkMoused = false
local function showPin(self)
if (self.title) then
local x, y = self:GetCenter()
local parentX, parentY = UIParent:GetCenter()
if ( x > parentX ) then
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
else
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
end
local t = db.trackColors
local dbtable
if not checkMoused then
local pinset
if self.worldmap then
pinset = worldmapPins
else
pinset = minimapPins
end
for id, pin in pairs(pinset) do --Cache mouseovered pins to improve tooltip perf
if pin.title and pin:IsMouseOver() then
dbtable = t[pin.nodeType]
mouseoveredPins[pin] = format(tooltip_template, dbtable.Alpha*255, dbtable.Red*255, dbtable.Green*255, dbtable.Blue*255, pin.title)
end
end
checkMoused = true
end
dbtable = t[self.nodeType]
local text = format(tooltip_template, dbtable.Alpha*255, dbtable.Red*255, dbtable.Green*255, dbtable.Blue*255, self.title)
for pin, pin_text in pairs(mouseoveredPins) do
if pin ~= self then
text = text .. "\n" .. pin_text
end
end
GameTooltip:SetText(text)
GameTooltip:Show()
end
end
--[[
Pin OnLeave
]]
local function hidePin(self)
GameTooltip:Hide()
wipe(mouseoveredPins)
checkMoused = false
end
--[[
Pin click handler
]]
local function pinClick(self, button)
if button == "RightButton" and self.worldmap then
pinClickedOn = self
ToggleDropDownMenu(1, nil, GatherMate2_GenericDropDownMenu, self, 0, 0)
elseif self.worldmap == false then
-- This "simulates" clickthru on the minimap to ping the minimap, by roughknight
if Minimap:GetObjectType() == "Minimap" then -- This is for SexyMap's HudMap, which reparents to a hud frame that isn't a minimap
local point, parent, relPoint, x, y = self:GetPoint()
Minimap:PingLocation(x, y)
end
end
end
--[[
Add pin location to TomTom waypoints
]]
local function addTomTomWaypoint(button,pin)
if TomTom then
local x, y = GatherMate:DecodeLoc(pin.coords)
TomTom:AddWaypoint(pin.zone, x, y, {
title = pin.title,
persistent = nil,
minimap = true,
world = true
})
end
end
--[[
Generate a drop down menu for a pin
]]
local function generatePinMenu(self,level)
if (not level) then return end
for k in pairs(info) do info[k] = nil end
if (level == 1) then
-- Create the title of the menu
info.isTitle = 1
info.text = L["GatherMate Pin Options"]
info.notCheckable = 1
UIDropDownMenu_AddButton(info, level)
-- Generate a menu item for each pin the mouse is on
info.disabled = nil
info.isTitle = nil
info.notCheckable = nil
for pin, pin_text in pairs(mouseoveredPins) do --Reuse here, not as significant since this is ran occasionally
info.text = L["Delete"] .. " :" ..pin.title
info.icon = nodeTextures[pin.nodeType][GatherMate:GetIDForNode(pin.nodeType, pin.title)]
info.func = deletePin
info.arg1 = pin
UIDropDownMenu_AddButton(info, level);
end
if TomTom then
info.text = L["Add this location to TomTom waypoints"]
info.icon = nil
info.func = addTomTomWaypoint
info.arg1 = pinClickedOn
UIDropDownMenu_AddButton(info, level)
end
-- Close menu item
info.text = CLOSE
info.icon = nil
info.func = function() CloseDropDownMenus() end
info.arg1 = nil
info.notCheckable = 1
UIDropDownMenu_AddButton(info, level);
end
end
--[[
Setup the dropdown menu
]]
local GatherMate2_GenericDropDownMenu = CreateFrame("Frame", "GatherMate2_GenericDropDownMenu")
GatherMate2_GenericDropDownMenu.displayMode = "MENU"
GatherMate2_GenericDropDownMenu.initialize = generatePinMenu
local last_update = 0
local listening = false
--[[
Enable the mod and add our event listeners and timers
]]
local fullInit = false
function Display:OnEnable()
db = GatherMate.db.profile
trackingCircle = self.trackingCircle
nodeTextures = GatherMate.nodeTextures
-- Recheck cvars after all addons are loaded.
rotateMinimap = GetCVar("rotateMinimap") == "1"
if not self.updateFrame then
GatherMate.Visible = {}
self.updateFrame = CreateFrame("Frame")
self.updateFrame:SetScript("OnUpdate", function(frame, elapsed)
last_update = last_update + elapsed
if last_update > 2 or forceNextUpdate then
Display:UpdateMiniMap(true)
last_update = 0
forceNextUpdate = false
else
Display:UpdateIconPositions()
end
end)
end
WorldMapFrame:AddDataProvider(Display.WorldMapDataProvider)
self:RegisterMapEvents()
self:RegisterEvent("SKILL_LINES_CHANGED")
self:RegisterEvent("MINIMAP_UPDATE_TRACKING")
self:RegisterEvent("PLAYER_ENTERING_WORLD","UpdateMaps")
GatherMate.HBD.RegisterCallback(self, "PlayerZoneChanged")
self:SKILL_LINES_CHANGED()
self:MINIMAP_UPDATE_TRACKING()
self:PlayerZoneChanged()
self:DigsitesChanged()
--self:UpdateMaps() -- already in DigsitesChanged()
fullInit = true
end
function Display:RegisterMapEvents()
self:RegisterEvent("MINIMAP_UPDATE_ZOOM", "MinimapZoom")
self:RegisterEvent("CVAR_UPDATE", "ChangedVars")
self:RegisterMessage("GatherMate2ConfigChanged","ConfigChanged")
self:RegisterMessage("GatherMate2NodeAdded", "ScheduleUpdate")
self:RegisterMessage("GatherMate2DataImport", "DataUpdate")
self:RegisterMessage("GatherMate2Cleanup", "DataUpdate")
--self:RegisterEvent("ARTIFACT_DIG_SITE_UPDATED","DigsitesChanged")
self.updateFrame:Show()
listening = true
end
function Display:UnregisterMapEvents()
self:UnregisterEvent("MINIMAP_UPDATE_ZOOM")
self:UnregisterEvent("CVAR_UPDATE")
--self:UnregisterEvent("ARTIFACT_DIG_SITE_UPDATED")
self:UnregisterMessage("GatherMate2ConfigChanged")
self:UnregisterMessage("GatherMate2NodeAdded")
self:UnregisterMessage("GatherMate2DataImport")
self:UnregisterMessage("GatherMate2Cleanup")
clearpins(worldmapPins)
clearpins(minimapPins)
self.updateFrame:Hide()
listening = false
end
-- Disable the mod
function Display:OnDisable()
self:UnregisterMapEvents()
self:UnregisterEvent("SKILL_LINES_CHANGED")
self:UnregisterEvent("MINIMAP_UPDATE_TRACKING")
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
GatherMate.HBD.UnregisterCallback(self, "PlayerZoneChanged")
WorldMapFrame:RemoveDataProvider(Display.WorldMapDataProvider)
end
function Display:PlayerZoneChanged()
local newZone = GatherMate.HBD:GetPlayerZone()
if GatherMate.phasing[newZone] then newZone = GatherMate.phasing[newZone] end
if newZone ~= zone then
zone = newZone
self:UpdateMiniMap(true)
end
end
function Display:SKILL_LINES_CHANGED()
for k,v in pairs(have_prof_skill) do
have_prof_skill[k] = nil
end
for index, key in pairs({GetProfessions()}) do
local name, icon, rank, maxrank, numspells, spelloffset, skillline = GetProfessionInfo(key)
if profession_to_skill[name] then
have_prof_skill[profession_to_skill[name]] = true
end
end
self:UpdateMaps()
end
function Display:MINIMAP_UPDATE_TRACKING()
local count = C_Minimap.GetNumTrackingTypes()
for id=1, count do
local info = C_Minimap.GetTrackingInfo(id)
if info.active and tracking_spells[info.name] then
active_tracking[tracking_spells[info.name]] = true
else
if tracking_spells[info.name] and not info.active then
active_tracking[tracking_spells[info.name]] = false
end
end
end
self:UpdateMaps()
end
local digSites = {}
function Display:DigsitesChanged()
table.wipe(digSites)
for continent in pairs(continentZoneList) do
local digSitesOnMap = C_ResearchInfo.GetDigSitesForMap(continent)
for i, digSiteInfo in ipairs(digSitesOnMap) do
local positionMapInfo = C_Map.GetMapInfoAtPosition(continent, digSiteInfo.position.x, digSiteInfo.position.y)
if positionMapInfo and positionMapInfo.mapID ~= continent then
digSites[positionMapInfo.mapID] = true
end
end
end
self:UpdateMaps()
end
local function IsActiveDigSite()
local showDig = _G.GetCVarBool("digSites")
return digSites[zone] and showDig
end
function Display:UpdateVisibility()
for k, v in pairs(GatherMate.db_types) do
local visible = false
local state = db.show[v]
if state == "always" then
visible = true
elseif state == "with_profession" then
visible = have_prof_skill[v]
elseif state == "active" then
visible = active_tracking[v] == true
if v == "Archaeology" then
visible = IsActiveDigSite()
end
end
GatherMate.Visible[v] = visible
-- For tracking circle
visible = false
state = db.trackShow
if state == "always" then
visible = true
elseif state == "with_profession" then
visible = have_prof_skill[v]
elseif state == "active" then
visible = (active_tracking[v] == true)
if v == "Archaeology" then
visible = IsActiveDigSite()
end
end
trackShow[v] = visible
end
end
function Display:SetTrackingSpell(skill,spell)
local spellName = C_Spell.GetSpellName(spell)
if not spellName then return end
tracking_spells[spellName] = skill
if fullInit then self:MINIMAP_UPDATE_TRACKING() end
end
function Display:SetSkillProfession(skill, profession)
profession_to_skill[profession] = skill
if fullInit then self:SKILL_LINES_CHANGED() end
end
function Display:ScheduleUpdate()
forceNextUpdate = true
end
function Display:DataUpdate()
forceNextUpdate = true
self:UpdateMaps()
end
function Display:ConfigChanged()
db = GatherMate.db.profile
self:UpdateMaps()
-- TODO filter prefs
end
--[[
Get a Map pin
]]
function Display:getMapPin()
local pin = next(pinCache)
if pin then
pinCache[pin] = nil -- remove it from the cache
return pin
end
-- create a new pin
pinCount = pinCount + 1
pin = CreateFrame("Button", "GatherMatePin"..pinCount, Minimap)
pin:SetFrameLevel(5)
pin:EnableMouse(true)
pin:SetWidth(16)
pin:SetHeight(16)
pin:SetPoint("CENTER", Minimap, "CENTER")
local texture = pin:CreateTexture(nil, "OVERLAY")
pin.texture = texture
texture:SetAllPoints(pin)
texture:SetTexture(trackingCircle)
texture:SetTexCoord(0, 1, 0, 1)
texture:SetTexelSnappingBias(0)
texture:SetSnapToPixelGrid(false)
pin:RegisterForClicks("LeftButtonUp", "RightButtonUp");
pin:SetScript("OnEnter", showPin)
pin:SetScript("OnLeave", hidePin)
pin:SetScript("OnClick", pinClick)
pin:Hide()
return pin
end
--[[
Add a new pin to the minimap
]]
function Display:getMiniPin(coord, nodeID, nodeType, zone, index)
local pin = minimapPins[index]
if not pin then
pin = self:getMapPin()
pin.coords = coord
pin.title = GatherMate:GetNameForNode(nodeType, nodeID)
pin.zone = zone
pin.nodeID = nodeID
pin.nodeType = nodeType
pin.worldmap = false
pin:SetParent(Minimap)
pin:SetFrameStrata(minimapStrata)
pin:SetFrameLevel(minimapFrameLevel)
pin:SetHeight(12 * db.miniscale / minimapScale)
pin:SetWidth(12 * db.miniscale / minimapScale)
--pin:SetAlpha(db.alpha)
pin:EnableMouse(db.minimapTooltips)
pin.isCircle = false
pin.texture:SetTexture(nodeTextures[nodeType][nodeID])
pin.texture:SetTexCoord(0, 1, 0, 1)
pin.texture:SetVertexColor(1, 1, 1, 1)
pin.x, pin.y = GatherMate:DecodeLoc(coord)
pin.x1, pin.y1 = GatherMate.HBD:GetWorldCoordinatesFromZone(pin.x,pin.y,zone)
minimapPins[index] = pin
end
return pin
end
function Display:addMiniPin(pin, refresh)
local xDist, yDist = lastXY - pin.x1, lastYY - pin.y1
-- calculate relative position and distance to the player
local dist_2 = xDist*xDist + yDist*yDist
-- if distance <= db.trackDistance, convert to the circle texture
if (not pin.isCircle or refresh) and trackShow[pin.nodeType] and dist_2 <= db.trackDistance^2 then
pin.texture:SetTexture(trackingCircle)
local t = db.trackColors[pin.nodeType]
pin.texture:SetVertexColor(t.Red, t.Green, t.Blue, t.Alpha)
pin:SetHeight(12 / minimapScale)
pin:SetWidth(12 / minimapScale)
pin.isCircle = true
pin.texture:SetTexCoord(0, 1, 0, 1)
pin.texture:ClearAllPoints()
pin.texture:SetPoint("TOPLEFT", -1, 1)
pin.texture:SetPoint("BOTTOMRIGHT", -1, 1)
-- if distance > 100, set back to the node texture
elseif (pin.isCircle or refresh) and dist_2 > db.trackDistance^2 then
pin:SetHeight(12 * db.miniscale / minimapScale)
pin:SetWidth(12 * db.miniscale / minimapScale)
pin.texture:SetTexture(nodeTextures[pin.nodeType][pin.nodeID])
pin.texture:SetVertexColor(1, 1, 1, 1)
pin.texture:SetTexCoord(0, 1, 0, 1)
pin.texture:ClearAllPoints()
pin.texture:SetAllPoints()
pin.isCircle = false
end
-- support for rotating minimap - transpose coordinates for the circular movement
if rotateMinimap then
local dx, dy = xDist, yDist
xDist = dx*cos - dy*sin
yDist = dx*sin + dy*cos
end
-- place pin on the map
local diffX, diffY, alpha = 0, 0, 1
-- adapt delta position to the map radius
diffX = xDist / mapRadius
diffY = yDist / mapRadius
-- different minimap shapes
local isRound = true
if ( minimapShape and not (xDist == 0 or yDist == 0) ) then
isRound = (xDist < 0) and 1 or 3
if ( yDist < 0 ) then
isRound = minimapShape[isRound]
else
isRound = minimapShape[isRound + 1]
end
end
-- calculate distance from the center of the map
local dist
if isRound then
dist = (diffX*diffX + diffY*diffY) / 0.9^2
else
dist = max(diffX*diffX, diffY*diffY) / 0.9^2
end
-- if distance > 1, then adapt node position to slide on the border, and set the node alpha accordingly
if dist > 1 then
dist = dist^0.5
diffX = diffX/dist
diffY = diffY/dist
alpha = 2 - dist
if alpha < 0 then
pin.keep = nil
alpha = 0
end
end
-- finally show and SetPoint the pin
if db.nodeRange or alpha >= 1 then
pin:Show()
pin:ClearAllPoints()
pin:SetPoint("CENTER", Minimap, "CENTER", diffX * minimapWidth, -diffY * minimapHeight)
pin:SetAlpha(min(alpha,db.alpha))
else
pin:Hide()
end
end
--[[
Minimap zoom changed
]]
function Display:MinimapZoom()
self:UpdateMiniMap()
end
--[[
Minimap rotation changed
]]
function Display:ChangedVars(event,cvar,value)
if cvar == "rotateMinimap" then
rotateMinimap = value == "1"
end
forceNextUpdate = true
end
function Display:UpdateMaps()
clearpins(minimapPins)
-- Ask to update the visiblity for archaeology updates to blobs
self:UpdateVisibility()
self:UpdateMiniMap(true)
self:UpdateWorldMap(true)
end
function Display:UpdateIconPositions()
if not db.showMinimap or not Minimap:IsVisible() or not zone then return end
-- get the current map zoom
local zoom = Minimap:GetZoom()
local diffZoom = zoom ~= lastZoom
-- if the map zoom changed, run a full update sweep
if diffZoom then
self:UpdateMiniMap()
return
end
-- we have no active minimap pins, just return early
if minimapPinCount == 0 then return end
-- get current player position
local x, y = GatherMate.HBD:GetPlayerWorldPosition()
-- for rotating minimap support
local facing
if rotateMinimap then
facing = GetPlayerFacing()
else
facing = lastFacing
end
if not x or not y or (rotateMinimap and not facing) then
self:UpdateMiniMap()
return
end
local refresh
local newScale = Minimap:GetScale()
if minimapScale ~= newScale then
minimapScale = newScale
refresh = true
end
-- if the player moved, or changed the facing (rotating map) - update nodes
if x ~= lastXY or y ~= lastYY or facing ~= lastFacing or refresh then
-- update radius of the map
mapRadius = C_Minimap.GetViewRadius()
-- update upvalues for icon placement
lastXY, lastYY = x, y
lastFacing = facing
if rotateMinimap then
sin = math_sin(facing)
cos = math_cos(facing)
end
-- iterate all nodes and check if they are still in range of our minimap display, or even still existing
for k,v in pairs(minimapPins) do
-- update the position of the node
self:addMiniPin(v, refresh)
end
end
end
--[[
Update the minimap
we only care about nodes 1000 yards away
]]
function Display:UpdateMiniMap(force)
if not db.showMinimap or not Minimap:IsVisible() then return end
if not zone or zone == 0 then
zone = nil
return
end
-- get current player position
local x, y = GatherMate.HBD:GetPlayerWorldPosition()
-- get data from the API for calculations
local zoom = Minimap:GetZoom()
local diffZoom = zoom ~= lastZoom
-- for rotating minimap support
local facing
if rotateMinimap then
facing = GetPlayerFacing()
else
facing = lastFacing
end
-- disable all pins if no position is available
if not x or not y or (rotateMinimap and not facing) then
minimapPinCount = 0
for k,v in pairs(minimapPins) do
recyclePin(v)
minimapPins[k] = nil
end
return
end
local newScale = Minimap:GetScale()
if minimapScale ~= newScale then
minimapScale = newScale
force = true
end
-- if the player moved, the zoom changed, or changed the facing (rotating map) - update nodes
if x ~= lastXY or y ~= lastYY or diffZoom or facing ~= lastFacing or force then
-- set upvalues to new settings
minimapShape = GetMinimapShape and self.minimapShapes[GetMinimapShape() or "ROUND"]
minimapWidth = Minimap:GetWidth() / 2
minimapHeight = Minimap:GetHeight() / 2
minimapStrata = Minimap:GetFrameStrata()
minimapFrameLevel = Minimap:GetFrameLevel() + 5
mapRadius = C_Minimap.GetViewRadius()
local x1, y1 = GatherMate.HBD:GetZoneCoordinatesFromWorld(x,y,zone)
if not x1 then
x1, y1 = GatherMate.HBD:GetZoneCoordinatesFromWorld(x,y,zone)
if not x1 then return end
end
-- update upvalues for icon placement
lastZoom = zoom
lastFacing = facing
lastXY, lastYY = x, y
if rotateMinimap then
sin = math_sin(facing)
cos = math_cos(facing)
end
-- iterate the node databases and add the nodes
for i,db_type in pairs(GatherMate.db_types) do
if GatherMate.Visible[db_type] then
for coord, nodeID in GatherMate:FindNearbyNode(zone, x1, y1, db_type, mapRadius*nodeRange) do
local pin = self:getMiniPin(coord, nodeID, db_type, zone, (i * 1e14) + coord)
pin.keep = true
self:addMiniPin(pin, force)
end
end
end
minimapPinCount = 0
for k,v in pairs(minimapPins) do
if not v.keep then
recyclePin(v)
minimapPins[k] = nil
else
minimapPinCount = minimapPinCount + 1
v.keep = nil
end
end
end
end
---------------------------------------------------------
-- World Map Data Provider
Display.WorldMapDataProvider = CreateFromMixins(MapCanvasDataProviderMixin)
function Display.WorldMapDataProvider:RemoveAllData()
self:GetMap():RemoveAllPinsByTemplate("GatherMate2WorldMapPinTemplate")
wipe(worldmapPins)
end
function Display.WorldMapDataProvider:RefreshAllData(fromOnShow)
self:RemoveAllData()
if not db.showWorldMap then return end
-- update visibility for archaeology blobs
Display:UpdateVisibility()
local map = self:GetMap()
local uiMapID = map:GetMapID()
if not uiMapID then return end
if GatherMate.phasing[uiMapID] then uiMapID = GatherMate.phasing[uiMapID] end
-- iterate databases and add nodes
for i,db_type in pairs(GatherMate.db_types) do
if GatherMate.Visible[db_type] then
for coord, nodeID in GatherMate:GetNodesForZone(uiMapID, db_type) do
local pin = map:AcquirePin("GatherMate2WorldMapPinTemplate", coord, nodeID, db_type, uiMapID)
table.insert(worldmapPins, pin)
end
end
end
end
--[[ Handy Notes WorldMap Pin ]]--
GatherMate2WorldMapPinMixin = CreateFromMixins(MapCanvasPinMixin)
function GatherMate2WorldMapPinMixin:OnLoad()
self:UseFrameLevelType("PIN_FRAME_LEVEL_AREA_POI")
self:SetScalingLimits(1, 1.0, 1.2);
end
function GatherMate2WorldMapPinMixin:OnAcquired(coord, nodeID, nodeType, zone)
local x,y = GatherMate:DecodeLoc(coord)
self:SetPosition(x, y)
self.coords = coord
self.title = GatherMate:GetNameForNode(nodeType, nodeID)
self.zone = zone
self.nodeID = nodeID
self.nodeType = nodeType
self.worldmap = true
self:SetHeight(12 * db.scale)
self:SetWidth(12 * db.scale)
self:SetAlpha(db.alpha)
self.texture:SetTexture(nodeTextures[nodeType][nodeID])
self.texture:SetTexCoord(0, 1, 0, 1)
self.texture:SetVertexColor(1, 1, 1, 1)
self:EnableMouse(db.worldMapIconsInteractive)
-- enable right-click interactivity
if db.worldMapIconsInteractive and self.SetPassThroughButtons then
self:SetPassThroughButtons("")
end
end
function GatherMate2WorldMapPinMixin:OnMouseEnter()
return showPin(self)
end
function GatherMate2WorldMapPinMixin:OnMouseLeave()
return hidePin(self)
end
function GatherMate2WorldMapPinMixin:OnClick(button)
return pinClick(self, button)
end
-- hack to avoid error in combat in 10.1.5
GatherMate2WorldMapPinMixin.SetPassThroughButtons = function() end
function Display:UpdateWorldMap()
self.WorldMapDataProvider:RefreshAllData()
end
--[[
This function is for external addons to call to reparent all existing
minimap icons to a new minimap frame.
]]
function Display:ReparentMinimapPins(parent)
Minimap = parent
GameTooltip:SetFrameLevel(parent:GetFrameLevel()+2) -- Because Chinchilla_Expander_Minimap is on TOOLTIP strata too
for k, v in pairs(minimapPins) do
v:SetParent(parent)
end
self:UpdateIconPositions()
end