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.

244 lines
8.0 KiB

local myname = ...
local core = LibStub("AceAddon-3.0"):GetAddon("SilverDragon")
local module = core:GetModule("Overlay")
local Debug = core.Debug
local ns = core.NAMESPACE
local HBD = LibStub("HereBeDragons-2.0")
local HBDPins = LibStub("HereBeDragons-Pins-2.0")
4 years ago
local f = CreateFrame("Frame", myname .. "MiniMapDataProviderFrame")
local dataProvider = {
facing = GetPlayerFacing(),
pins = {},
pinPools = {},
-- pool = CreateFramePool("FRAME", Minimap, "SilverDragonOverlayMinimapPinTemplate"),
}
module.MiniMapDataProvider = dataProvider
function dataProvider:RefreshAllData()
-- if we're here really early for some reason
if not module.db then return end
HBDPins:RemoveAllMinimapIcons(self)
4 years ago
self:ReleaseAllPins()
4 years ago
-- if we either can't display anything meaningful, or are disabled
if GetCVar('rotateMinimap') == '1' and self.facing == nil then return end
if not module.db.profile.minimap.enabled then return end
local uiMapID = HBD:GetPlayerZone()
if not uiMapID then return end
for coord, mobid, textureData, scale, alpha in module:IterateNodes(uiMapID, true) do
local x, y = core:GetXY(coord)
4 years ago
local pin = self:AcquirePin("SilverDragonOverlayMinimapPinTemplate", mobid, x, y, textureData, scale or 1.0, alpha or 1.0, coord, uiMapID, true)
local edge = module.db.profile.minimap.edge == module.const.EDGE_ALWAYS
if module.db.profile.minimap.edge == module.const.EDGE_FOCUS then
edge = mobid == module.focus_mob
end
HBDPins:AddMinimapIconMap(self, pin, uiMapID, x, y, false, edge)
pin:UpdateEdge()
end
4 years ago
if module.db.profile.minimap.routes and ns.mobsByZone[uiMapID] then
for mobid, coords in pairs(ns.mobsByZone[uiMapID]) do
self:AddRoute(uiMapID, mobid)
end
end
end
function dataProvider:RefreshAllRotations()
for _, pool in pairs(self.pinPools) do
for pin in pool:EnumerateActive() do
if pin.UpdateRotation then
pin:UpdateRotation()
end
end
end
end
local function OnPinReleased(pinPool, pin)
FramePool_HideAndClearAnchors(pinPool, pin)
pin:OnReleased()
pin.pinTemplate = nil
pin.provider = nil
end
function dataProvider:AcquirePin(pinTemplate, ...)
if not self.pinPools[pinTemplate] then
self.pinPools[pinTemplate] = CreateFramePool("FRAME", Minimap, pinTemplate, OnPinReleased)
end
local pin, newPin = self.pinPools[pinTemplate]:Acquire()
pin.pinTemplate = pinTemplate
pin.provider = self
if newPin then
pin:OnLoad()
end
pin:Show()
pin:OnAcquired(...)
return pin
end
function dataProvider:ReleaseAllPins()
for _, pool in pairs(self.pinPools) do
pool:ReleaseAll()
end
end
module:RegisterEvent("MINIMAP_UPDATE_ZOOM", function() dataProvider:RefreshAllData() end)
module:RegisterEvent("CVAR_UPDATE", function(_, varname)
if varname == "ROTATE_MINIMAP" then
dataProvider:RefreshAllData()
end
end)
f:SetScript("OnUpdate", function(self)
if GetCVar("rotateMinimap") == "1" then
local facing = GetPlayerFacing()
if facing ~= dataProvider.facing then
dataProvider.facing = facing
dataProvider:RefreshAllRotations()
end
end
end)
C_Timer.NewTicker(0.5, function(...)
for _, pool in pairs(dataProvider.pinPools) do
for pin in pool:EnumerateActive() do
if pin.UpdateEdge then
pin:UpdateEdge()
end
end
end
end)
function dataProvider:AddRoute(uiMapID, mobid)
local data = ns.mobdb[mobid or 0]
if not data then return end
if not (data.routes and data.routes[uiMapID]) then return end
if not (core:IsMobInPhase(mobid, uiMapID) and not core:ShouldIgnoreMob(mobid, uiMapID)) then return end
if not module.should_show_mob(mobid) then return end
for _, route in ipairs(data.routes[uiMapID]) do
for i=1, #route - 1 do
self:DrawSegment(route[i], route[i+1], uiMapID, mobid, route)
end
if route.loop and #route > 1 then
self:DrawSegment(route[1], route[#route], uiMapID, mobid, route)
end
end
end
4 years ago
local segmented = {}
function dataProvider:DrawSegment(coord1, coord2, ...)
wipe(segmented)
local x1, y1 = core:GetXY(coord1)
local x2, y2 = core:GetXY(coord2)
-- find an appropriate number of segments
local distance = math.sqrt(((x2-x1) * 1.85)^2 + (y2-y1)^2)
local segments = floor(distance / 0.015)
for i=0, segments do
segmented[#segmented + 1] = core:GetCoord(
x1 + (x2-x1) / segments * i,
y1 + (y2-y1) / segments * i
)
end
for i=1, #segmented - 1 do
self:AcquirePin("SilverDragonOverlayMinimapRoutePinTemplate", segmented[i], segmented[i + 1], ...)
end
end
--
SilverDragonOverlayMinimapPinMixin = CreateFromMixins(module.SilverDragonOverlayPinMixinBase)
function SilverDragonOverlayMinimapPinMixin:OnLoad()
self:SetParent(Minimap)
self:SetFrameStrata(Minimap:GetFrameStrata())
self:SetFrameLevel(Minimap:GetFrameLevel() + 5)
self:EnableMouse()
self:SetScript("OnEnter", self.OnMouseEnter)
self:SetScript("OnLeave", self.OnMouseLeave)
self:SetScript("OnMouseUp", self.OnMouseUp)
self:SetMouseClickEnabled(true)
self:SetMouseMotionEnabled(true)
end
function SilverDragonOverlayMinimapPinMixin:UpdateEdge()
local alpha = (HBDPins:IsMinimapIconOnEdge(self) and 0.6 or 1) * self:Config().icon_alpha
4 years ago
self:SetAlpha(alpha)
end
SilverDragonOverlayMinimapRoutePinMixin = {}
function SilverDragonOverlayMinimapRoutePinMixin:OnLoad()
self:SetParent(Minimap)
self:SetFrameStrata(Minimap:GetFrameStrata())
self:SetFrameLevel(Minimap:GetFrameLevel() + 3)
-- self.texture:SetTexture("Interface\\TaxiFrame\\UI-Taxi-Line")
self.texture:SetAtlas("_AnimaChannel-Channel-Line-horizontal")
self.minimap = true
end
function SilverDragonOverlayMinimapRoutePinMixin:OnAcquired(coord1, coord2, uiMapID, mobid, route)
-- print("OnAcquired", coord1, coord2, uiMapID)
local x1, y1 = core:GetXY(coord1)
local x2, y2 = core:GetXY(coord2)
local wx1, wy1 = HBD:GetWorldCoordinatesFromZone(x1, y1, uiMapID)
local wx2, wy2 = HBD:GetWorldCoordinatesFromZone(x2, y2, uiMapID)
local wmapDistance = math.sqrt((wx2-wx1)^2 + (wy2-wy1)^2)
local mmapDiameter = C_Minimap:GetViewRadius() * 2
local length = Minimap:GetWidth() * (wmapDistance / mmapDiameter)
self.rotation = -math.atan2(wy2-wy1, wx2-wx1)
self:SetSize(length, 30)
self.texture:SetRotation(self.rotation)
local r, g, b, a = 1, 1, 1, 0.6
if route and route.r then
r, g, b, a = route.r or 1, route.g or 1, route.b or 1, route.a or 0.6
else
r, g, b = module.id_to_color(mobid)
end
self.texture:SetVertexColor(r, g, b, a * self:Config().icon_alpha)
4 years ago
local x, y = (x1+x2)/2, (y1+y2)/2
HBDPins:AddMinimapIconMap(dataProvider, self, uiMapID, x, y)
if GetCVar('rotateMinimap') == '1' then self:UpdateRotation() end
end
function SilverDragonOverlayMinimapRoutePinMixin:OnReleased()
self.texture:SetRotation(0)
self.texture:SetTexCoord(0, 1, 0, 1)
self.texture:SetVertexColor(1, 1, 1, 1)
self.rotation = nil
self:SetAlpha(1)
if self.SetScalingLimits then -- world map
self:SetScalingLimits(nil, nil, nil)
end
end
function SilverDragonOverlayMinimapRoutePinMixin:UpdateRotation()
if self.rotation == nil or self.provider.facing == nil then return end
self.texture:SetRotation(self.rotation + math.pi*2 - self.provider.facing)
end
-- This isn't made from the mixin, but I want this method anyway:
SilverDragonOverlayMinimapRoutePinMixin.Config = module.SilverDragonOverlayPinMixinBase.Config
4 years ago
--
function module:UpdateMinimapIcons()
self.MiniMapDataProvider:RefreshAllData()
end