Thread Tools Display Modes
01-28-18, 11:25 PM   #1
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Making my own BossFrames with XML - Need help with show states

Since it seems I cannot move the default Boss1TargetFrame without running in to issues in combat, I've just decided to recreate the boss frames in XML with BossTargetFrameTemplate. XML is uncharted territory for me, so be gentle.

I have essentially gotten the frames to look how I want them to look, and function how I want them to function with the exception of their show state.

I can get them to hide when there's no bosses around, but I cannot get them to mirror the "normal" bossframes, especially when more than 1 boss gets pulled.

Here is my current code:

Basic XML

Code:
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
	<Script file="mBossframes.lua"/>
	<Button name="mBoss1TargetFrame" inherits="BossTargetFrameTemplate" id="1">
		<Anchors>
			<Anchor point="TOPRIGHT" x="-310" y="-510"/>
		</Anchors>
	</Button>
	<Button name="mBoss2TargetFrame" inherits="BossTargetFrameTemplate" id="2">
		<Anchors>
			<Anchor point="TOPLEFT" relativeTo="mBoss1TargetFrame" relativePoint="BOTTOMLEFT" x="0" y="-30"/>
		</Anchors>
	</Button>
	<Button name="mBoss3TargetFrame" inherits="BossTargetFrameTemplate" id="3">
		<Anchors>
			<Anchor point="TOPLEFT" relativeTo="mBoss2TargetFrame" relativePoint="BOTTOMLEFT" x="0" y="-30"/>
		</Anchors>
	</Button>
	<Button name="mBoss4TargetFrame" inherits="BossTargetFrameTemplate" id="4">
		<Anchors>
			<Anchor point="TOPLEFT" relativeTo="mBoss3TargetFrame" relativePoint="BOTTOMLEFT" x="0" y="-30"/>
		</Anchors>
	</Button>
	<Button name="mBoss5TargetFrame" inherits="BossTargetFrameTemplate" id="5">
		<Anchors>
			<Anchor point="TOPLEFT" relativeTo="mBoss4TargetFrame" relativePoint="BOTTOMLEFT" x="0" y="-30"/>
		</Anchors>
	</Button>
</Ui>
And Lua:

Lua Code:
  1. function IsBossFrameShown()
  2.     for i = 1, MAX_BOSS_FRAMES do
  3.     local b = _G["Boss"..i.."TargetFrame"]
  4.         if b and b:IsShown() then
  5.           return true
  6.         end
  7.     end
  8.     return false
  9. end
  10.  
  11. function UpdateView()
  12.     for i = 1, MAX_BOSS_FRAMES do
  13.         local t = _G["mBoss"..i.."TargetFrame"]
  14.     if mBoss1TargetFrame:IsShown() and IsBossFrameShown() then
  15.         return
  16.     elseif not mBoss1TargetFrame:IsShown() and IsBossFrameShown() then
  17.         mBoss1TargetFrame:Show()
  18.     elseif (t) then
  19.             t:Hide()
  20.     end
  21.     end
  22. end
  23.  
  24. for i = 1, MAX_BOSS_FRAMES do
  25.     local b = _G["Boss"..i.."TargetFrame"]
  26.     b:HookScript("OnShow",function() UpdateView() end)
  27.     b:HookScript("OnHide",function() UpdateView() end)
  28. end
  Reply With Quote
01-29-18, 08:12 AM   #2
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
I think this is going to be a lot harder then i thought so since calling the default global boss loaders also taint shit, i'll create my boss frames later this week then i can share my insights if you can wait a bit.
  Reply With Quote
01-29-18, 11:19 AM   #3
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Sounds good, look forward to it.
  Reply With Quote
01-29-18, 09:48 PM   #4
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
You can run this after your XML:
Code:
for id = 1, MAX_BOSS_FRAMES do
	local frame = _G[("mBoss%uTargetFrame"):format(id)]
	if frame then
		RegisterStateDriver(frame, "visibility", ("[@boss%u,exists] show; hide"):format(id))
	end
end
  Reply With Quote
01-30-18, 05:27 AM   #5
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Originally Posted by Vrul View Post
You can run this after your XML:
Code:
for id = 1, MAX_BOSS_FRAMES do
	local frame = _G[("mBoss%uTargetFrame"):format(id)]
	if frame then
		RegisterStateDriver(frame, "visibility", ("[@boss%u,exists] show; hide"):format(id))
	end
end
Running this shows them okay but without a TargetFrame_Update() they look like this (the bottom ones)



Also, when two bosses are pulled at the same time it throws another error.

Code:
1x [ADDON_ACTION_BLOCKED] AddOn '!mUI' tried to call the protected function 'Boss1TargetFrame:Show()'.
  Reply With Quote
01-30-18, 05:32 AM   #6
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
That is because you have altered the Blizzard frames in combat with your UpdateView?!

The state driver will do the show/hide for you securely.
Do not interact with the frames directly unless you have a InCombatLockdown check in place.

That being said you can write your own secure handler. Inside that handler you have access to a referenced frame if needed and have access to functions that are allowed in secure environment.

An example can be the secure page handling on actionbars I use: https://github.com/zorker/rothui/blo...r/bars.lua#L78

Lua Code:
  1. --state frame
  2. local frame = CreateFrame("Frame",nil,nil,"SecureHandlerStateTemplate")
  3. --_onstate-boss state driver
  4. for id = 1, MAX_BOSS_FRAMES do
  5.   local name = "Boss"..i.."TargetFrame"
  6.   local unitFrame = _G[name]
  7.   frame:SetFrameRef(name, unitFrame)
  8. end
  9. frame:Execute(([[
  10.   unitFrames = table.new()
  11.   for i=1, %d do
  12.     table.insert(unitFrames , self:GetFrameRef("Boss"..i.."TargetFrame"))
  13.   end
  14. ]]):format(MAX_BOSS_FRAMES))
  15. frame:SetAttribute("_onstate-boss", [[
  16.   print("_onstate-boss",newstate,unitFrames )
  17.   for i, unitFrame in next, unitFrames do
  18.     print(unitFrame:GetName(),unitFrame:IsShown())
  19.   end
  20. ]])
  21. RegisterStateDriver(frame, "boss", "[@boss5,exists,nodead]5;[@boss4,exists,nodead]4;[@boss3,exists,nodead]3;[@boss2,exists,nodead]2;[@boss1,exists,nodead]1;0")
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 01-30-18 at 06:01 AM.
  Reply With Quote
01-30-18, 05:46 AM   #7
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Originally Posted by zork View Post
That is because you have altered the Blizzard frames in combat with your UpdateView?!

The state driver will do the show/hide for you securely.
Do not interact with the raid frames directly unless you have a InCombatLockdown check in place.
Will try out code posted and let you know.

Last edited by tehmoku : 01-30-18 at 05:52 AM.
  Reply With Quote
01-30-18, 05:57 AM   #8
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Forgot the first two lines. You need a state handler frame.
If you need additional references to your frame you need to add them.
Do not try to access frames inside the handler that you have no access to via getframeref.
Not sure if the state handler frame needs to be visible to work.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 01-30-18 at 06:00 AM.
  Reply With Quote
01-30-18, 05:13 PM   #9
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
The problem is that the default Target/Boss global functions taints stuff when called from addons, so you can't just use the template and call it a day, you probably need to create everything from scratch.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Making my own BossFrames with XML - Need help with show states


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