• Dear Guest,

    You're browsing our forum as a Guest meaning you can only see a portion of the forum in read-only mode.
    To view all forum nodes and be able to create threads/posts please register or log-in with your existing account.

    TwinStar team

Luna Unit Frames (an edit of v. 2008 beta)

Drood

New Member
Joined
Dec 28, 2015
I made a few changes to the most recent LUF, which is sadly a frozen project.

Here's what I changed in v. 0.1:
1) Debuff borders are now coloured based on the type of the debuff.

2) You can now set keybinds that allow you to temporarily track certain groups of buffs other than the three buffs you might usually be tracking. The purpose of this is mainly for buffers to be able to quickly see who needs a rebuff without having to either track the buffs all the time or rewrite the name of the buffs in the options all the time. There are only a few basic groups of buffs to be tracked right now; I might add more later.

3) Some tags are added/changed. In particular, you might appreciate the new
[shortname], [shortername], [gridname]
They display only the first n characters of the unit's name where n is a number you can set in the general tab of the options window. For the target's powerbar, I suggest the combo: [difficulty][level][shortclassification][white] [classcolor][smartclass][white] [smartrace]
The [gridname] tag is meant to be used for raid frames and will also replace the name of the person with her status when offline, feigned, ghost or dead.

4) Finally, for healers mainly, there is an option to set the raid frames to match a particular configuration of Grid:
- aggro in upperleft corner
- HOTs in other three corners
- tracked debuffs in the centre
- Under Auratracker, disable "Show dispellable debuffs" and under Highlight, enable "Dispellable debuffs". Highlight will become a border around the frame if the "Grid style" box is ticked.
The graphic that tracks HOTs duration should be better in sync now, however it might still be badly out of sync if you have bad lag, specially if it goes up and down.

Changes in v. 0.2:
1) fixed PvP icons
2) disabled TOT and TOTOT when target is player
3) added option to disable clickcasting with right button on target and player frame

Changes in v. 0.3:
1) Added the 40yd range check for healers (see the general options tab). This works by checking the range of your healing spells against other units so it only works if you have HL/FH/HT/HW on your actionbars (even if they are hidden). Also, the range between 28 and 40yds will not be refreshed if you have a non-friendly unit targeted or if you have loot/trade/inspect windows open (things that depend on target).
2) Added some icons to the castbar and changed the time format on it.

Changes in v. 0.3c:
1) Added the ~38yd range check based on map coordinates and Renew's scales database (thanks, m8); this is faster than the other method, but it is less precise and does not work in instances, only in world and battlegrounds. (Tick both boxes in the general options if you want to use this).
2) The default method based on checking range of healing spells should now check 5 players at a time, not the full raid, and should be smoother than before
3) the [gridname] indicators for dead and ghost can be customized in locales/enUS.lua (default was "dead"->"+_+" and "ghost"->"dead")

Changes in v. 0.3d:
Minor fixes.

Changes in v. 0.4:
- a few extra tags,
- minor fixes to the castbar
- overlapping comboPts-bar and castbar; if this is enabled and Hide is enabled for both bars, only one should pop-up when applicable, with castbar overriding combo points. I made this because when both pop up, they narrow the other bars, making tags difficult to read
- automatic idol and libram swapping (not fully tested, please report strange behaviour)

You can download the latest version here:
http://www.mediafire.com/file/2l0l5w3bwjo7rz1

To fix the annoying target-retarget sound when advanced range-checks are enabled, copy the contents of this to your WoW folder: http://www.mediafire.com/file/9626jrjlrqxn8r6

Enjoy. Feedback welcome.
 
Last edited:
I get

"LUF_2008b_em01.rar is malicious and Chrome has blocked it"

Can you upload differently, great changes!
 
Not sure how it can think it's malicious when it's an encrypted .rar; it has no way of knowing what's inside. I think it's just Chrome blocking sharing websites. I will look into other ways of uploading, but this should be fine. Try with another browser, please.
 
My account data is: gordonfreeman13x pw: yournameinhere

just wanted to share it with you without downloading your encrypted rar file :) have fun selling my acc
 
I don't know what you've heard about RAR archives and their magical powers, but you've been lied to ;)
 
The idea being that it would eventually be merged? Because my coding is highly inelegant and should be rewritten, probably. I do this kind of stuff on the fly when I need a functionality and usually go with the first thing that comes to mind. My choices tend to be suboptimal and my comments usually useless because well... it was only done with myself in mind. If I get more time, I might clean it up and more clearly mark my changes in the comments. I like what my changes do, I don't necessarily like the way I did it :)

