Thread Tools Display Modes
09-15-17, 04:50 PM   #1
nKweo
A Deviate Faerie Dragon
 
nKweo's Avatar
Join Date: Oct 2012
Posts: 16
Question Anchoring cast bar to personal resource display

I've anchored the default casting bar to the default personal resource display (so they don't overlap anymore) with some very basic code:
Code:
CastingBarFrame:ClearAllPoints()
CastingBarFrame:SetPoint("TOP",NamePlatePlayerResourceFrame,"BOTTOM",0,-28)
CastingBarFrame.SetPoint = function() end --without this line the cast bar glitches/stretches
It works pretty well, but when the personal resource display fades (i.e. without a target) the cast bar has a tendency to anchor to random nameplates. So for example when I mount up or hearthstone, I often see a cast bar in very weird places. Any ideas how I can solve this glitch?

I took a peak at the WeakAuras code (as it allows anchoring to the PRD without glitches), but it's a bit out of my league to fully grasp what is going on there. Any suggestions are much appreciated!
  Reply With Quote
09-15-17, 06:53 PM   #2
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
This happens because Personal Resource display is just another nameplate. Nameplates get recycled when not in use so the nameplate associated with your character may end up being assigned to some other random player/NPC if you walk in range while out of combat.

In your case, the best course of action would probably be to add a check when you begin casting to ensure the cast bar is currently anchored to the player's resource frame, and if not, set its position elsewhere (for example, its default anchor, but it can be anywhere.)

Something like this should help:
Code:
if CastingBarFrame:GetParent() ~= NamePlatePlayerResourceFrame and NamePlatePlayerResourceFrame then
	CastingBarFrame:ClearAllPoints()
	CastingBarFrame:SetPoint("TOP",NamePlatePlayerResourceFrame,"BOTTOM",0,-28)
	CastingBarFrame.SetPoint = function() end
else
	[... code that re-anchors the cast bar somewhere else ...]
end
Untested, but the idea is that if the castbar isn't currently anchored to NamePlatePlayerResourceFrame AND NamePlatePlayerResourceFrame exists, it will anchor the castbar to Personal Resource Display, and if you begin casting while out of combat, it will re-anchor the castbar to its default position to prevent it from showing up in places you don't want it to.

You can probably hook into UNIT_SPELLCAST_CHANNEL_START for this.
  Reply With Quote
09-16-17, 04:59 AM   #3
nKweo
A Deviate Faerie Dragon
 
nKweo's Avatar
Join Date: Oct 2012
Posts: 16
Thanks! Unfortunately the first if-statement doesn't seem to work the way one might assume though. The cast bar still anchors to a random nameplate when the PRD is hidden:
Code:
local function attach()
if CastingBarFrame:GetParent() ~= NamePlatePlayerResourceFrame and NamePlatePlayerResourceFrame then
	CastingBarFrame:ClearAllPoints()
	CastingBarFrame:SetPoint("TOP",NamePlatePlayerResourceFrame,"BOTTOM",0,-28)
	--CastingBarFrame.SetPoint = function() end (seems to break the code)
else
	CastingBarFrame:ClearAllPoints()
	CastingBarFrame:SetPoint("TOP",UIParent,"BOTTOM",0,160)
	--CastingBarFrame.SetPoint = function() end (seems to break the code)
end
end

local f = CreateFrame("frame")
f:RegisterUnitEvent("UNIT_SPELLCAST_START","player")
f:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_START","player")
f:SetScript("OnEvent",attach)
Substituting the if-statement with a simple UnitExists("target") statement seems to work ok though (although it is not as elegant):
Code:
if (UnitExists("target")) then
Moreover, there is a new problem I can't seem to solve now. I used CastingBarFrame.SetPoint = function() end to prevent to repositioned cast bar from stretching back to its original position. But entering this statement into the logic seems to break it... Can this be solved without too much hassle?
  Reply With Quote
09-16-17, 10:19 AM   #4
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Originally Posted by nKweo View Post
Substituting the if-statement with a simple UnitExists("target") statement seems to work ok though (although it is not as elegant):
Code:
if (UnitExists("target")) then
I wouldn't do it that way because it's possible to have a target while the personal resource display isn't showing which would cause the code to specifically attach it to a wrong nameplate (or perhaps cause the code to panic and return a lua error if no nameplates are in range.)

Code:
local function attach()
	if C_NamePlate.GetNamePlateForUnit("player") then
		CastingBarFrame:ClearAllPoints()
		CastingBarFrame:SetPoint("TOP",C_NamePlate.GetNamePlateForUnit("player"),"BOTTOM",0,-28)
		--CastingBarFrame.SetPoint = function() end (seems to break the code)
	else
		CastingBarFrame:ClearAllPoints()
		CastingBarFrame:SetPoint("TOP",UIParent,"BOTTOM",0,160)
		--CastingBarFrame.SetPoint = function() end (seems to break the code)
	end
end

local f = CreateFrame("frame")
f:RegisterUnitEvent("UNIT_SPELLCAST_START","player")
f:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_START","player")
f:SetScript("OnEvent",attach)
Turns out NamePlatePlayerResourceFrame can't be reliably used, using C_NamePlate.GetNamePlateForUnit("player") instead gets the desired results (at least from my limited testing it does.)
Works with both default cast bar, and with "Cast Bar Underneath" enabled.

