--[[
Questionably Epic Mythic + Dungeon Tips
Version : 5.0 ( Shadowlands )
Developed by : Voulk
Contact :
Discord : Voulk # 1858
Email : itsvoulk @ gmail.com
Special Thanks :
- CoV ( testing & support )
- Everyone who helped test the addon and support the site
--Shorthand--
Defensives { Defensive : SpellName }
Interrupts { Interrupt : SpellName ( SpellEffect ) } , { Stun Interrupt : SpellName ( SpellEffect ) }
Dispels { Dispel : SpellName ( SpellEffect ) } , { Purge : SpellName ( SpellEffect ) }
Positioning : { Spread : When } , { Stack : When } , { Dodge : SpellName ( Area / description ) }
Other : { Frontal Cleave ( opt : tank dodgeable ) } , { Healing CD : SpellName } , { ClassName : Specific Cheese } , { Priority DPS target }
--Examples--
Interrupt : Stone Bolt ( heavy ST nuke )
Defensive : Arcing / Expel Light overlap
Healing CD : Slicing Maelstrom ( every 25 s )
Dispel : Brittle Bones ( inc dmg taken )
Frontal Cleave : Razor Shards ( tank dodgeable )
Druid : Shapeshift the Arcane Lockdown debuff
] ] --
local _ , addon = ... ;
-- Color code information for the different types of tips:
-- Important: Green
-- Interrupt: Orange
-- Healer Note: Light Blue
-- Blank: Default Blizzard color
local tipsColors = {
[ " Legion " ] = { 0.8 , 0.8 , 0.8 } ,
[ " Important " ] = { 1 , 0.59 , 0.14 } ,
[ " Defensives " ] = { 1 , 0.57 , 0.12 } ,
[ " Interrupts " ] = { 0.37 , 0.92 , 1 } ,
[ " Dodge " ] = { 0.54 , 0.81 , 0.94 } ,
[ " PriorityTargets " ] = { 1 , 1 , 0 } ,
[ " Fluff " ] = { 1 , 1 , 1 } ,
[ " Advanced " ] = { 0.75 , 0.55 , 0.35 } ,
[ " HEALER " ] = { 0.2 , 0.98 , 0.25 } ,
[ " TANK " ] = { 0.8 , 0.6 , 0 } ,
[ " DAMAGE " ] = { 1 , 0.72 , 0.68 } ,
--["DEMONHUNTER"] = {0.64, 0.19, 0.79},
[ " DEMONHUNTER " ] = { 0.68 , 0.22 , 0.84 } ,
[ " DRUID " ] = { 1 , 0.49 , 0.04 } ,
[ " DEATHKNIGHT " ] = { 0.77 , 0.12 , 0.23 } ,
[ " HUNTER " ] = { 0.67 , 0.83 , 0.45 } ,
[ " MAGE " ] = { 0.41 , 0.8 , 0.94 } ,
[ " MONK " ] = { 0 , 1 , 0.59 } ,
[ " PALADIN " ] = { 0.96 , 0.55 , 0.73 } ,
[ " PRIEST " ] = { 1 , 1 , 1 } ,
[ " ROGUE " ] = { 1 , 0.96 , 0.41 } ,
[ " SHAMAN " ] = { 0 , 0.44 , 0.87 } ,
[ " WARRIOR " ] = { 0.78 , 0.61 , 0.43 } ,
[ " WARLOCK " ] = { 0.58 , 0.51 , 0.79 }
}
local roleList = {
TANK = true ,
HEALER = true ,
DAMAGE = true ,
}
local classList = {
DEMONHUNTER = true ,
DRUID = true ,
DEATHKNIGHT = true ,
HUNTER = true ,
MAGE = true ,
MONK = true ,
PALADIN = true ,
PRIEST = true ,
ROGUE = true ,
SHAMAN = true ,
WARRIOR = true ,
WARLOCK = true
}
local iconList = {
PriorityTargets = " ability_hunter_markedfordeath " ,
Interrupts = " ability_kick " ,
Defensives = " inv_shield_05 " ,
Important = " ability_dualwield " ,
Legion = " ability_dualwield " ,
Dodge = " ability_dualwield " ,
DEMONHUNTER = " classicon_demonhunter " ,
DRUID = " classicon_druid " ,
DEATHKNIGHT = " classicon_deathknight " ,
HUNTER = " classicon_hunter " ,
MAGE = " classicon_mage " ,
MONK = " classicon_monk " ,
PALADIN = " classicon_paladin " ,
PRIEST = " classicon_priest " ,
ROGUE = " classicon_rogue " ,
SHAMAN = " classicon_shaman " ,
WARRIOR = " classicon_warrior " ,
WARLOCK = " classicon_warlock " ,
HEALER = " spell_nature_healingtouch " ,
TANK = " inv_shield_06 " ,
DAMAGE = " inv_sword_01 "
}
addon.acceptedDungeons = {
-- Shadowlands
[ 595 ] = true , -- Iron Docks
[ 606 ] = true , -- Grimrail Depot
[ 608 ] = true , -- Grimrail Depot
[ 609 ] = true , -- Grimrail Depot
[ 1683 ] = true , -- Theater of Pain
[ 1684 ] = true , -- Theater of Pain
[ 1685 ] = true , -- Theater of Pain
[ 1686 ] = true , -- Theater of Pain
[ 1687 ] = true , -- Theater of Pain
[ 1663 ] = true , -- Halls of Atonement
[ 1664 ] = true , -- Halls of Atonement
[ 1665 ] = true , -- Halls of Atonement
[ 1669 ] = true , -- Mists of Tirna Scithe
[ 1674 ] = true , -- Plaguefall
[ 1697 ] = true , -- Plaguefall
[ 1675 ] = true , -- Sanguine Depths
[ 1676 ] = true , -- Sanguine Depths
[ 1692 ] = true , -- Spires of Ascension
[ 1693 ] = true , -- Spires of Ascension
[ 1694 ] = true , -- Spires of Ascension
[ 1695 ] = true , -- Spires of Ascension
[ 1666 ] = true , -- Necrotic Wake
[ 1667 ] = true , -- Necrotic Wake
[ 1668 ] = true , -- Necrotic Wake
[ 1683 ] = true , -- Theater of Pain
[ 1684 ] = true , -- Theater of Pain
[ 1685 ] = true , -- Theater of Pain
[ 1686 ] = true , -- Theater of Pain
[ 1687 ] = true , -- Theater of Pain
[ 1680 ] = true , -- De Other Side
[ 1678 ] = true , -- De Other Side
[ 1679 ] = true , -- De Other Side
[ 1677 ] = true , -- De Other Side
-- Shadowlands (Torghast)
[ 1618 ] = true ,
[ 1619 ] = true ,
[ 1620 ] = true , -- Torghast
[ 1621 ] = true , -- Torghast
[ 1623 ] = true , -- Torghast
[ 1624 ] = true , -- Torghast
[ 1627 ] = true , -- Torghast
[ 1628 ] = true , -- Torghast
[ 1629 ] = true , -- Torghast
[ 1630 ] = true , -- Torghast
[ 1631 ] = true , -- Torghast
[ 1632 ] = true , -- Torghast
[ 1635 ] = true , -- Torghast
[ 1636 ] = true , -- Torghast
[ 1641 ] = true , -- Torghast
[ 1645 ] = true , -- Torghast
[ 1721 ] = true , -- Torghast
[ 1736 ] = true , -- Torghast
[ 1749 ] = true , -- Torghast
[ 1751 ] = true , -- Torghast
[ 1752 ] = true , -- Torghast
[ 1753 ] = true , -- Torghast
[ 1754 ] = true , -- Torghast
[ 1792 ] = true , -- Torghast
[ 1787 ] = true , -- Torghast
[ 1789 ] = true , -- Torghast
[ 1791 ] = true , -- Torghast
[ 1768 ] = true , -- Torghast
[ 1764 ] = true , -- Torghast
[ 1770 ] = true , -- Torghast
[ 1801 ] = true , -- Torghast
[ 1805 ] = true , -- Torghast
[ 1807 ] = true , -- Torghast
[ 1920 ] = true , -- Torghast
[ 1921 ] = true , -- Torghast
[ 1913 ] = true , -- Torghast
[ 1914 ] = true , -- Torghast
[ 1989 ] = true , -- Tazavesh
[ 1990 ] = true , -- Tazavesh
[ 1991 ] = true , -- Tazavesh
[ 1992 ] = true , -- Tazavesh
[ 1993 ] = true , -- Tazavesh
[ 1994 ] = true , -- Tazavesh
[ 1995 ] = true , -- Tazavesh
[ 1996 ] = true , -- Tazavesh
[ 1997 ] = true , -- Tazavesh
-- BFA
[ 1038 ] = true , -- Temple of Sethraliss
[ 1043 ] = true , -- Temple of Sethraliss
[ 934 ] = true , -- Atal'Dazar (MapUI = 934, instance = 968))
[ 935 ] = true , -- Atal'Dazar (MapUI = 934, instance = 968))
[ 936 ] = true , -- Freehold
[ 1004 ] = true , -- Kings' Rest
[ 1039 ] = true , -- Shrine of the Storm
[ 1040 ] = true , -- Shrine of the Storm
[ 1161 ] = true , -- Siege of Boralus
[ 1162 ] = true , -- Siege of Boralus
[ 1010 ] = true , -- Motherlode
[ 1041 ] = true , -- Underrot
[ 1042 ] = true , -- Tol Dagor
[ 974 ] = true , -- Tol Dagor
[ 975 ] = true , -- Tol Dagor
[ 976 ] = true , -- Tol Dagor
[ 977 ] = true , -- Tol Dagor
[ 978 ] = true , -- Tol Dagor
[ 979 ] = true , -- Tol Dagor (+1169!?)
[ 980 ] = true , -- Tol Dagor
[ 1169 ] = true , -- Tol Dagor
[ 1015 ] = true , -- Waycrest Manor
[ 1016 ] = true , -- Waycrest Manor
[ 1017 ] = true , -- Waycrest Manor
[ 1018 ] = true , -- Waycrest Manor
[ 1148 ] = true , -- Uldir
[ 1149 ] = true , -- Uldir
[ 1150 ] = true , -- Uldir
[ 1151 ] = true , -- Uldir
[ 1152 ] = true , -- Uldir
[ 1153 ] = true , -- Uldir
[ 1154 ] = true , -- Uldir
[ 1155 ] = true , -- Uldir
[ 1490 ] = true , -- Mechagon Junkyard
[ 1491 ] = true , -- Mechagon Workshop
[ 1493 ] = true , -- Mechagon Workshop
[ 1494 ] = true , -- Mechagon Workshop
[ 1497 ] = true , -- Mechagon Workshop
-- Legion
[ 751 ] = true , -- Blackrook Hold
[ 752 ] = true , -- Blackrook Hold
[ 753 ] = true , -- Blackrook Hold
[ 754 ] = true , -- Blackrook Hold
[ 755 ] = true , -- Blackrook Hold
[ 756 ] = true , -- Blackrook Hold
[ 845 ] = true , -- Cathedral of Endless Night
[ 846 ] = true , -- Cathedral of Endless Night
[ 847 ] = true , -- Cathedral of Endless Night
[ 848 ] = true , -- Cathedral of Endless Night
[ 849 ] = true , -- Cathedral of Endless Night
[ 761 ] = true , -- Court of Stars
[ 762 ] = true , -- Court of Stars
[ 763 ] = true , -- Court of Stars
[ 733 ] = true , -- Darkheart Thicket
[ 790 ] = true , -- Eye of Azshara
[ 703 ] = true , -- Halls of Valor
[ 704 ] = true , -- Halls of Valor
[ 705 ] = true , -- Halls of Valor
[ 829 ] = true , -- Halls of Valor
[ 1 ] = true , -- Maw of Souls
[ 731 ] = true , -- Neltharion's Lair
[ 794 ] = true , -- Return to Karazhan
[ 795 ] = true , -- Return to Karazhan
[ 796 ] = true , -- Return to Karazhan
[ 797 ] = true , -- Return to Karazhan
[ 809 ] = true , -- Return to Karazhan
[ 810 ] = true , -- Return to Karazhan
[ 811 ] = true , -- Return to Karazhan
[ 812 ] = true , -- Return to Karazhan
[ 813 ] = true , -- Return to Karazhan
[ 814 ] = true , -- Return to Karazhan
[ 815 ] = true , -- Return to Karazhan
[ 816 ] = true , -- Return to Karazhan
[ 817 ] = true , -- Return to Karazhan
[ 818 ] = true , -- Return to Karazhan
[ 819 ] = true , -- Return to Karazhan
[ 820 ] = true , -- Return to Karazhan
[ 821 ] = true , -- Return to Karazhan
[ 822 ] = true , -- Return to Karazhan
[ 903 ] = true , -- Seat of the Triumvirate
[ 749 ] = true , -- Arcway
[ 677 ] = true , -- Vault of the Wardens
[ 678 ] = true , -- Vault of the Wardens
[ 679 ] = true , -- Vault of the Wardens
[ 710 ] = true , -- Vault of the Wardens
[ 711 ] = true , -- Vault of the Wardens
[ 712 ] = true , -- Vault of the Wardens
-- Dragonflight
[ 429 ] = true , -- Temple of the Jade Serpent
[ 430 ] = true , -- Temple of the Jade Serpent
[ 2094 ] = true , -- Ruby Life Pools
[ 2095 ] = true , -- RLP
[ 2096 ] = true , -- Brackenhide Hollow
[ 2097 ] = true , -- Algeth'ar Academy
[ 2098 ] = true , -- Algeth'ar Academy
[ 2099 ] = true , -- Algeth'ar Academy
[ 2106 ] = true , -- Brackenhide Hollow
[ 2080 ] = true , -- Neltharus
[ 2081 ] = true , -- Neltharus
[ 2071 ] = true , -- Uldaman
[ 2072 ] = true , -- Uldaman
[ 2073 ] = true , -- Azure Vaults
[ 2074 ] = true , -- Azure Vaults
[ 2075 ] = true , -- Azure Vaults
[ 2076 ] = true , -- Azure Vaults
[ 2077 ] = true , -- Azure Vaults
[ 2093 ] = true , -- Nokhud Offensive
[ 574 ] = true , -- Shadowmoon Burial Ground I
[ 576 ] = true , -- Shadowmoon Burial Ground II
[ 2082 ] = true , -- Halls of Infusion
[ 325 ] = true , -- Vortex Pinnacle
[ 2190 ] = true , -- Dawn of the Infinite I
[ 2191 ] = true , -- Dawn of the Infinite I
[ 2192 ] = true , -- Dawn of the Infinite I
[ 2193 ] = true , -- Dawn of the Infinite I
[ 2194 ] = true , -- Dawn of the Infinite I
[ 2195 ] = true , -- Dawn of the Infinite I
[ 2196 ] = true , -- Dawn of the Infinite I
[ 2197 ] = true , -- Dawn of the Infinite I
[ 2198 ] = true , -- Dawn of the Infinite I
[ 2199 ] = true , -- Dawn of the Infinite I
[ 2201 ] = true , -- Dawn of the Infinite I
[ 2202 ] = true , -- Dawn of the Infinite I
[ 2203 ] = true , -- Dawn of the Infinite I
[ 2204 ] = true , -- Dawn of the Infinite I
[ 2205 ] = true , -- Dawn of the Infinite I
[ 2206 ] = true , -- Dawn of the Infinite I
[ 2207 ] = true , -- Dawn of the Infinite I
[ 1 ] = true -- Bookstop
}
local function RGBToHex ( r , g , b )
r = r <= 1 and r >= 0 and r or 0
g = g <= 1 and g >= 0 and g or 0
b = b <= 1 and b >= 0 and b or 0
return string.format ( " %02x%02x%02x " , r * 255 , g * 255 , b * 255 )
end
-- The addline function hooks into the WoW API to add a line to an NPC's tooltip.
local function addLine ( tooltip , tips , type , role , class )
local found = false
-- Check if we already added to this tooltip. This prevents writing the same thing to the tooltip multiple times.
for i = 1 , 15 do
local frame = _G [ tooltip : GetName ( ) .. " TextLeft " .. i ]
local text
if frame then text = frame : GetText ( ) end
if text and text == type then found = true break end
end
-- If we haven't added to the NPC tooltip yet, proceed.
if not found then
-- Remember we are passing in an array {"HEALER", "HealersOnly"}} in our example so we'll iterate through each pair here.
for i , tip in ipairs ( tips ) do
-- tip[1] is the category indicator and we'll use that to decide whether we should show this tooltip or not.
if QEConfig [ tip [ 1 ] ] or tip [ 1 ] == " Legion " or tip [ 1 ] == " Dodge " or -- Show if tip type turned on, or if it's using an old Legion tag.
( tip [ 1 ] == role and QEConfig [ " RoleChoice " ] == " Show my role only " ) or -- Show if role matches the tip, and the user wants to see their role only.
( roleList [ tip [ 1 ] ] and QEConfig [ " RoleChoice " ] == " Show all roles " ) or -- Show if role tip and user wants to see all.
( tip [ 1 ] == class and QEConfig [ " ClassChoice " ] == " Show my class only " ) or
( classList [ tip [ 1 ] ] and QEConfig [ " ClassChoice " ] == " Show all classes " ) then
local r , g , b = tipsColors [ tip [ 1 ] ] [ 1 ] , tipsColors [ tip [ 1 ] ] [ 2 ] , tipsColors [ tip [ 1 ] ] [ 3 ]
if iconList [ tip [ 1 ] ] then -- Check if Icon exists
tooltip : AddLine ( ( ( " |T%s:0|t " ) : format ( " Interface \\ Icons \\ " .. iconList [ tip [ 1 ] ] ) .. tip [ 2 ] ) , r , g , b )
elseif tipsColors [ tip [ 1 ] ] then -- Check if color exists
tooltip : AddLine ( tip [ 2 ] , r , g , b )
else -- There is no icon or color assigned to the category so a plain line will be added instead.
tooltip : AddLine ( tip [ 2 ] )
end
end
end
tooltip : Show ( ) -- This is necessary to actually update the tooltip whenever we add anything to it.
end
end
-- The addline function hooks into the WoW API to add a line to an NPC's tooltip.
local function addFrameLine ( tooltip , tips , type , role , class )
local found = false
-- Check if we already added to this tooltip. This prevents writing the same thing to the tooltip multiple times.
if not QE_HeaderPanel : IsVisible ( ) then addon : setEnabled ( ) end
for i = 1 , 15 do
local frame = _G [ tooltip : GetName ( ) .. " TextLeft " .. i ]
local text
if frame then text = frame : GetText ( ) end
if text and text == type then found = true break end
end
-- If we haven't added to the NPC tooltip yet, proceed.
if not found then
-- Remember we are passing in an array {"HEALER", "HealersOnly"}} in our example so we'll iterate through each pair here.
for i , tip in ipairs ( tips ) do
-- tip[1] is the category indicator and we'll use that to decide whether we should show this tooltip or not.
if QEConfig [ tip [ 1 ] ] or tip [ 1 ] == " Legion " or tip [ 1 ] == " Dodge " or -- Show if tip type turned on, or if it's using an old Legion tag.
tip [ 1 ] == " HEALER " or tip [ 1 ] == " TANK " or tip [ 1 ] == " DPS " or
--(tip[1] == role and QEConfig["RoleChoice"] == "Show my role only") or -- Show if role matches the tip, and the user wants to see their role only.
--(roleList[tip[1]] and QEConfig["RoleChoice"] == "Show all roles") or -- Show if role tip and user wants to see all.
( tip [ 1 ] == class and QEConfig [ " ClassChoice " ] == " Show my class only " ) or
( classList [ tip [ 1 ] ] and QEConfig [ " ClassChoice " ] == " Show all classes " ) then
local r , g , b = tipsColors [ tip [ 1 ] ] [ 1 ] , tipsColors [ tip [ 1 ] ] [ 2 ] , tipsColors [ tip [ 1 ] ] [ 3 ]
local lineHex = RGBToHex ( r , g , b )
local tipBase = QE_TipText : GetText ( ) or " "
if iconList [ tip [ 1 ] ] then -- Check if Icon exists
--tooltip:AddLine((("|T%s:0|t"):format("Interface\\Icons\\"..iconList[tip[1]])..tip[2]),r,g,b)
QE_TipText : SetText ( tipBase .. ( ( ( " |T%s:0|t " ) : format ( " Interface \\ Icons \\ " .. iconList [ tip [ 1 ] ] ) .. " |cff " .. lineHex .. " " .. tip [ 2 ] .. " |r " .. " \n " ) ) )
elseif tipsColors [ tip [ 1 ] ] then -- Check if color exists
QE_TipText : SetText ( tipBase .. " |cff " .. lineHex .. " " .. tip [ 2 ] .. " |r " .. " \n " )
--tooltip:AddLine(tip[2],r,g,b)
else -- There is no icon or color assigned to the category so a plain line will be added instead.
QE_TipText : SetText ( tipBase .. " " .. tip [ 2 ] .. " \n " )
--tooltip:AddLine(tip[2])
end
end
end
--tooltip:Show() -- This is necessary to actually update the tooltip whenever we add anything to it.
end
end
-- The addline function hooks into the WoW API to add a line to an NPC's tooltip.
local function addLineNew ( tooltip , data )
if C_PetBattles.IsInBattle ( ) then return end -- Tiny Snippet to disable the mod while pet battling.
if QEConfig.ShowFrame == " Show in separate frame " and QEConfig.TargetTrigger == " Show targeted mob " then return end -- Tiny Snippet to disable the tooltip hook if targeting is selected instead.
if QEConfig.ShowFrame == " Show in separate frame " and QEConfig.TargetTrigger == " Show mouseover " and QE_onBoss then return end -- Disable tooltip hook if player is using frame + Mouseover but is on boss
if not addon : checkInstance ( ) then return end -- We won't be adding anything to tooltips if the addon is disabled in the current instance.
local role = UnitGroupRolesAssigned ( " player " )
local _ , class , _ = UnitClass ( " player " )
if data then
local guid = data.guid or " "
local id = tonumber ( guid : match ( " -(%d+)-%x+$ " ) , 10 ) -- This is the mobs ID. Don't worry about the regex.
local name = data.lines [ 1 ] . leftText or " "
-- Check our dictionary to see if we actually have any tips for the mob targeted.
if tipsMap [ id ] then
-- Don't remove active tip if you accidentally mouse over ally.
QE_TipText : SetText ( " " )
QE_MobName : SetText ( name )
if QEConfig.ShowFrame == " Show in separate frame " then addFrameLine ( QE_TipPanel , tipsMap [ id ] , " NPC ID: " , role , class )
else addLine ( tooltip , tipsMap [ id ] , " NPC ID: " , role , class )
end
elseif UnitIsEnemy ( guid , " player " ) then
QE_TipText : SetText ( " " )
QE_MobName : SetText ( name )
end
end
end
-- This starts the ball rolling. This function is called whenever an NPC tooltip is moused over.
--GameTooltip:HookScript("OnTooltipSetUnit", function(self)
TooltipDataProcessor.AddTooltipPostCall ( Enum.TooltipDataType . Unit , addLineNew )
-- This starts the ball rolling on a mob target.
function addon : getTarget ( mobType )
if C_PetBattles.IsInBattle ( ) then return end -- Tiny Snippet to disable the mod while pet battling.
local guid = UnitGUID ( mobType ) -- This grabs information about the unit we have targeted.
local role = UnitGroupRolesAssigned ( " player " )
local _ , class , _ = UnitClass ( " player " )
--print("GUID: " .. UnitGUID("boss1"))
if guid then
--local guid = UnitGUID(unit) or ""
local id = tonumber ( guid : match ( " -(%d+)-%x+$ " ) , 10 ) -- This is the mobs ID. Don't worry about the regex.
local name = UnitName ( mobType ) or " "
-- Check our dictionary to see if we actually have any tips for the mob targeted.
if tipsMap [ id ] then
-- Don't remove active tip if you accidentally mouse over ally.
QE_TipText : SetText ( " " )
QE_MobName : SetText ( name )
addFrameLine ( QE_TipPanel , tipsMap [ id ] , " NPC ID: " , role , class )
--addLine(GameTooltip, tipsMap[id], "NPC ID:", role, class)
elseif UnitIsEnemy ( mobType , " player " ) then
QE_TipText : SetText ( " " )
QE_MobName : SetText ( name )
end
end
end