AnySCT 0.2.0
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
-- AnySCT menu.lua -- "Mark as targetSCT" in the unit right-click menus (target, party and raid frames;
|
||||
-- pfUI uses the same Blizzard UnitPopup dropdowns). Hooks the 1.12 UnitPopup system:
|
||||
-- UnitPopupButtons / UnitPopupMenus register the button, inserted before CANCEL
|
||||
-- UnitPopup_ShowMenu sets the label: Mark as targetSCT / Unmark targetSCT
|
||||
-- UnitPopup_HideButtons hides the entry for hostile units and non-players
|
||||
-- UnitPopup_OnClick handles our value, everything else goes to the original
|
||||
-- Everything is guarded so a missing menu table or function never errors.
|
||||
|
||||
AnySCT_Menu = {}
|
||||
local M = AnySCT_Menu
|
||||
|
||||
local KEY = "ANYSCT_TOGGLE"
|
||||
-- Menus the client opens for a unit: PLAYER (other players, incl. hostile), PARTY, RAID, FRIEND list.
|
||||
-- NPC targets open "RAID_TARGET_ICON" (the title is the icon list); the key is added to it at
|
||||
-- level 1 only and removed again for the nested icon submenu of the player menus.
|
||||
local MENUS = { "PLAYER", "PARTY", "RAID", "FRIEND" }
|
||||
M.KEY = KEY
|
||||
|
||||
local origShow, origHide, origClick
|
||||
|
||||
-- The name the menu is about: captured when the menu opened (ShowMenu wrapper), else the unit's
|
||||
-- current name. Never dd.name: for NPC targets that is the menu title.
|
||||
local function nameOf(dd)
|
||||
if type(dd) ~= "table" then return nil end
|
||||
if dd.anyName then return dd.anyName end
|
||||
if dd.unit then return UnitName(dd.unit) end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function listed(name)
|
||||
return name ~= nil and AnySCT_Core.state.byName[name] ~= nil
|
||||
end
|
||||
|
||||
function M.Label(name)
|
||||
if listed(name) then return "Unmark targetSCT" end
|
||||
return "Mark as targetSCT"
|
||||
end
|
||||
|
||||
-- true when the entry must not be offered: no name, or the player themself (own events are never shown)
|
||||
function M.Hidden(dd)
|
||||
if type(dd) ~= "table" then return true end
|
||||
local n = nameOf(dd)
|
||||
if n == nil then return true end
|
||||
return n == UnitName("player")
|
||||
end
|
||||
|
||||
-- Add (or remove) the key in the NPC menu depending on the menu level.
|
||||
local function syncIconMenu(which)
|
||||
local menu = UnitPopupMenus["RAID_TARGET_ICON"]
|
||||
if type(menu) ~= "table" then return end
|
||||
local level = UIDROPDOWNMENU_MENU_LEVEL or 1
|
||||
local at
|
||||
for i = 1, table.getn(menu) do
|
||||
if menu[i] == KEY then at = i end
|
||||
end
|
||||
if level == 1 and which == "RAID_TARGET_ICON" then
|
||||
if not at then table.insert(menu, KEY) end
|
||||
elseif at then
|
||||
table.remove(menu, at)
|
||||
end
|
||||
end
|
||||
|
||||
-- Mark / unmark. unit (optional) lets the list learn the GUID of a unit outside the group.
|
||||
function M.Toggle(name, unit)
|
||||
local C = AnySCT_Core
|
||||
if C.state.byName[name] then
|
||||
C.RemoveSource(name)
|
||||
C.Print(name .. " is no longer a targetSCT")
|
||||
else
|
||||
-- what is known about the unit decides the default of the threat switch (pets, mobs and hostile
|
||||
-- players off; players on)
|
||||
local info
|
||||
if unit and UnitIsPlayer and UnitCanAttack then
|
||||
info = { player = UnitIsPlayer(unit) and true or false, friendly = not UnitCanAttack("player", unit) }
|
||||
end
|
||||
C.AddSource(name, "manual", nil, info)
|
||||
if unit and C.SeeUnit then C.SeeUnit(name, unit) end
|
||||
-- no token from the menu (or it did not resolve): look at target / targettarget / mouseover
|
||||
if C.ProbeLoose then C.ProbeLoose() end
|
||||
C.Print(name .. " marked as targetSCT")
|
||||
end
|
||||
end
|
||||
|
||||
local function insertKey(menu)
|
||||
if type(menu) ~= "table" then return end
|
||||
local n = table.getn(menu)
|
||||
local at = n + 1
|
||||
for i = 1, n do
|
||||
if menu[i] == KEY then return end
|
||||
if menu[i] == "CANCEL" then at = i; break end
|
||||
end
|
||||
table.insert(menu, at, KEY)
|
||||
end
|
||||
|
||||
-- Installs the hooks once. Returns true when the UnitPopup tables exist.
|
||||
function M.Install()
|
||||
if M.installed then return true end
|
||||
if type(UnitPopupButtons) ~= "table" or type(UnitPopupMenus) ~= "table" then return false end
|
||||
UnitPopupButtons[KEY] = { text = "Mark as targetSCT", dist = 0 }
|
||||
for i = 1, table.getn(MENUS) do insertKey(UnitPopupMenus[MENUS[i]]) end
|
||||
|
||||
if type(UnitPopup_ShowMenu) == "function" then
|
||||
origShow = UnitPopup_ShowMenu
|
||||
UnitPopup_ShowMenu = function(dropdownMenu, which, unit, name, userData)
|
||||
syncIconMenu(which)
|
||||
local n = unit and UnitName(unit) or ((not unit) and name) or nil
|
||||
if type(dropdownMenu) == "table" then dropdownMenu.anyName = n end
|
||||
UnitPopupButtons[KEY].text = M.Label(n)
|
||||
return origShow(dropdownMenu, which, unit, name, userData)
|
||||
end
|
||||
end
|
||||
if type(UnitPopup_HideButtons) == "function" then
|
||||
origHide = UnitPopup_HideButtons
|
||||
UnitPopup_HideButtons = function()
|
||||
origHide()
|
||||
local dd = getglobal(UIDROPDOWNMENU_INIT_MENU)
|
||||
if type(dd) ~= "table" or type(UnitPopupShown) ~= "table" then return end
|
||||
local menu = UnitPopupMenus[dd.which]
|
||||
if type(menu) ~= "table" then return end
|
||||
for i = 1, table.getn(menu) do
|
||||
if menu[i] == KEY and M.Hidden(dd) then UnitPopupShown[i] = 0 end
|
||||
end
|
||||
end
|
||||
end
|
||||
if type(UnitPopup_OnClick) == "function" then
|
||||
origClick = UnitPopup_OnClick
|
||||
UnitPopup_OnClick = function()
|
||||
if this and this.value == KEY then
|
||||
local dd = getglobal(UIDROPDOWNMENU_INIT_MENU)
|
||||
local n = nameOf(dd)
|
||||
if n then M.Toggle(n, dd.unit) end
|
||||
return
|
||||
end
|
||||
return origClick()
|
||||
end
|
||||
end
|
||||
M.installed = true
|
||||
return true
|
||||
end
|
||||
Reference in New Issue
Block a user