Here's another link: http://expirebox.com/download/8f6efa263f54ef022d9e332ffd475530.html
This one will expire in 48h, however.


The few that have successfully downloaded and used it, could you please leave a comment? People seem to be overly skeptical.
 
Last edited:
Any idea what could be the cause of this bug? https://github.com/Aviana/LunaUnitFrames/issues/145
No idea, I don't get this error when I run EnumerateFrames().

Edited the first post, there's a newer version with slight improvements and a mediafire link. By the way, why mediafire? I locked the .rar precisely so that some BS website can't touch it, so it doesn't matter where I actually put it. But if it gives you your peace of mind, here it is: http://www.mediafire.com/download/skajvgicf3u7914/LUF_2008b_em02.rar
 
You don't get the error from calling the function once. You have to run this:
Code:
local frame; repeat frame = EnumerateFrames(frame) until not frame
 
I almost did. I ran this
Code:
local frame = EnumerateFrames(); repeat print(frame:GetName()) frame = EnumerateFrames(frame) until not frame
I got a different error, that I thought to be because at some point nil:GetName() was attempted. But removing the print(), I indeed get the same error as you. That's odd, I have no idea what might cause it.
 
Last edited:
Someone asked me ingame about the possibility of adding a reliable 40yd range check. The reasons for not having one are outlined in the old nost thread's faq. The problem is CheckInteractDistance only works up to 30yd and there are (afaik) only two alternatives that work for a larger range.

The first one is checking if there has been a combat log event for that player recently, which is what Luna currently does (via the proximitylib library). The downsides to this approach are:
1) it depends on a certain combat log range which must be set in the Config.wtf file and may cause issues with other addons
2) it is not reliable as there may not have been combat log events despite a player being in range

The other approach, used by a modified sraidframes, is to use IsActionInRange. The downsides of this approach are
1) You need to have a spell with the range you want to check for and it must be on your actionbar
2) Since the function only works on the current target the addon needs to target everyone to update the range information

I think the main reasoning for not using the 2nd approach that the author of luna mentioned was the targeting. Of course this can be a big issue in some cases, e.g., rogues losing combo points (or does this only happen when targeting another hostile target? not sure about that) but I think for classes who need this check the most (probably mainly healers) this shouldn't be an issue. The same applies to point 1 as those classes mainly want the check to know if the target is in range to be healed so they would naturally have a spell with the appropriate range and most likely have it on the action bar anyway unless they're using it through some sort of macro.

Anyway, I don't have the time to start working on modifying luna right now but I've written a short snippet implementing the 40yd check which one could use in luna, either by replacing the combat log stuff in the proximitylib by this or by changing the range.lua file which is there he calls into proximitylib. It's not tested but it should work in principle at least:
Code:
local f = CreateFrame'Frame'
f:SetScript('OneEvent', function() this[event]() end)
f:RegisterEvent'ACTIONBAR_SLOT_CHANGED'
f:RegisterEvent'PLAYER_LOGIN'

local spell, slot

function f.PLAYER_LOGIN()
    spell = ({ Paladin='Holy Light', Priest='Flash Heal', Druid='Healing Touch', Shaman='Healing Wave' })[UnitClass'player']
    if spell then
        CreateFrame('GameTooltip', 'RangeCheckTooltip', nil, 'GameTooltipTemplate')
        function f.ACTIONBAR_SLOT_CHANGED()
            local newSlot
            for i = 1, 120 do
                RangeCheckTooltip:SetAction(i)
                RangeCheckTooltip:Show()
                if RangeCheckTooltipTextLeft1:GetText() == spell then
                    newSlot = i
                end
            end
            slot = newSlot
        end
        f.ACTIONBAR_SLOT_CHANGED()
    end
end

function TargetWithin40yd()
    return not slot or IsActionInRange(slot)
end
 
hey bit, there is a 3. method for BGs and world - by calculating the range over the mappoints. This req. a calibration with the checkdistance - 28yrds function (since every map has different scale) :)

i made a 40yrd health meter once and can share my exp.

the method with IsActionInRange works pretty good, thou it has some downsides:

- extreme performance issue if updated with OnUpdate -> update the 40yrds every x seconds, for me 0.5s worked very well

- to prevent autoattack/loot bug the IsActionInRange update shouldnt be executed if you have an enemy as target
- other checks to prevent bugs like: lootframe/inspectframe/tradeframe/xloot(and other loot addons)

but basically its possible to write a stable 40yrd check in ~30 lines
 
replacement for the range.lua file. maybe it works, maybe not:

Code:
local Range = {}
LunaUF:RegisterModule(Range, "range", LunaUF.L["Range"])
local proximity = ProximityLib:GetInstance("1")

