WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Making my own BossFrames with XML - Need help with show states (https://www.wowinterface.com/forums/showthread.php?t=56010)

tehmoku 01-28-18 11:25 PM

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

Resike 01-29-18 08:12 AM

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.

tehmoku 01-29-18 11:19 AM

Sounds good, look forward to it.

Vrul 01-29-18 09:48 PM

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


tehmoku 01-30-18 05:27 AM

Quote:

Originally Posted by Vrul (Post 326691)
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()'.

zork 01-30-18 05:32 AM

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")

tehmoku 01-30-18 05:46 AM

Quote:

Originally Posted by zork (Post 326693)
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.

zork 01-30-18 05:57 AM

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.

Resike 01-30-18 05:13 PM

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.


All times are GMT -6. The time now is 08:15 PM.

vBulletin © 2018, Jelsoft Enterprises Ltd
© 2004 - 2017 MMOUI