View Single Post
05-27-11, 05:25 PM   #6
hankthetank
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Jul 2009
Posts: 64
i'll try to clear things up.

the basic strategy that would work for every unit is to save the unit id of the nameplate whenever it is possible for you to retrieve as this is what you will compare to when you receive an unfiltered combatlog event for a cast.

you will only get the unit id for a nameplate unit on two occasions (feel free to correct me here but i don't see another possibility for this):
  • you mouseover a nameplate, that means you mouseover a unit and can access the unitid "mouseover". listen to the UPDATE_MOUSEOVER_UNIT event to let wow inform you thusly.
  • you target an unit (unitid "target") that is currently represented by nameplate.

now you will need the scan for the nameplate that corresponds the unit you just retrieved if there is any. so you iterate through all nameplates and check them:
  • when you mouseover a unit there is this one overlay region for the matching nameplate that is shown (the one when the healthbar lightens up). here is the signature for nameplate regions:

    lua Code:
    1. aggro, border, hover, name, level, boss, raidTarget, elite = frame:GetRegions()

    the one you are looking for is hover. when you find a nameplate in your scan where this texture IsShown() you know it matches unitid "mouseover".
  • when you target something all nameplates but the one of the unit you're targeting are half transparent. so you make sure that at least one nameplate has a GetAlpha() value < 1 and one has an alpha value of 1. when you target some unit that has no nameplate all nameplates have values < 1. if there is only one nameplate available you will have to rely on a simple name check or discard this information altogether.

now that you hopefully have a guid-nameplate pair you can store this information. the best way to do that is to save it with the nameplate itself, e.g. NameplateN.guid.

when the nameplate is hidden (register OnHide) you will need to flag this information invalid, e.g. NameplateN.guid = -1, because this nameplate, if it is recycled later on, will most definitely represent another unit.

now when you receive an event for a unit cast you can iterate through all nameplates in WorldFrame and check if casterGUID == Nameplate.guid.

this of course means it will only work if you have mouseovered or targeted the unit previously and the moment you walk out of range the information is rendered useless but that's how it works.

the case where you can speed up things and make it more reliable is with player casts as you can assume that there is no name ambiguity. so you extend your code and check, inside the combatlog event, if the unit is a player (see my previous post and http://www.wowpedia.org/GUID#Notes). if that's the case you can bypass that whole guid thing, iterate through all nameplates, check if it's a player nameplate and compare casterName with name:GetText() (see above).

to decide if a nameplate belongs to a player you check the color of the healthbar

lua Code:
  1. healthBar, castBar = frame:GetChildren()

player nameplates are either blue or class-colored whereas npc nameplates are reaction-colored. this is an excerpt from cael's nameplates:

lua Code:
  1. local r, g, b = self.healthBar:GetStatusBarColor()
  2. local newr, newg, newb
  3. if g + b == 0 then
  4.         -- Hostile unit
  5.         newr, newg, newb = 0.69, 0.31, 0.31
  6.         self.healthBar:SetStatusBarColor(0.69, 0.31, 0.31)
  7. elseif r + b == 0 then
  8.         -- Friendly unit
  9.         newr, newg, newb = 0.33, 0.59, 0.33
  10.         self.healthBar:SetStatusBarColor(0.33, 0.59, 0.33)
  11. elseif r + g == 0 then
  12.         -- Friendly player
  13.         newr, newg, newb = 0.31, 0.45, 0.63
  14.         self.healthBar:SetStatusBarColor(0.31, 0.45, 0.63)
  15. elseif 2 - (r + g) < 0.05 and b == 0 then
  16.         -- Neutral unit
  17.         newr, newg, newb = 0.65, 0.63, 0.35
  18.         self.healthBar:SetStatusBarColor(0.65, 0.63, 0.35)
  19. else
  20.         -- Hostile player - class colored.
  21.         newr, newg, newb = r, g, b
  22. end

when the nameplate is player-colored and the name matches you're safe to say it's the same unit.

all that's left to do is handling the statusbar update. you can either attach your custom castbar to the nameplate. do this when you register OnHide() once. or you reuse the existing castbar and take care of manually showing and skinning it. mind that if the caster is also your target wow automatically shows the nameplate castbar and you can skip that part entirely for this case. this also means that it is probably better to reuse the existing castbar for an uniform look.

edit: good lord...... how long this post became.

it also came to my mind that another possibility to associate a guid to a nameplate would be to check the raid icon texture of the nameplate for its offset and maintain a guid<->raidtarget table. see my lich king addon (stun module) to get an idea of how to do this.

Last edited by hankthetank : 05-27-11 at 08:13 PM.
  Reply With Quote