Originally Posted by nKweo View Post
Moreover, there is a new problem I can't seem to solve now. I used CastingBarFrame.SetPoint = function() end to prevent to repositioned cast bar from stretching back to its original position. But entering this statement into the logic seems to break it... Can this be solved without too much hassle?
What actions are you doing in-game when this stretching happens? Is it during combat? I can't reproduce it.

Either way it breaks because CastingBarFrame:SetPoint() is calling CastingBarFrame.SetPoint, so if you zero out the latter it prevents the former from working.

Last edited by Ammako : 09-16-17 at 10:38 AM.
  Reply With Quote
09-16-17, 12:26 PM   #5
nKweo
A Deviate Faerie Dragon
 
nKweo's Avatar
Join Date: Oct 2012
Posts: 16
Very nice work! There's a CVAR for always showing the PRD with a target (even out of combat), but your method is way cleaner. Still there is some glitchiness with the cast bar though. It has happened on all kinds of casts, but only sporadically. Can't pinpoint it. I've recorded a vid so you can see what I mean: https://www.useloom.com/share/a23202...fe2b4ccb4f7e6f. Thoughts are appreciated.
  Reply With Quote
09-16-17, 03:25 PM   #6
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Interesting, I didn't know there was a CVar for that.
(tfw Blizzard adds hidden options that never really get officially documented)

Yeah, I've managed to reproduce the error. I don't know why it happens and since Blizzard didn't assign a name to the actual progress bar frame inside the cast bar I can't begin to try and prevent it from happening (that, and it doesn't consistently happen so it's hard to troubleshoot.)

Somebody else who knows more about the cast bar frame (or who knows how to deal with unnamed frames) would have to pitch in.

In the meantime, this doesn't seem to happen if Cast Bar Underneath is enabled, in the right-click menu on your character portrait. This changes the appearance of the cast bar so it's possible you may not like it, but I've not seen that bug happen when using this. You may have to add some code to prevent the cast bar from sometimes re-anchoring itself under the character portrait, though (it happens for a split second when I mount and fly away too quickly, but haven't seen it happen any other time.) The code for that is in PlayerFrame.lua

Also, I think I should have suggested NAME_PLATE_UNIT_ADDED and NAME_PLATE_UNIT_REMOVED instead; those make a lot more sense. That way the castbar should more reliably re-anchor itself to the personal resource display when it appears (and vice-versa when it disappears) instead of only anchoring itself when you begin casting. Otherwise I can start casting something at an enemy and it isn't until the third cast that the castbar anchors itself to the Personal Resource Display.

Last edited by Ammako : 09-16-17 at 03:30 PM.
  Reply With Quote
09-17-17, 03:56 AM   #7
nKweo
A Deviate Faerie Dragon
 
nKweo's Avatar
Join Date: Oct 2012
Posts: 16
So you ended up with something like this?
Code:
local function attach()
	CastingBarFrame:ClearAllPoints()
	CastingBarFrame:SetPoint("TOP",C_NamePlate.GetNamePlateForUnit("player"),"BOTTOM",0,-28)
	--CastingBarFrame.SetPoint = function() end
end

local function detach()
	CastingBarFrame:ClearAllPoints()
	CastingBarFrame:SetPoint("TOP",UIParent,"BOTTOM",0,160)
	--CastingBarFrame.SetPoint = function() end
end

local f = CreateFrame("frame")
f:RegisterEvent("NAME_PLATE_UNIT_ADDED","player")
f:SetScript("OnEvent",attach)

local f = CreateFrame("frame")
f:RegisterEvent("NAME_PLATE_UNIT_REMOVED","player")
f:SetScript("OnEvent",detach)
Haven't played around too much with it, since it won't solve the cast bar stretching problem. Would be nice if someone else would chime in, but otherwise your other suggestions work ok for now.
  Reply With Quote
09-17-17, 11:16 AM   #8
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
No, that's no good. This tries to attach the castbar to Personal Resource Display whenever -any- nameplate appears on screen and puts it back in your default location whenever any nameplate disappears.
So you'd be out of combat and your castbar doesn't show up anymore because it tried attaching to a nameplate that isn't in view, or you'd be in middle of combat and castbar goes back to default location when you want it to stay on personal resource display.

Just replace RegisterUnitEvent in the previous code with RegisterEvent and use NAMEPLATE_UNIT_ADDED/NAMEPLATE_UNIT_REMOVED instead of the spellcast events.
  Reply With Quote
09-17-17, 12:41 PM   #9
nKweo
A Deviate Faerie Dragon
 
nKweo's Avatar
Join Date: Oct 2012
Posts: 16
Thanks, was a bit confused by the NAMEPLATE events. Appreciate your time and please let me know if you ever find a solution for the stretching issue (of course I'll share whatever I may find on the subject)!
  Reply With Quote
11-13-17, 07:46 AM   #10
nKweo
A Deviate Faerie Dragon
 
nKweo's Avatar
Join Date: Oct 2012
Posts: 16
Update: Haven't tested it much yet, but adding CastingBarFrame.ignoreFramePositionManager = true seems to do the trick!
  Reply With Quote
07-24-18, 04:10 PM   #11
Purpleswag
A Murloc Raider
Join Date: Oct 2013
Posts: 4
Figure out how to make it into addon, but i wonder if it possible to do the same thing with target and focus castbars?

Last edited by Purpleswag : 07-24-18 at 04:23 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Anchoring cast bar to personal resource display

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off