local within40yd = {}
do
    local f = CreateFrame'Frame'
    local function nop() end
    f:SetScript('OnEvent', function() (this[event] or nop)() end)
    f:RegisterEvent'PLAYER_LOGIN'

    CreateFrame('GameTooltip', 'RangeCheckTooltip', nil, 'GameTooltipTemplate')

    local spell, slot

    do
        local count = 0
        function f.UPDATE()
            if count > 0 then
                count = count - 1
            elseif not UnitExists'target' or UnitIsFriend'target' then
                count = 10
                for i = 1,  GetNumGroupMembers() do
                    local player = GetRaidRosterInfo(i)
                    TargetByName(player, true)
                    Within40yd[player] = slot and IsActionInRange(slot) and GetTime()
                end
            end
        end
    end

    function f.ACTIONBAR_SLOT_CHANGED()
        local newSlot
        for i = 1, 120 do
            RangeCheckTooltip:SetOwner(UIParent, 'ANCHOR_NONE')
            RangeCheckTooltip:SetAction(i)
            if RangeCheckTooltipTextLeft1:GetText() == spell then
                newSlot = i
            end
        end
        slot = newSlot
    end

    function f.PLAYER_LOGIN()
        spell = ({ Paladin='Holy Light', Priest='Flash Heal', Druid='Healing Touch', Shaman='Healing Wave' })[UnitClass'player']
        if spell then
            f:RegisterEvent'ACTIONBAR_SLOT_CHANGED'
            f.ACTIONBAR_SLOT_CHANGED()
            f:SetScript('OnUpdate', f.UPDATE)
        end
    end
end

local function OnUpdate()
    Range:FullUpdate(this:GetParent())
end

function Range:OnEnable(frame)
    if not frame.range then
        frame.range = CreateFrame("Frame", nil, frame)
    end
    frame.range:SetScript("OnUpdate", OnUpdate)
end

function Range:OnDisable(frame)
    if frame.range then
        frame.range:SetScript("OnUpdate", nil)
    end
end

function Range:FullUpdate(frame)
    if frame.DisableRangeAlpha then return end
    local range, lastseen = proximity:GetUnitRange(frame.unit)
    if (not range or range > 30) and within40yd[frame.unit] then
        range, lastseen = 40, within40yd[frame.unit]
    end
    if range and ((GetTime()-lastseen) < 3 ) then
        frame:SetAlpha(LunaUF.db.profile.units[frame.unitGroup].fader.enabled and LunaUF.db.profile.units[frame.unitGroup].fader.combatAlpha or 1)
    else
        frame:SetAlpha(LunaUF.db.profile.units[frame.unitGroup].range.alpha)
    end
end
 
Last edited:
Having sRaidframes improved range check on Luna (with an option to choose at which intervals to update) is something I've been wanting for a long time. That or having sRaidframes with the Luna incoming healing aspect.
 
replacement for the range.lua file. maybe it works, maybe not:

Code:
local Range = {}
LunaUF:RegisterModule(Range, "range", LunaUF.L["Range"])
local proximity = ProximityLib:GetInstance("1")

local within40yd = {}
do
    local f = CreateFrame'Frame'
    f:SetScript('OnEvent', function()this[event]() end)
    f:RegisterEvent'PLAYER_LOGIN'

    CreateFrame('GameTooltip', 'RangeCheckTooltip', nil, 'GameTooltipTemplate')

    local spell, slot

    do
        local count = 0
        function f.UPDATE()
            if count > 0 then
                count = count - 1
            elseif not UnitExists'target' or UnitIsFriend'target' then
                count = 10
                for i = 1,  GetNumGroupMembers() do
                    local player = GetRaidRosterInfo(i)
                    TargetByName(player, true)
                    Within40yd[player] = slot and IsActionInRange(slot) and GetTime()
                end
            end
        end
    end

    function f.ACTIONBAR_SLOT_CHANGED()
        local newSlot
        for i = 1, 120 do
            RangeCheckTooltip:SetOwner(UIParent, 'ANCHOR_NONE')
            RangeCheckTooltip:SetAction(i)
            if RangeCheckTooltipTextLeft1:GetText() == spell then
                newSlot = i
            end
        end
        slot = newSlot
    end

    function f.PLAYER_LOGIN()
        spell = ({ Paladin='Holy Light', Priest='Flash Heal', Druid='Healing Touch', Shaman='Healing Wave' })[UnitClass'player']
        if spell then
            f:RegisterEvent'ACTIONBAR_SLOT_CHANGED'
            f.ACTIONBAR_SLOT_CHANGED()
            f:SetScript('OnUpdate', f.UPDATE)
        end
    end
