Add minimap tracking dropdown with Wrath-style NPC icons
Take over native MiniMapTrackingFrame to show a tracking spell dropdown (Hunter Track X, Sense Undead/Demons, Find Herbs/Minerals) plus NPC tracking categories with icons extracted from the 3.3.5 client (Auctioneer, Flight Master, Mailbox, Repair, etc.).
This commit is contained in:
@@ -19,7 +19,7 @@ const module_list = [_]ModuleDesc{
|
||||
.{ .name = "worldmarkers", .desc = "Enable world markers module", .src_dir = "markers", .addon_name = "WorldMarkers" },
|
||||
.{ .name = "framecrash", .desc = "Enable framecrash fix", .default = false },
|
||||
.{ .name = "logsessions", .desc = "Enable log session rotation", .addon_name = "LogSessions" },
|
||||
.{ .name = "minimapicons", .desc = "Enable custom minimap icons" },
|
||||
.{ .name = "minimapicons", .desc = "Enable custom minimap icons", .addon_name = "MinimapIcons" },
|
||||
.{ .name = "transmogfix", .desc = "Enable transmog update coalescing" },
|
||||
.{ .name = "customassets", .desc = "Enable loose file loading & permissive patch glob" },
|
||||
.{ .name = "healtextfix", .desc = "Enable SuperWoW heal text fix" },
|
||||
|
||||
+2
-1
@@ -146,6 +146,7 @@ const embed_modules = [_]EmbedModule{
|
||||
.{ .option = "outline", .addon_name = "Outline", .addon_files_opt = "outline_addon_files" },
|
||||
.{ .option = "worldmarkers", .addon_name = "WorldMarkers", .addon_files_opt = "worldmarkers_addon_files", .asset_files_opt = "worldmarkers_asset_files" },
|
||||
.{ .option = "logsessions", .addon_name = "LogSessions", .addon_files_opt = "logsessions_addon_files" },
|
||||
.{ .option = "minimapicons", .addon_name = "MinimapIcons", .addon_files_opt = "minimapicons_addon_files", .asset_files_opt = "minimapicons_asset_files" },
|
||||
};
|
||||
|
||||
/// Extract filename from a path like "markers/addon/Foo.lua" → "Foo.lua"
|
||||
@@ -202,7 +203,7 @@ fn embedFiles(comptime paths: []const []const u8) [paths.len]FileEntry {
|
||||
|
||||
/// Build all AddonPrefix entries from embed_modules at comptime.
|
||||
fn buildAllPrefixes() []const AddonPrefix {
|
||||
@setEvalBranchQuota(10000);
|
||||
@setEvalBranchQuota(50000);
|
||||
comptime {
|
||||
// First pass: count total prefix entries
|
||||
var count: usize = 0;
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
-- MinimapIcons addon (embedded in DLL, loaded from memory)
|
||||
-- Takes over the native MiniMapTrackingFrame to add a tracking spell dropdown
|
||||
-- with Wrath-style NPC tracking categories.
|
||||
|
||||
MINIMAPICONS_VERSION = 2
|
||||
|
||||
-- =============================================================================
|
||||
-- Tracking spell definitions grouped by category
|
||||
-- =============================================================================
|
||||
|
||||
local SPELL_CATEGORIES = {
|
||||
{ name = "Hunter Tracking", spells = {
|
||||
"Track Beasts", "Track Humanoids", "Track Undead", "Track Hidden",
|
||||
"Track Elementals", "Track Demons", "Track Giants", "Track Dragonkin",
|
||||
}},
|
||||
{ name = "Class Abilities", spells = {
|
||||
"Sense Undead", "Sense Demons",
|
||||
}},
|
||||
{ name = "Professions", spells = {
|
||||
"Find Herbs", "Find Minerals", "Find Treasure",
|
||||
}},
|
||||
}
|
||||
|
||||
-- NPC tracking categories (icons embedded from Wrath client)
|
||||
-- These don't filter minimap blips yet — future DLL hook work.
|
||||
local NPC_CATEGORIES = {
|
||||
{ name = "Auctioneer", icon = "Interface\\Minimap\\Tracking\\Auctioneer" },
|
||||
{ name = "Banker", icon = "Interface\\Minimap\\Tracking\\Banker" },
|
||||
{ name = "Battle Master", icon = "Interface\\Minimap\\Tracking\\BattleMaster" },
|
||||
{ name = "Class Trainer", icon = "Interface\\Minimap\\Tracking\\Class" },
|
||||
{ name = "Flight Master", icon = "Interface\\Minimap\\Tracking\\FlightMaster" },
|
||||
{ name = "Food & Drink", icon = "Interface\\Minimap\\Tracking\\Food" },
|
||||
{ name = "Innkeeper", icon = "Interface\\Minimap\\Tracking\\Innkeeper" },
|
||||
{ name = "Mailbox", icon = "Interface\\Minimap\\Tracking\\Mailbox" },
|
||||
{ name = "Profession Trainer", icon = "Interface\\Minimap\\Tracking\\Profession" },
|
||||
{ name = "Reagent Vendor", icon = "Interface\\Minimap\\Tracking\\Reagents" },
|
||||
{ name = "Repair", icon = "Interface\\Minimap\\Tracking\\Repair" },
|
||||
{ name = "Stable Master", icon = "Interface\\Minimap\\Tracking\\StableMaster" },
|
||||
{ name = "Ammunition", icon = "Interface\\Minimap\\Tracking\\Ammunition" },
|
||||
}
|
||||
|
||||
-- =============================================================================
|
||||
-- NPC tracking state (persists per session, no SavedVariables)
|
||||
-- =============================================================================
|
||||
|
||||
local activeNpcCategories = {} -- name -> 1/nil
|
||||
|
||||
-- =============================================================================
|
||||
-- Spellbook scanning
|
||||
-- =============================================================================
|
||||
|
||||
local knownSpells = {} -- name -> spellbook index
|
||||
|
||||
local function scanSpellbook()
|
||||
knownSpells = {}
|
||||
local trackable = {}
|
||||
for _, cat in ipairs(SPELL_CATEGORIES) do
|
||||
for _, s in ipairs(cat.spells) do
|
||||
trackable[s] = 1
|
||||
end
|
||||
end
|
||||
local i = 1
|
||||
while GetSpellName(i, BOOKTYPE_SPELL) do
|
||||
local name = GetSpellName(i, BOOKTYPE_SPELL)
|
||||
if trackable[name] then
|
||||
knownSpells[name] = i
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- =============================================================================
|
||||
-- Active tracking detection
|
||||
-- =============================================================================
|
||||
|
||||
local DEFAULT_ICON = "Interface\\Minimap\\Tracking\\None"
|
||||
|
||||
local function isTrackingActive(spellId)
|
||||
local active = GetTrackingTexture()
|
||||
if not active then return nil end
|
||||
if active == GetSpellTexture(spellId, BOOKTYPE_SPELL) then return 1 end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- =============================================================================
|
||||
-- Dropdown menu
|
||||
-- =============================================================================
|
||||
|
||||
local dropdown = CreateFrame("Frame", "MinimapIconsDropDown", UIParent, "UIDropDownMenuTemplate")
|
||||
|
||||
UIDropDownMenu_Initialize(dropdown, function()
|
||||
-- Spell tracking section
|
||||
local hasSpells = nil
|
||||
for _, cat in ipairs(SPELL_CATEGORIES) do
|
||||
local found = {}
|
||||
for _, spell in ipairs(cat.spells) do
|
||||
if knownSpells[spell] then
|
||||
table.insert(found, spell)
|
||||
end
|
||||
end
|
||||
if table.getn(found) > 0 then
|
||||
local title = {}
|
||||
title.text = cat.name
|
||||
title.isTitle = 1
|
||||
title.notCheckable = 1
|
||||
UIDropDownMenu_AddButton(title)
|
||||
|
||||
for _, spell in ipairs(found) do
|
||||
local sid = knownSpells[spell]
|
||||
local info = {}
|
||||
info.text = spell
|
||||
info.icon = GetSpellTexture(sid, BOOKTYPE_SPELL)
|
||||
info.tCoordLeft = 0.0625
|
||||
info.tCoordRight = 0.9
|
||||
info.tCoordTop = 0.0625
|
||||
info.tCoordBottom = 0.9
|
||||
info.checked = isTrackingActive(sid)
|
||||
info.func = function() CastSpell(sid, BOOKTYPE_SPELL) end
|
||||
UIDropDownMenu_AddButton(info)
|
||||
end
|
||||
hasSpells = 1
|
||||
end
|
||||
end
|
||||
|
||||
-- NPC tracking section
|
||||
local npcTitle = {}
|
||||
npcTitle.text = "NPC Tracking"
|
||||
npcTitle.isTitle = 1
|
||||
npcTitle.notCheckable = 1
|
||||
UIDropDownMenu_AddButton(npcTitle)
|
||||
|
||||
for _, cat in ipairs(NPC_CATEGORIES) do
|
||||
local catName = cat.name
|
||||
local info = {}
|
||||
info.text = catName
|
||||
info.icon = cat.icon
|
||||
info.checked = activeNpcCategories[catName]
|
||||
info.keepShownOnClick = 1
|
||||
info.func = function()
|
||||
if activeNpcCategories[catName] then
|
||||
activeNpcCategories[catName] = nil
|
||||
else
|
||||
activeNpcCategories[catName] = 1
|
||||
end
|
||||
end
|
||||
UIDropDownMenu_AddButton(info)
|
||||
end
|
||||
|
||||
-- None option (cancel all tracking)
|
||||
if hasSpells then
|
||||
local none = {}
|
||||
none.text = NONE or "None"
|
||||
none.notCheckable = 1
|
||||
none.func = function() CancelTrackingBuff() end
|
||||
UIDropDownMenu_AddButton(none)
|
||||
end
|
||||
end, "MENU")
|
||||
|
||||
-- =============================================================================
|
||||
-- Take over native MiniMapTrackingFrame
|
||||
-- =============================================================================
|
||||
|
||||
local function updateTrackingIcon()
|
||||
local tex = GetTrackingTexture()
|
||||
if tex then
|
||||
MiniMapTrackingIcon:SetTexture(tex)
|
||||
else
|
||||
MiniMapTrackingIcon:SetTexture(DEFAULT_ICON)
|
||||
end
|
||||
end
|
||||
|
||||
-- Resize to match other minimap button icons (EasyLoot etc.)
|
||||
-- Native: frame 33x33 at TOPLEFT(-15,0), icon 26x26 at TOPLEFT(7,-6), border 64x64 at TOPLEFT
|
||||
-- Shrink border 64->52 (diff 12), shift frame right 6 and down 6 to compensate
|
||||
MiniMapTrackingFrame:SetWidth(32)
|
||||
MiniMapTrackingFrame:SetHeight(32)
|
||||
MiniMapTrackingFrame:ClearAllPoints()
|
||||
MiniMapTrackingFrame:SetPoint("TOPLEFT", Minimap, "TOPLEFT", -9, -6)
|
||||
MiniMapTrackingIcon:ClearAllPoints()
|
||||
MiniMapTrackingIcon:SetWidth(18)
|
||||
MiniMapTrackingIcon:SetHeight(18)
|
||||
MiniMapTrackingIcon:SetPoint("CENTER", MiniMapTrackingFrame, "CENTER", -1, 1)
|
||||
MiniMapTrackingBorder:ClearAllPoints()
|
||||
MiniMapTrackingBorder:SetWidth(52)
|
||||
MiniMapTrackingBorder:SetHeight(52)
|
||||
MiniMapTrackingBorder:SetPoint("TOPLEFT", MiniMapTrackingFrame, "TOPLEFT", 0, 0)
|
||||
|
||||
-- Always show the tracking frame (native hides it when no tracking active)
|
||||
MiniMapTrackingFrame:Show()
|
||||
updateTrackingIcon()
|
||||
|
||||
-- Prevent the native OnEvent from hiding the frame
|
||||
MiniMapTrackingFrame:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_AURAS_CHANGED" then
|
||||
updateTrackingIcon()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Left-click opens dropdown, right-click cancels tracking (native behavior)
|
||||
MiniMapTrackingFrame:SetScript("OnMouseUp", function()
|
||||
if arg1 == "LeftButton" then
|
||||
scanSpellbook()
|
||||
ToggleDropDownMenu(1, nil, dropdown, MiniMapTrackingFrame, 0, 0)
|
||||
elseif arg1 == "RightButton" then
|
||||
CancelTrackingBuff()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Keep native tooltip but add hint text
|
||||
MiniMapTrackingFrame:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(this, "ANCHOR_BOTTOMLEFT")
|
||||
GameTooltip:SetTrackingSpell()
|
||||
if not GetTrackingTexture() then
|
||||
GameTooltip:AddLine("Tracking")
|
||||
end
|
||||
GameTooltip:AddLine("Click to select tracking", 0.5, 0.5, 0.5)
|
||||
GameTooltip:AddLine("Right-click to cancel", 0.5, 0.5, 0.5)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
|
||||
-- =============================================================================
|
||||
-- Events
|
||||
-- =============================================================================
|
||||
|
||||
local events = CreateFrame("Frame")
|
||||
events:RegisterEvent("PLAYER_LOGIN")
|
||||
events:RegisterEvent("SPELLS_CHANGED")
|
||||
events:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
|
||||
events:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_LOGIN" or event == "SPELLS_CHANGED" then
|
||||
scanSpellbook()
|
||||
end
|
||||
MiniMapTrackingFrame:Show()
|
||||
updateTrackingIcon()
|
||||
end)
|
||||
|
||||
-- =============================================================================
|
||||
-- Slash command
|
||||
-- =============================================================================
|
||||
|
||||
SLASH_TRACKING1 = "/tracking"
|
||||
SlashCmdList["TRACKING"] = function()
|
||||
scanSpellbook()
|
||||
ToggleDropDownMenu(1, nil, dropdown, MiniMapTrackingFrame, 0, 0)
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
## Interface: 11200
|
||||
## Title: MinimapIcons
|
||||
## Notes: Minimap tracking spell dropdown
|
||||
## Version: 1.0
|
||||
|
||||
MinimapIcons.lua
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user