Files
pfUI/modules/minimap.lua
T
Brues b7c3fe5333 Filter unit events with RegisterUnitEvent
ClassicAPI's RegisterUnitEvent registers for an event but only delivers it
when arg1 is one of the given units, so a handler for one unit stops waking
for every other one in the world. Convert the 26 registrations whose unit set
is fixed and known at registration time.

The rule throughout is register the superset and keep the handler's own
check: the filter narrows what arrives, it does not decide what to act on.
castbar is the case that matters -- the player's own casts only ever fire
arg1=="player", never "target"/"focus", so the target and focus bars must
register "player" too, and their UnitIsUnit test is what still rejects a
"player" event while you are targeting a mob.

Two that are not one-line swaps:

  actionbar's two unit events are keys in tables that also drive dispatch, so
  they cannot leave the tables -- and they cannot be plain-registered first,
  because a registration keeps its kind and RegisterUnitEvent over a plain
  one stays plain. They route through a small event_units map instead.

  swingtimer's UNIT_DIED carries a GUID, not a token. The filter is a plain
  case-insensitive string compare with no GUID resolution, so the player's
  own GUID -- fixed for the session -- filters it exactly.

Guards that are now unreachable stay put: the filter applies only when arg1
is a string, so an event that ever fires with a number or no argument is
delivered as if plainly registered, and the handler's own test is what still
rejects it.

Left alone: api/unitframes.lua (the frame's unit changes at runtime and the
handler also matches on GUID), nameplates' six nameplateN events, libdebuff
and libpredict's UNIT_HEALTH (genuinely any unit), and raid.lua's UNIT_PET
(any raid member can own the pet).
2026-09-09 13:24:17 -05:00

243 lines
8.6 KiB
Lua

