H.H.T.D.
H.H.T.D.
In World of Warcraft healers have to die (H.H.T.D). This is a cruel truth that you're taught very early in the game. This add-on helps you influence this unfortunate destiny in a way or another depending on the healer's side...
This add-on is now known as H.H.T.D.
I originally chose the original name as a provocation to make one of the basic cruel truths of World of Warcraft perfectly obvious to everyone. Now I find this name too harsh, too long and mostly not specific enough to WoW.
As an author I could not stand that name anymore. This add-on does have an existence (and meaning) both in WoW and in the real world where obviously we don't want the death of our beloved healers...
While H.H.T.D is just an acronym of the original name, it will stay in World of Warcraft where it belongs.
Current features:
HHTD automatically adds healer symbols on top of players nameplate indicating their class and healing rank. Unlike other add-ons it only takes into account actively healing players. (It uses different symbols for friends and foes).
HHTD lets you apply custom marks on top of any unit's nameplate. These are the same marks as the default raid markers but you can set as many as you want and customize their look. These marks persist across game sessions. (They are only visible to you)
IMPORTANT NOTE: You have to enable nameplates, else you won't see any healer symbol!
HHTD lets you announce through a customizable message who the enemy and friendly healers are (using the Raid Warning channel if possible).
It will also help you protect the healers who are on your side alerting you when they are being attacked (check the option panel for details).
Helps you target healers easily when they are in a pack.
All of this applies to PVP and PVE.
NOTE: Type /HHTDG to open the configuration panel. There are many settings to check!
HHTD's options are not directly available in the "Interface" panel due to ongoing tainting issues Blizzard is not willing to fix.
That player is not a healer?
If you see a player marked as healer that should not be:
If their mark's background is NOT grey, check the 'Logging' option in the option panel (/HHTDG) ; then when you see such a player, reopen the option panel and check the content of the 'Logs' tab and report to me by opening a ticket. Please avoid comments on Curse.com as it's impossible to follow what happens there).
If their mark's background is grey then enable the 'Healer specialization detection' option so as to only report specialized healers ignoring others.
Also note that the healer's rank is displayed as a number in the center of the displayed mark so you can judge the importance of that player in the healing currently being done (the lower the number, the better the healer).
How it works
HHTD uses the combat log events to detect friendly and enemy healers who are currently healing other players (during the last 60s). HHTD detects specialized healers spells (for human players only) and differentiates specialized healers from hybrid ones.
HHTD also lets you choose a specified amount of healing healers have to reach before being marked as such (50% of your own health by default). This threshold is the only criterion used for NPCs.
When a healer is identified it will be marked with a healer symbol above their nameplate. If the healer is specialized, the symbol's background will be colored according to their class. In other cases the background will be grey.
In all cases a number in the center of the symbol indicates the rank of the healer, the lowest the number the better the healer (ie: '1' represents the most effective healer while '9' is the least effective).
You can force HHTD to only report specialized healers through HHTD's options (/hhtdg).
Needless to say that self-heals and heals to pets are filtered out.
Commands
/HHTDP (or /hhtdp) posts healers name to the raid channel ordered by effectiveness for all to see (Will use the Raid Warning channel if possible).
You need to configure the messages in the announce module options first.
You can bind the above command to a key (WoW key-bindings interface)
/HHTDG opens option panel
/HHTD gives you access to the command line configuration interface (useful for changing settings through macros...)
Planned features
- Detection when a friendly healer is being attacked and alert others through /yell, /say and emote.
Compatibility
HHTD is only compatible with nameplate add-ons which have been coded responsibly and do not modify internal parts of Blizzard nameplates (a very selfish behaviour as it prevents any other add-on from re-using them).
HHTD will detect these incompatibilities and report to you so that you can ask the culprit add-on authors to fix their code and make it compatible with ALL nameplate add-ons.
Guidelines for other add-on authors:
Do not call :Hide() or :Show() on nameplates' base frame. This breaks nameplate tracking for other add-ons by unduly firing OnHide/OnShow hooks...
Instead, make its sub-frames invisible by changing their size and/or setting them to the empty (not nil) texture. (check out how TidyPlates does)
Do not call :SetParent() on nameplates' subframes, this would prevent other add-ons from finding and hooking nameplate elements.
Do not use SetScript() EVER. You don't need it. :SetScript() shall only be used on frames YOU create. You can simply replace all your SetScript() calls by HookScript().
Videos
Here is a video by Hybridpanda featuring HHTD in the Eye of the Storm battleground:
YouTube - This makes me a sad Panda
Articles
Here are two excellent articles about HHTD by Cynwise (A must read if you have some doubts about the fairness of this add-on!) :
HHTD and the PvP Addons Arms Race
Using HHTD to Protect Friendly Healers
Here is another article written by Gevlon (a PVP healer).
type /hhtdg to open the configuration interface, or /hhtd for command-line access
Comments and suggestions are welcome :-)
To report issues or ask for new features, use the ticket system.
Bitcoin donation address: 1JkA5Ns1dMQLM4D8HUsbXyka6yhp312KnN
This add on is great, and it's heartbreaking that it's not compatible with 10.1! could we please get an update!
i use this and works fine but one question. i use the minimal design, so i see a small cross in class color.
is it possible to make fix colored depends on friendly or enemy healer? so friendly is always green, enemy always red, ignoring the class?
EDIT: Found out that the "normal" Cross Style change color the same way to classes with a little cross in white for friendly and red for enemy healer.
Can you make a check box or so to disable class coloring? I just want a red cross for enemy and green(or maybe white) for friendly.
In reply to ex2j:
Yes this is possible, please create an issue so I do not forget: https://www.wowace.com/projects/h-h-t-d/issues
this is currently causing lua errors, seems to be something with nameplates.
In reply to Yawhatever:
Could you copy/paste such a Lua error here please?
In reply to archarodim:
this is just sitting in valdrakken, not in instance, warmod off, does pretty much the same elsewhere though.
Message: ...ibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:348: attempt to compare number with nil
Time: Fri Jan 6 13:13:48 2023
Count: 2
Stack: ...ibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:348: attempt to compare number with nil
[string "@Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua"]:348: in function `RawGetPlateType'
[string "@Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua"]:499: in function `?'
[string "@Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua"]:883: in function <...ibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:882>
Locals: frame = NamePlate4 {
OnSizeChanged = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:587
driverFrame = NamePlateDriverFrame {
}
GetPreferredInsets = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:568
GetAdditionalInsetPadding = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:557
ApplyOffsets = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:539
namePlateUnitToken = "nameplate4"
OnRemoved = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:526
OnAdded = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:515
UnitFrame = Button {
}
template = "NamePlateUnitFrameTemplate"
0 = <userdata>
OnOptionsUpdated = <function> defined @Interface/AddOns/Blizzard_NamePlates/Blizzard_NamePlates.lua:533
}
unitToken = "nameplate4"
reaction = nil
(*temporary) = "player"
(*temporary) = "nameplate4"
(*temporary) = nil
(*temporary) = nil
(*temporary) = "attempt to compare number with nil"
LNR_Private = <table> {
NAME_PLATE_UNIT_REMOVED = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:529
FatalIncompatibilityError = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:1105
callbacks = <table> {
}
Quit = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:1058
GetUnitTokenFromPlate = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:267
NAME_PLATE_UNIT_ADDED = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:462
Ticker = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:894
PLAYER_TARGET_CHANGED = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:587
UnregisterAllCallbacks = <function> defined @Interface/AddOns/DBM-Core/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:164
Enable = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:942
RawGetPlateName = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:330
UPDATE_MOUSEOVER_UNIT = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:607
UsedCallBacks = 8
EventFrame = Frame {
}
OnEvent = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:882
mixinTargets = <table> {
}
RegisterCallback = <function> defined @Interface/AddOns/DBM-Core/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:80
RawGetPlateType = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:342
ValidateCache = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:383
UnregisterCallback = <function> defined @Interface/AddOns/DBM-Core/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:143
PLAYER_REGEN_ENABLED = <function> defined @Interface/AddOns/HHTD/Libs/LibNameplateRegistry-1.0/LibNameplateRegistry-1.0.lua:581
IsPlateTa
In reply to Yawhatever:
Thanks, this is fixed in the latest release
Can it work on arena?
Any updates coming for retail or wow classic`?
Hello!
I am just writing this message to humbly request that you also post this addon on either: https://www.wowinterface.com/downloads/index.php or https://addons.wago.io
This is due to the recent Curseforge policy of restricting their API from the Wowup addon manager. If you can't be bothered to do this, I will be happy to post it for you (with your permission). Thanks!
I'm not going to make a ticket about it, I'm just going to state that for the few years I've had this addon, for about a year now when a Ret pally heals, he gets a pink healing icon over his head, same with ele and enhance shammys, ww monks, etc. It wasn't always like that, it still helps to identify the healer except I have to pay attention to their abilities to make sure they are actually healers. Just seems a bit broken and i cant fix it for quite some time.
In reply to georgia226:
You can actually help by commenting on this page: https://www.wowace.com/projects/h-h-t-d/pages/specialized-healers-spells and identify the spells that should be updated.
Any possibility to be able to adjust the offsets for friendly and enemy players separately as opposed to the current set up which applies to both? Would be helpful for nameplates that are configured to display differently for friend/foe (i.e. size differences of their plates, or location of their buffs/debuffs). Not sure how hard this would be to do.
Broke in TBC beta and PTR with pre patch. Lot of errors.
Message: Interface\AddOns\HHTD\Core.lua:149: attempt to call global 'GetSpecializationInfoForClassID' (a nil value)
Time: Sat May 15 17:00:20 2021
Count: 1
Stack: Interface\AddOns\HHTD\Core.lua:149: attempt to call global 'GetSpecializationInfoForClassID' (a nil value)
[string "@Interface\AddOns\HHTD\Core.lua"]:149: in main chunk
Locals: ERROR = 1
WARNING = 2
INFO = 3
INFO2 = 4
UNPACKAGED = "@project-version@"
VERSION = "2.4.9.7"
ADDON_NAME = "HHTD"
T = <table> {
_MessageBox = <function> defined @Interface\AddOns\HHTD\Core.lua:70
HHTD = <table> {
}
_FatalError = <function> defined @Interface\AddOns\HHTD\Core.lua:44
_tocversion = 20501
}
_ = "2.5.1"
_ = "38677"
_ = "May 14 2021"
tocversion = 20501
HHTD = <table> {
SetDefaultModuleLibraries = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:367
Enable = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:294
RegisterChatCommand = <function> defined @Interface\AddOns\Dominos\libs\AceConsole-3.0\AceConsole-3.0.lua:85
EnableModule = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:332
modules = <table> {
}
GetModule = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:210
IterateEmbeds = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:442
defaultModuleLibraries = <table> {
}
TimeLeft = <function> defined @Interface\AddOns\HHTD\Libs\AceTimer-3.0\AceTimer-3.0.lua:172
UnregisterChatCommand = <function> defined @Interface\AddOns\Dominos\libs\AceConsole-3.0\AceConsole-3.0.lua:111
ScheduleRepeatingTimer = <function> defined @Interface\AddOns\HHTD\Libs\AceTimer-3.0\AceTimer-3.0.lua:129
CancelAllTimers = <function> defined @Interface\AddOns\HHTD\Libs\AceTimer-3.0\AceTimer-3.0.lua:160
Printf = <function> defined @Interface\AddOns\Dominos\libs\AceConsole-3.0\AceConsole-3.0.lua:69
SetDefaultModulePrototype = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:409
name = "H.H.T.D."
IsEnabled = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:451
orderedModules = <table> {
}
ScheduleTimer = <function> defined @Interface\AddOns\HHTD\Libs\AceTimer-3.0\AceTimer-3.0.lua:94
DisableModule = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:350
RegisterMessage = <function> defined @Interface\AddOns\Bagnon\common\Wildpants\libs\CallbackHandler-1.0\CallbackHandler-1.0.lua:90
GetArgs = <function> defined @Interface\AddOns\Dominos\libs\AceConsole-3.0\AceConsole-3.0.lua:144
Print = <function> defined @Interface\AddOns\Dominos\libs\AceConsole-3.0\AceConsole-3.0.lua:54
IsModule = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:468
SetDefaultModuleState = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:387
SetEnabledState = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:424
Constants = <table> {
}
enabledState = true
CancelTimer = <function> defined @Interface\AddOns\HHTD\Libs\AceTimer-3.0\AceTimer-3.0.lua:147
RegisterEvent = <function> defined @Interface\AddOns\Bagnon\common\Wildpants\libs\CallbackHandler-1.0\CallbackHandler-1.0.lua:90
UnregisterAllMessages = <function> defined @Interface\AddOns\Bagnon\common\Wildpants\libs\CallbackHandler-1.0\CallbackHandler-1.0.lua:174
Localized_Text = <table> {
}
UnregisterAllEvents = <function> defined @Interface\AddOns\Bagnon\common\Wildpants\libs\CallbackHandler-1.0\CallbackHandler-1.0.lua:174
SendMessage = <function> defined @Interface\AddOns\Bagnon\common\Wildpants\libs\CallbackHandler-1.0\CallbackHandler-1.0.lua:59
IterateModules = <function> defined @Interface\AddOns\Dominos\libs\AceAddon-3.0\AceAddon-3.0.lua:437
UnregisterMessage = <function> defined @Interface\AddOns\Bagnon\common\Wildpants\libs\CallbackHandler-1.0\CallbackHandler-1.0.lua:153
NewModule = <function> defined @Interface\Ad
Hey, thanks for the great addon. Is there a way to disable everything for friendly heals? I have a really hard time to target enemy healers with this addon in a big 40vs40 zerg where everyone is on one spot. Woul love to disable the friendly heal markers and only see enemy ones, is that possible? Tried pretty much every options, but it does not work. I do not want to disable the friendly nameplates at all, only the heal mark from HHTD...... :-D
In reply to TheKingOfKingz2109:
This is impossible by design. Killing enemy healers is as important as protecting the friendly ones.
Hi. Awesome addon. Been using it forever.
I have a suggestion.
I have a neurodegenerative sickness and it is advancing and I have problem selecting targets with mouse. In heavy combat BG's when I try to click with mouse a healer tagged by your mod I am usually dead. So if there could be an optional component that allows me to see the healer in the target screen. I dont know if possible of course. Can you rename the target name and add an prefix [healer].
In reply to ranafuineluva:
What do you mean by "see the healer in the target screen"? HHTD already adds a mark above the healer plate and you can move this mark through the options (/hhtdg).
I'm sorry about your advancing neurodegenerative disease, I hope your body will find a way to heal itself.
In reply to archarodim:
Thanks mate. Is it possible to add some kind of mark like Raid markers on target frame?
In reply to ranafuineluva:
You mean the frame that appears once you've selected a target? I'm not sure if that is possible, I'll have to check...
HHTD also has a sound option that validates that you did target a healer, I don't remember if it's enabled by default, it might also help you.