Please note, all the QuickHealth modules currently available use Quickhealth-1.0, they will be upgraded eventualy.
Features:
LibQuickHealth-2.0 is a library that provides more up to date health data than the default Blizz events and functions.
In addition to the standard UNIT_HEALTH event, the library listens to combat log events (CLEU) to update health values.
CLEU events fire more often than UNIT_HEALTH, and allow the library to get around the ~300ms throttling of UNIT_HEALTH updates.
The interesting CLEU events are those containing health differences (damage and heals). Normally, when UNIT_HEALTH fires,
those differences add up to the value reported by Blizz's UnitHealth. But sometimes, when a unit takes damage according to the CLEU,
that damage is processed *after* the next UNIT_HEALTH event.
This is called "pending damage". One of the features of LibQuickHealth-2.0 (and an improvement over 1.0) is to detect pending damage,
and incorporate it into the health values that are presented to players.
Limitations:
1.) Sometimes there are combat log entries like this: -6000 (damage), +5000 (heal).
But what really happened on the server was that the heal occured first.
If at least part of this heal was overheal, the prediction (-6000+5000 = -1000) is way off,
because what happened is for example +50 heal first(4950 overheal), and then 6000 damage,
for a total of +50-6000 = -5950. No AddOn could possibly prevent or predict this, but luckily these cases are very rare.
However, if you see something like this happening (tank at ~100%, then takes damage instantly followed by a heal),
you should know that this heal might have been overheal. So don't cancel your heal. ;)
2.) If the maximum health changes, pending damage is completely ignored. Example: The tank is at 11001/18000,
takes 9001 damage and uses Last Stand at the same time.
Your client might tell you now that the tank health is 16401/23400 (+30% health and max health),
because that 9k hit was not yet processed (pending damage).
What the library does is: Show the tank at 11001/18000, then at 11001-9001 = 2000/18000, then at 16401/23400,
because pending damage is ignored. But on the server, the tank has only 16401-9001 = 7400/23400 health!
This looks very similar to the case before: The tank takes damage, but shortly afterwards that damage is (magically) undone.
Again, if you see this, don't cancel your heal!
3.) Bloodrush. There's no combat log entry for the health lost.
I believe the health cost depends on the caster level and race, but I don't know the exact formula.
4.) Exceptionally large HP5 values. There are no combat log entries for HP5 ticks, which occur every 2 seconds.
The library assumes that the health regen in combat is between 0 and 50 HP5, i.e. HP5 ticks between 0 and 20.
Common HP5 values: Demon skin/armor <=18 (24 talented?), Elixir of Major Fortitude 10, Enchant Boots - Vitality 4.
Less common: Dreaming Glory 30 (buff from herbalism), and a few level 60 items.
So the library might get confused by two things: Small amounts of pending damage (20 or less), and Warlocks with herbalism...
Usage:
The library supports two events, UnitHealthUpdated and HealthUpdated.
The difference is that HealthUpdated fires for
guids, and UnitHealthUpdated fires for unitIDs.
UnitHealthUpdated replaces not only UNIT_HEALTH, but also UNIT_MAXHEALTH.
That means even if only the max health changes (but not the health),
UnitHealthUpdated (and HealthUpdated) will fire. QuickHealth.UnitHealth replaces Blizz's UnitHealth. See example 2 below.
To start listening to the event, do QuickHealth.RegisterCallback(YourAddonTableHere, "HealthUpdated", HandlerMethodHere).
The "HealthUpdated" callback triggers with 5 arguments: self, event, guid, health, healthMax (first two passed by the callbackhandler).
The "UnitHealthUpdated" callback triggers with 5 arguments: self, event, unitID, health, healthMax.
Additionaly, QuickHealth.UnitHealth(unitID) can be called to get what QuickHealth thinks is the current health.
Example 1: Using UnitHealthUpdated.
local QuickHealth = LibStub("LibQuickHealth-2.0")
local MyAddon = {}
function MyAddon:Initialize()
-- Note: It's QuickHealth.RegisterCallback(), not QuickHealth:RegisterCallback().
QuickHealth.RegisterCallback(MyAddon, "UnitHealthUpdated", "UnitHealthUpdated")
end
function MyAddon:UnitHealthUpdated(event, unitID, health, healthMax)
assert(event == "UnitHealthUpdated")
ChatFrame1:AddMessage(format("%s HealthUpdated %i/%i", unitID, health, healthMax))
assert(health==QuickHealth.UnitHealth(unitID))
end
Example 2: Making LibQuickHealth an optional dependency.
local QuickHealth = LibStub and LibStub("LibQuickHealth-2.0", true) -- don't error if not found
local UnitHealth = QuickHealth and QuickHealth.UnitHealth or UnitHealth
MyAddon = ...
function MyAddon:Initialize()
if QuickHealth then
-- Add QuickHealth support. Register for the event and add a simple adapter method.
QuickHealth.RegisterCallback(MyAddon, "UnitHealthUpdated", "UnitHealthUpdated")
function MyAddon:UnitHealthUpdated(event, unitID)
self:UpdateStuff(unitID)
end
else
-- Assuming it's an Ace addon.
MyAddon:RegisterEvent("UNIT_HEALTH", "UpdateStuff")
MyAddon:RegisterEvent("UNIT_MAXHEALTH", "UpdateStuff")
end
end
function MyAddon:UpdateStuff(unitID)
local hp, max = UnitHealth(unitID), UnitHealthMax(unitID)
-- do something with hp and max
end
Example 3: Using HealthUpdated.
local QuickHealth = LibStub("LibQuickHealth-2.0")
local MyAddon = {}
function MyAddon:Initialize()
QuickHealth.RegisterCallback(MyAddon, "HealthUpdated", "HealthUpdated")
end
function MyAddon:HealthUpdated(event, guid, health, healthMax)
assert(event == "HealthUpdated")
ChatFrame1:AddMessage(format("%s HealthUpdated %i/%i", guid, health, healthMax))
end
Lets say I include this with my addon, and it is the only unit frame running. If the user doesn't want fast updates, can the events of this lib be unregistered so that it doesn't use cpu/mem? I might be more inclined to include a separate implementation of this, because I would have better control over when it was enabled or disabled.
Lets say I include this with my addon, and it is the only unit frame running. If the user doesn't want fast updates, can the events of this lib be unregistered so that it doesn't use cpu/mem? I might be more inclined to include a separate implementation of this, because I would have better control over when it was enabled or disabled.
It uses CallbackHandler-1.0 to do its updates. But even if nothing is registered on it, it will still listen to combatlog events and update its internal values. The cpu & memory taken is minimal though, its just doing some very basic maths.
edit: I'd suggest adding support for it as a seperate module instead of builtin, for maximum control of what its doing.
edit2: I think I misunderstoof what you mean, yes , the events can be unregistered using UnregisterCallback.
to me it looks like MSBT is about 0.2-0.5 sec after. :/
its possible MSBT throttles events to group them together, if it does there should be a setting to disable that :p (should ask that in the MSBT thread though)
How does this compare to the Instant health addon? Mostly performance vise :P
I haven't done any benchmarks personaly, but I think it'd be faster as it doesn't have to loop through all frames that have the UNIT_HEALTH event registered to forcably trigger it. (this is pure speculation however)
Doesn't seem to work with the latest version of Xperl, though the release notes say it should. In fact, the health bar of the target frame doesn't move with quickhealth installed until the mob is dead lol.
Features:
LibQuickHealth-2.0 is a library that provides more up to date health data than the default Blizz events and functions.
In addition to the standard UNIT_HEALTH event, the library listens to combat log events (CLEU) to update health values.
CLEU events fire more often than UNIT_HEALTH, and allow the library to get around the ~300ms throttling of UNIT_HEALTH updates.
The interesting CLEU events are those containing health differences (damage and heals). Normally, when UNIT_HEALTH fires,
those differences add up to the value reported by Blizz's UnitHealth. But sometimes, when a unit takes damage according to the CLEU,
that damage is processed *after* the next UNIT_HEALTH event.
This is called "pending damage". One of the features of LibQuickHealth-2.0 (and an improvement over 1.0) is to detect pending damage,
and incorporate it into the health values that are presented to players.
Limitations:
1.) Sometimes there are combat log entries like this: -6000 (damage), +5000 (heal).
But what really happened on the server was that the heal occured first.
If at least part of this heal was overheal, the prediction (-6000+5000 = -1000) is way off,
because what happened is for example +50 heal first(4950 overheal), and then 6000 damage,
for a total of +50-6000 = -5950. No AddOn could possibly prevent or predict this, but luckily these cases are very rare.
However, if you see something like this happening (tank at ~100%, then takes damage instantly followed by a heal),
you should know that this heal might have been overheal. So don't cancel your heal. ;)
2.) If the maximum health changes, pending damage is completely ignored. Example: The tank is at 11001/18000,
takes 9001 damage and uses Last Stand at the same time.
Your client might tell you now that the tank health is 16401/23400 (+30% health and max health),
because that 9k hit was not yet processed (pending damage).
What the library does is: Show the tank at 11001/18000, then at 11001-9001 = 2000/18000, then at 16401/23400,
because pending damage is ignored. But on the server, the tank has only 16401-9001 = 7400/23400 health!
This looks very similar to the case before: The tank takes damage, but shortly afterwards that damage is (magically) undone.
Again, if you see this, don't cancel your heal!
3.) Bloodrush. There's no combat log entry for the health lost.
I believe the health cost depends on the caster level and race, but I don't know the exact formula.
4.) Exceptionally large HP5 values. There are no combat log entries for HP5 ticks, which occur every 2 seconds.
The library assumes that the health regen in combat is between 0 and 50 HP5, i.e. HP5 ticks between 0 and 20.
Common HP5 values: Demon skin/armor <=18 (24 talented?), Elixir of Major Fortitude 10, Enchant Boots - Vitality 4.
Less common: Dreaming Glory 30 (buff from herbalism), and a few level 60 items.
So the library might get confused by two things: Small amounts of pending damage (20 or less), and Warlocks with herbalism...
Usage:
The library supports two events, UnitHealthUpdated and HealthUpdated.
The difference is that HealthUpdated fires for
guids, and UnitHealthUpdated fires for unitIDs.
UnitHealthUpdated replaces not only UNIT_HEALTH, but also UNIT_MAXHEALTH.
That means even if only the max health changes (but not the health),
UnitHealthUpdated (and HealthUpdated) will fire. QuickHealth.UnitHealth replaces Blizz's UnitHealth. See example 2 below.
To start listening to the event, do QuickHealth.RegisterCallback(YourAddonTableHere, "HealthUpdated", HandlerMethodHere).
The "HealthUpdated" callback triggers with 5 arguments: self, event, guid, health, healthMax (first two passed by the callbackhandler).
The "UnitHealthUpdated" callback triggers with 5 arguments: self, event, unitID, health, healthMax.
Additionaly, QuickHealth.UnitHealth(unitID) can be called to get what QuickHealth thinks is the current health.
Example 1: Using UnitHealthUpdated.
Example 2: Making LibQuickHealth an optional dependency.
Example 3: Using HealthUpdated.
Correct :D
It uses CallbackHandler-1.0 to do its updates. But even if nothing is registered on it, it will still listen to combatlog events and update its internal values. The cpu & memory taken is minimal though, its just doing some very basic maths.
edit: I'd suggest adding support for it as a seperate module instead of builtin, for maximum control of what its doing.
edit2: I think I misunderstoof what you mean, yes , the events can be unregistered using UnregisterCallback.
MSBT should be using the combatlog just like QuickHealth is, so they should update at the exact same moment in theory.
to me it looks like MSBT is about 0.2-0.5 sec after. :/
its possible MSBT throttles events to group them together, if it does there should be a setting to disable that :p (should ask that in the MSBT thread though)
I haven't done any benchmarks personaly, but I think it'd be faster as it doesn't have to loop through all frames that have the UNIT_HEALTH event registered to forcably trigger it. (this is pure speculation however)
the Grid Download Link doesn't work :/
fixed
can you link it ? I'll add it to the main thread
It works for all languages
libQuickHealth-1.0 ⇒ LibQuickHealth-1.0