end

local function OnUpdate()
    Range:FullUpdate(this:GetParent())
end

function Range:OnEnable(frame)
    if not frame.range then
        frame.range = CreateFrame("Frame", nil, frame)
    end
    frame.range:SetScript("OnUpdate", OnUpdate)
end

function Range:OnDisable(frame)
    if frame.range then
        frame.range:SetScript("OnUpdate", nil)
    end
end

function Range:FullUpdate(frame)
    if frame.DisableRangeAlpha then return end
    local range, lastseen = proximity:GetUnitRange(frame.unit)
    if (not range or range > 30) and within40yd[frame.unit] then
        range, lastseen = 40, within40yd[frame.unit]
    end
    if range and ((GetTime()-lastseen) < 3 ) then
        frame:SetAlpha(LunaUF.db.profile.units[frame.unitGroup].fader.enabled and LunaUF.db.profile.units[frame.unitGroup].fader.combatAlpha or 1)
    else
        frame:SetAlpha(LunaUF.db.profile.units[frame.unitGroup].range.alpha)
    end
end
 
Last edited:
here is the OnUpdate function for 40yrd range from my current project:

this forum is total garbage, cant post my code: http://pastebin.com/807kq3tk

Code:
VHM.GroupData[i]
is a database with pets and players from another function
 
Last edited:
Yeah, code tags seem to break the edit function somehow. What's the issue with having those frames open when switching targets btw? Also, has anyone tried if the range.lua from my last post works? Can't test it myself as I don't have a char with one of those spells.
 
Yeah, code tags seem to break the edit function somehow. What's the issue with having those frames open when switching targets btw?

this can cause loot bug with grp loot (at least thats what i got from old sraidframes improved posts). speaking of sraidframes, the 40yrd range is causing DCs on kronos if your updatefrequency is too high...

what i check before i target->retarget:

Code:
not VHM.UnitIsUnit("target",UnitID) and not VHM.UnitIsEnemy("player","target")

Code:
(InspectFrame and InspectFrame:IsVisible()) or (LootFrame and LootFrame:IsVisible()) or (XLootFrame and XLootFrame:IsVisible()) or (TradeFrame and TradeFrame:IsVisible())

Code:
VHM.UnitIsVisible(UnitID) or VHM.UnitIsConnected(UnitID) or VHM.UnitIsGhost(UnitID) or not VHM.UnitIsGhost(UnitID) or not VHM.UnitIsDead(UnitID) and not VHM.UnitIsEnemy(UnitID,"player")

Code:
VHM.CheckInteractDistance(UnitID,4)

thats also the checks in sraidframes
 
Yeah, code tags seem to break the edit function somehow. What's the issue with having those frames open when switching targets btw? Also, has anyone tried if the range.lua from my last post works? Can't test it myself as I don't have a char with one of those spells.
With minor fixes, I think it works in principle. You used within40yd with a capital W at some point and also GetNumGroupMembers() doesn't exist and should be probably be replaced by "GetNumRaidMembers() or GetNumPartyMembers()" and it should also be UnitIsFriend('target','player'). However, you do not retarget the last target and I think the update rate is too fast so the UI target frame is cycling through targets very fast and nothing is really targetable since the target switches immediately. I will add all the checks Renew mentioned and play with it a bit, see what happens.

P.S.
Does anyone know if it would work noticably faster if one set the update function to nil when not in raid, or is it not worth doing?

I tested this target-retarget approach with 1sec refreshrate and it didn't really work for me. In particular:
Code:
for i = 1, GetNumRaidMembers() do
    unitID = 'raid'..i
    if ConditionsAreSatisfied(unitID) then
        TargetUnit(unitID)
        within40yd[unitID] = slot and IsActionInRange(slot) and GetTime()
        TargetUnit('playertarget')
    end
end
doesn't quite work as it does not retarget correctly. Same with TargetLastTarget(). Also, since I use 3D portraits in Luna, the animation is reset on each retarget so it looks very bad on low refreshrates.
 
Last edited by a moderator:
Couldn't you just get the name with UnitName'target' before the loop and then retarget with TargetByName(name, true) when finished? Seems pointless to keep retargeting 40 times while looping through the raid.
 
That's probably better for most cases, but there exist mobs with same names. There may be a way to make this smoother by telling the Luna target frame (and TOT and TOTOT) to not refresh on every target change by checking a global variable. Still, I do not quite understand why this messes up targeting so badly. Anyway, TargetByName(name, true) actually gets things done, unlike what I tried to do.
 
Last edited:
Top Bottom