You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
830 lines
24 KiB
830 lines
24 KiB
local GatherMate = LibStub("AceAddon-3.0"):GetAddon("GatherMate2")
|
|
local Display = GatherMate:NewModule("Display","AceEvent-3.0")
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("GatherMate2")
|
|
|
|
-- WoW 10.0 tracking API compat
|
|
local GetNumTrackingTypes = GetNumTrackingTypes or C_Minimap.GetNumTrackingTypes
|
|
local GetTrackingInfo = GetTrackingInfo or C_Minimap.GetTrackingInfo
|
|
|
|
-- 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 tinsert, tremove, next, pairs = tinsert, tremove, next, pairs
|
|
-- minimap rotation
|
|
local rotateMinimap = GetCVar("rotateMinimap") == "1"
|
|
-- shape of the minimap
|
|
local minimapShape
|
|
-- is the minimap indoors or outdoors
|
|
local indoors = GetCVar("minimapZoom")+0 == Minimap:GetZoom() and "outdoor" or "indoor"
|
|
-- diameter of the minimap
|
|
local mapRadius, minimapWidth, minimapHeight, minimapScale, lastFacing, lastZoom
|
|
local minimapStrata, minimapFrameLevel
|
|
-- math function cache
|
|
local math_sin, math_cos, abs, max = math.sin, math.cos, math.abs, math.max
|
|
local sin, cos
|
|
-- API function cache
|
|
local GetRealZoneText = GetRealZoneText
|
|
local GetProfessionInfo = GetProfessionInfo
|
|
local strfind, format = string.find, string.format
|
|
local trackingCircle, nodeTextures
|
|
local db
|
|
local Minimap = Minimap
|
|
local inInstance
|
|
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
|
|
}
|
|
|
|
--[[
|
|
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 function showPin(self)
|
|
if (self.title) then
|
|
local pinset
|
|
if self.worldmap then
|
|
pinset = worldmapPins
|
|
else
|
|
pinset = minimapPins
|
|
end
|
|
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 text = format(tooltip_template, t[self.nodeType].Alpha*255, t[self.nodeType].Red*255, t[self.nodeType].Green*255, t[self.nodeType].Blue*255, self.title)
|
|
for id, pin in pairs(pinset) do
|
|
if pin:IsMouseOver() and pin.title and pin ~= self then
|
|
text = text .. "\n" .. format(tooltip_template, t[pin.nodeType].Alpha*255, t[pin.nodeType].Red*255, t[pin.nodeType].Green*255, t[pin.nodeType].Blue*255, pin.title)
|
|
end
|
|
end
|
|
GameTooltip:SetText(text)
|
|
GameTooltip:Show()
|
|
end
|
|
end
|
|
--[[
|
|
Pin OnLeave
|
|
]]
|
|
local function hidePin(self)
|
|
GameTooltip:Hide()
|
|
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 id, pin in pairs(worldmapPins) do
|
|
if pin:IsMouseOver() and pin.title then
|
|
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
|
|
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 = GetNumTrackingTypes();
|
|
local info;
|
|
for id=1, count do
|
|
local name, texture, active, category = GetTrackingInfo(id);
|
|
if tracking_spells[name] and active then
|
|
active_tracking[tracking_spells[name]] = true
|
|
else
|
|
if tracking_spells[name] and not active then
|
|
active_tracking[tracking_spells[name]] = false
|
|
end
|
|
end
|
|
end
|
|
self:UpdateMaps()
|
|
end
|
|
|
|
local digSites = {}
|
|
|
|
function Display:DigsitesChanged()
|
|
table.wipe(digSites)
|
|
for continent in pairs(continentZoneList) do
|
|
local digSites = C_ResearchInfo.GetDigSitesForMap(continent)
|
|
for i, digSiteInfo in ipairs(digSites) 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, _, texture = GetSpellInfo(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 uiMapID = self:GetMap():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 = self:GetMap():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
|
|
|