pfUI:RegisterModule("minimap", function ()
local rawborder, border = GetBorderSize()
local size = tonumber(C.appearance.minimap.size) or 140
if MiniMapWorldMapButton then MiniMapWorldMapButton:Hide() end
if MinimapToggleButton then MinimapToggleButton:Hide() end
MinimapBorderTop:Hide()
MinimapZoneTextButton:Hide()
MinimapZoomIn:Hide()
MinimapZoomOut:Hide()
GameTimeFrame:Hide()
MinimapBorder:SetTexture(nil)
pfUI.minimap = CreateFrame("Frame","pfMinimap",UIParent)
CreateBackdrop(pfUI.minimap)
CreateBackdropShadow(pfUI.minimap)
pfUI.minimap:SetPoint("TOPRIGHT", UIParent, -border*2, -border*2)
UpdateMovable(pfUI.minimap)
pfUI.minimap:SetScript("OnShow", function()
QueueFunction(ShowUIPanel, Minimap)
end)
Minimap:SetParent(pfUI.minimap)
Minimap:SetPoint("CENTER", pfUI.minimap, "CENTER", 0.5, -.5)
Minimap:SetFrameLevel(1)
Minimap:SetMaskTexture(pfUI.media["img:minimap"])
Minimap:EnableMouseWheel(true)
Minimap:SetScript("OnMouseWheel", function()
if(arg1 > 0) then Minimap_ZoomIn() else Minimap_ZoomOut() end
end)
pfUI.minimap.UpdateConfig = function(self)
size = tonumber(C.appearance.minimap.size) or 140
pfUI.minimap:SetSize(size, size)
Minimap:SetSize(size, size)
-- vanilla+tbc: do the best to detect the minimap arrow
local arrowscale = tonumber(C.appearance.minimap.arrowscale)
local minimaparrow = ({Minimap:GetChildren()})[9]
for k, v in pairs({Minimap:GetChildren()}) do
if v:IsObjectType("Model") and not v:GetName() then
if string.find(strlower(v:GetModel()), "interface\\minimap\\minimaparrow") then
minimaparrow = v
break
end
end
end
if minimaparrow then
minimaparrow:SetScale(arrowscale)
end
end
pfUI.minimap:UpdateConfig()
hooksecurefunc("ToggleMinimap", function()
if pfUI.farmmap and pfUI.farmmap:IsShown() then
Minimap:Hide()
return
end
if Minimap:IsVisible() then
pfUI.minimap:SetHeight(size)
pfUI.minimap:SetAlpha(1)
else
pfUI.minimap:SetHeight(-border-5)
pfUI.minimap:SetAlpha(0)
Minimap:Hide()
end
end)
-- battleground icon
MiniMapBattlefieldFrame:ClearAllPoints()
MiniMapBattlefieldFrame:SetPoint("BOTTOMRIGHT", Minimap, 4, -4)
MiniMapBattlefieldBorder:Hide()
MiniMapBattlefieldFrame:SetScript("OnClick", function()
GameTooltip:Hide()
if MiniMapBattlefieldFrame.status == "active" then
if arg1 == "RightButton" then
ToggleDropDownMenu(1, nil, MiniMapBattlefieldDropDown, "MiniMapBattlefieldFrame", -95, -5)
elseif IsShiftKeyDown() then
ToggleBattlefieldMinimap()
else
ToggleWorldStateScoreFrame()
end
elseif arg1 == "RightButton" then
ToggleDropDownMenu(1, nil, MiniMapBattlefieldDropDown, "MiniMapBattlefieldFrame", -95, -5)
end
end)
-- mail icon
MiniMapMailFrame:ClearAllPoints()
MiniMapMailFrame:SetPoint("TOPRIGHT", pfUI.minimap, "TOPRIGHT", 0, 0)
MiniMapMailBorder:Hide()
MiniMapMailIcon:SetTexture(pfUI.media["img:mail"])
MiniMapMailFrame:SetScript("OnShow", function()
if not this.highlight then
this.highlight = CreateFrame("Frame", nil, this)
this.highlight:SetAllPoints(this)
this.highlight:SetFrameLevel(this:GetFrameLevel() + 1)
this.highlight.tex = this.highlight:CreateTexture("OVERLAY")
this.highlight.tex:SetTexture(pfUI.media["img:mail"])
this.highlight.tex:SetPoint("TOPLEFT", MiniMapMailIcon, "TOPLEFT", -2, 2)
this.highlight.tex:SetPoint("BOTTOMRIGHT", MiniMapMailIcon, "BOTTOMRIGHT", 2, -2)
this.highlight.tex:SetVertexColor(1,.5,.5)
this.highlight:SetScript("OnUpdate", function()
if not this.count then this.count = 0 end
if not this.modifier then this.modifier = 1 end
if this.count >= 10 then this:Hide() end
this:SetAlpha(this:GetAlpha() + this.modifier)
if this:GetAlpha() <= 0.1 then
this.modifier = 0.05
this.count = this.count + 1
elseif this:GetAlpha() >= 0.9 then
this.modifier = -0.05
end
end)
end
this.highlight.count = 0
this.highlight:Show()
end)
-- Create coordinates text frame with location configurable
pfUI.minimapCoordinates = CreateFrame("Frame", "pfMinimapCoord", pfUI.minimap)
-- Update coords every 0.1 seconds
C_Timer.NewTicker(0.1, function()
if C.appearance.minimap.coordstext == "off" then return end
local coord = pfUI.minimapCoordinates
coord.posX, coord.posY = GetPlayerMapPosition("player")
if coord.posX ~= 0 and coord.posY ~= 0 then
coord.text:SetFormattedText("%.1f, %.1f", round(coord.posX * 100, 1), round(coord.posY * 100, 1))
else
coord.text:SetText("|cffffaaaaN/A")
end
end)
if C.appearance.minimap.coordsloc == "topleft" then
pfUI.minimapCoordinates:SetPoint("TOPLEFT", 3, -3)
elseif C.appearance.minimap.coordsloc == "topright" then
pfUI.minimapCoordinates:SetPoint("TOPRIGHT", -3, -3)
elseif C.appearance.minimap.coordsloc == "bottomright" then
pfUI.minimapCoordinates:SetPoint("BOTTOMRIGHT", -3, 3)
else
pfUI.minimapCoordinates:SetPoint("BOTTOMLEFT", 3, 3)
end
pfUI.minimapCoordinates:SetSize(Minimap:GetWidth(), C.global.font_size)
pfUI.minimapCoordinates.text = pfUI.minimapCoordinates:CreateFontString("MinimapCoordinatesText", "LOW", "GameFontNormal")
pfUI.minimapCoordinates.text:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
pfUI.minimapCoordinates.text:SetTextColor(1,1,1,1)
pfUI.minimapCoordinates.text:SetAllPoints(pfUI.minimapCoordinates)
if C.appearance.minimap.coordsloc == "topright" or C.appearance.minimap.coordsloc == "bottomright" then
pfUI.minimapCoordinates.text:SetJustifyH("RIGHT")
else
pfUI.minimapCoordinates.text:SetJustifyH("LEFT")
end
pfUI.minimapCoordinates:SetShown(C.appearance.minimap.coordstext == "on")
-- Create zone text frame in top center of minimap
pfUI.minimapZone = CreateFrame("Frame", "pfMinimapZone", pfUI.minimap)
pfUI.minimapZone:RegisterEvent("MINIMAP_ZONE_CHANGED")
pfUI.minimapZone:RegisterEvent("PLAYER_ENTERING_WORLD")
pfUI.minimapZone:SetPoint("TOP", 0, -3)
pfUI.minimapZone:SetSize(Minimap:GetWidth(), C.global.font_size + 2)
pfUI.minimapZone.text = pfUI.minimapZone:CreateFontString("minimapZoneText", "LOW", "GameFontNormal")
pfUI.minimapZone.text:SetFont(pfUI.font_default, C.global.font_size + 2, "OUTLINE")
pfUI.minimapZone.text:SetAllPoints(pfUI.minimapZone)
pfUI.minimapZone.text:SetJustifyH("CENTER")
pfUI.minimapZone:SetScript("OnEvent", function()
if not WorldMapFrame:IsShown() then
SetMapToCurrentZone()
end
if C.appearance.minimap.zonetext ~= "off" then
local pvp, _, arena = GetZonePVPInfo()
if arena then
pfUI.minimapZone.text:SetTextColor(1.0, 0.1, 0.1)
elseif pvp == "friendly" then
pfUI.minimapZone.text:SetTextColor(0.1, 1.0, 0.1)
elseif pvp == "hostile" then
pfUI.minimapZone.text:SetTextColor(1.0, 0.1, 0.1)
elseif pvp == "contested" then
pfUI.minimapZone.text:SetTextColor(1.0, 0.7, 0)
else
pfUI.minimapZone.text:SetTextColor(WHITE_FONT_COLOR:GetRGBA())
end
pfUI.minimapZone.text:SetText(GetMinimapZoneText())
end
end)
pfUI.minimapZone:SetShown(C.appearance.minimap.zonetext == "on")
-- Minimap hover event
-- Update and toggle showing of coordinates and zone text on mouse enter/leave
Minimap:SetScript("OnEnter", function()
if C.appearance.minimap.coordstext ~= "off" then
pfUI.minimapCoordinates:Show()
end
if C.appearance.minimap.zonetext ~= "off" then
pfUI.minimapZone:Show()
end
end)
Minimap:SetScript("OnLeave", function()
if C.appearance.minimap.coordstext ~= "on" then
pfUI.minimapCoordinates:Hide()
end
if C.appearance.minimap.zonetext ~= "on" then
pfUI.minimapZone:Hide()
end
end)
pfUI.minimap.pvpicon = CreateFrame("Frame", nil, pfUI.minimap)
pfUI.minimap.pvpicon:Hide()
pfUI.minimap.pvpicon:RegisterEvent("UPDATE_FACTION")
pfUI.minimap.pvpicon:RegisterUnitEvent("UNIT_FACTION", "player")
pfUI.minimap.pvpicon:SetFrameStrata("HIGH")
pfUI.minimap.pvpicon:SetSize(16, 16)
pfUI.minimap.pvpicon:SetAlpha(.5)
pfUI.minimap.pvpicon:SetParent(pfUI.minimap)
pfUI.minimap.pvpicon:SetPoint("BOTTOMRIGHT", pfUI.minimap, "BOTTOMRIGHT", -5, 5)
pfUI.minimap.pvpicon.texture = pfUI.minimap.pvpicon:CreateTexture(nil,"DIALOG")
pfUI.minimap.pvpicon.texture:SetTexture(pfUI.media["img:pvp"])
pfUI.minimap.pvpicon.texture:SetAllPoints(pfUI.minimap.pvpicon)
pfUI.minimap.pvpicon:SetScript("OnEvent", function()
pfUI.minimap.pvpicon:SetShown(C.unitframes.player.showPVPMinimap == "1" and UnitIsPVP("player"))
end)
end)