09-22-09, 02:53 AM | #1 |
oUF_AuraSort
What happened to it? I can't find it anymore and the latest version (seems to be from november 2008) I found on my HDD spits out a lua error @
Code:
oUF:SetAuraPosition(icons, visible) |
|
09-22-09, 05:12 AM | #2 |
How are you wanting to sort them? Assuming it's by time left, I use the following in preAuraSetPosition:
Code:
for i=1, #buffs do if( buffs[i].timeLeft == nil ) then buffs[i].timeLeft = 0 end end table.sort(buffs, function(a,b) return a.timeLeft > b.timeLeft end) |
|
09-22-09, 10:01 AM | #3 |
"AuraSort" sorted buffs by "your own first" and/or time left, afaik. Which is what I was aiming for, too. Time left will do it, though. I'll try that.
E: Not quite sure where to put this, though. |
|
09-22-09, 11:06 AM | #4 |
That is a very bad implementation wurmfood, the icons can jump and hide alot.
|
|
09-22-09, 12:09 PM | #5 |
That's how AuraSort did it. However it seems broken since 3.1 or 3.0, not quite sure.
Code:
-- Compares two icons for sorting local function sortIcons(a, b) local auras = a:GetParent() local frame = auras:GetParent() local settings = frame.sortAuras local unit, filter = frame.unit, auras.filter local nameA, _, _, countA, debuffTypeA, _, expiresA, isMineA, isStealableA = UnitAura(unit, a.oUF_AuraSort_index, filter) local nameB, _, _, countB, debuffTypeB, _, expiresB, isMineB, isStealableB = UnitAura(unit, b.oUF_AuraSort_index, filter) if(not expiresA) then expiresA = -1 end if(not expiresB) then expiresB = -1 end local result if(settings.selfFirst) then if(isMineA == isMineB) then result = expiresA > expiresB else result = isMineA and true or false end else result = expiresA > expiresB end if(settings.reverse) then result = not result end return result end -- Overrides the layouts SetAuraPosition function with a new one that will sort the auras local function OverrideSetAuraPosition(self, icons, visible) if(self.oUF_AuraSort_SetAuraPosition) then self.oUF_AuraSort_SetAuraPosition(self, icons, visible) end -- If layout has its own SetAuraPosition function already then call it if(visible <= 0) then return end -- Make a copy of the icon list and then sort it local sorted = {} for i = 1, visible do icons[i].oUF_AuraSort_index = i sorted[i] = icons[i] end sort(sorted, sortIcons) -- Iterate through each icon then find the match for its ID in the new sorted list. Once found reset the order of the icons with the final icon order local final = {} for i = 1, visible do final[i] = sorted[icons[i]:GetID()] end for i = 1, visible do icons[i] = final[i] end oUF:SetAuraPosition(icons, visible) end -- Applies aura sorting to a oUF layout frame local function applyAuraSorting(object) if(not object.sortAuras) then return end -- Store any predefined functions layout has, if any if(object.SetAuraPosition) then object.oUF_AuraSort_SetAuraPosition = object.SetAuraPosition end -- Override old functions with new ones object.SetAuraPosition = OverrideSetAuraPosition end local f = CreateFrame("Frame", nil) f:SetScript("OnEvent", function(s, e) for _, object in pairs(oUF.objects) do applyAuraSorting(object) end end) f:RegisterEvent("PLAYER_LOGIN") |
|
09-22-09, 02:47 PM | #6 |
p3lim, I honestly don't know of a better way to do it. At some point the table has to be sorted and I didn't really see a better place or way to do it. I'd love to see another suggestion.
Dawn, it shouldn't be too hard to take what's there and make it work. The most important part seems to be the sort function and the way it chooses to sort them. There's two parts that I used to make this work. The first was to copy over the customFilter from aura.lua to my layout. I just added "icon.timeLeft = timeLeft" just before the "return true". (The time left on the auras doesn't seem to be preserved anywhere else, though I may have missed it.) Then I created a preAuraSetPosition function. Here's the relevant part: Code:
local preAuraSetPosition = function(self, buffs, max) local visBuffs = 0 for i=1, #buffs do if( buffs[i].timeLeft == nil ) then buffs[i].timeLeft = 0 end end table.sort(buffs, function(a,b) return a.timeLeft > b.timeLeft end) end Code:
self.CustomAuraFilter = customFilter self.PreAuraSetPosition = preAuraSetPosition |
|
09-22-09, 03:50 PM | #7 | |
Anyways, you forgot you need to set the .timeLeft somewhere. Also, Im guessing you followed my code to make the timers in the first place, you don't really need to check for nil time if you do things properly with the initial creation of time text. |
||
09-22-09, 04:07 PM | #8 |
Hadn't looked at your layout yet, but will do so. I'm always open to better ways of doing thing.
I'm setting timeLeft in the customFilter function as it's the only good place I know of to set it. The only reason I'm checking it for nil is for the sorting. I'm letting OmniCC take care of the text part, so I don't worry about it. |
|
09-22-09, 04:07 PM | #9 |
Err, ... you lost me. Sorting by time left would be really enough for me. I don't really need to sort my own auras first. That is just a bonus I could live without.
From what I understand, I should copy the whole SetAuraPosition code from aura.lua ... Code:
local SetAuraPosition = function(self, icons, x) if(icons and x > 0) then local col = 0 local row = 0 local spacing = icons.spacing or 0 local gap = icons.gap local size = (icons.size or 16) + spacing local anchor = icons.initialAnchor or "BOTTOMLEFT" local growthx = (icons["growth-x"] == "LEFT" and -1) or 1 local growthy = (icons["growth-y"] == "DOWN" and -1) or 1 local cols = math.floor(icons:GetWidth() / size + .5) local rows = math.floor(icons:GetHeight() / size + .5) for i = 1, x do local button = icons[i] if(button and button:IsShown()) then if(gap and button.debuff) then if(col > 0) then col = col + 1 end gap = false end if(col >= cols) then col = 0 row = row + 1 end button:ClearAllPoints() button:SetPoint(anchor, icons, anchor, col * size * growthx, row * size * growthy) col = col + 1 end end end end Code:
local visBuffs = 0 for i=1, #buffs do if( buffs[i].timeLeft == nil ) then buffs[i].timeLeft = 0 end end table.sort(buffs, function(a,b) return a.timeLeft > b.timeLeft end) Edit: I have timeleft set here, maybe I can use this to also sort the buffs? Code:
local function auraUpdateTime(self, elapsed) self.timeLeft = math.max(self.timeLeft - elapsed, 0) local timeFormat, value = SecondsToTimeAbbrev(math.floor(self.timeLeft)) if type(value) == 'number' then self.time:SetFormattedText(timeFormat, value) else self.timeLeft = nil self.time:SetText() self:SetScript('OnUpdate', nil) end end local function auraUpdateTimeShort(self, elapsed) self.timeLeft = math.max(self.timeLeft - elapsed, 0) self.time:SetText(self.timeLeft < 120 and math.floor(self.timeLeft) or '') end local function auraUpdateIcon(self, icons, unit, icon, index, offset, filter, isDebuff) if(unit) or (self:GetParent():GetName():match"oUF_Party") then local _, _, _, _, _, duration, timeLeft = UnitAura(unit, index, filter) if duration > 0 and timeLeft then icon.timeLeft = timeLeft - GetTime() if unit == 'player' then --icon:SetScript('OnUpdate', auraUpdateTime) icon:SetScript('OnUpdate', auraUpdateTimeShort) else icon:SetScript('OnUpdate', auraUpdateTimeShort) end else icon.timeLeft = nil icon.time:SetText() icon:SetScript('OnUpdate', nil) end end end Last edited by Dawn : 09-22-09 at 04:10 PM. |
|
09-22-09, 07:15 PM | #10 | |
Calling his sort method a bad implementation is also plain wrong. Are you really expecting someone to implement id consistent time sort? But now that you've said what you have. Then please explain to the crowd here exactly why re-implementing the entire :SetAuraPosition() is a better solution that just sorting the table before it's positioned. It would also be beneficial that you post your far superior sort algorithm that respects icon position and sort order. Enough bashing of you for now at least: The way oUF updates auras is quite straight forward, but it has a lot of different ways to manipulate it. A really short example of why it's beneficial to use :PreAuraSetPosition() would be: lua Code:
What the function above those is basically invert the aura sort direction. Now compare it with what you would have to do with :SetAuraPosition(): lua Code:
Enough about that: To get your timer based sort you'll have to: 1. Add a start or end time variable to the icon, so that you can compare it. There's several ways to do this: CreateAuraIcon, PostCreateAuraIcon, CustomAuraFilter, PostUpdateAuraIcon, PreAuraSetPosition. CustomAuraFilter is most likely the best way to do this, as you have direct access to the variables you need. 2. Use :PreAuraSetPosition() to re-arrange the icon list. It's table.sort() compatible for a reason. 3. ??? 4. Profit! What you don't need for just aura sorting like this however is: an OnUpdate, duration, endTime and startTime is way more that you need for this. If you want to update some text, then you obviously will need this ofc tho'...
__________________
「貴方は1人じゃないよ」 |
||
09-23-09, 08:04 AM | #11 |
I just said what my experience with his code was, the buffs jumped alot and were placed way off the frame by index.
Saying that replacing SetAuraPosition could be better is just a guess, as I have not looked at this that much. |
|
09-23-09, 10:36 AM | #12 |
Ok, it's working.... most of the time.
I added Code:
local preAuraSetPosition = function(self, buffs, max) local visBuffs = 0 for i=1, #buffs do if( buffs[i].timeLeft == nil ) then buffs[i].timeLeft = 0 end end table.sort(buffs, function(a,b) return a.timeLeft > b.timeLeft end) end Code:
self.PreAuraSetPosition = preAuraSetPosition I didn't copy the customaurafilter to add "icon.timeLeft = timeLeft", because like I said above, I'm having some timeleft code already as part of my aura duration update code. However it's a little different. Instead of Code:
icon.timeLeft = timeLeft Code:
self.timeLeft = math.max(self.timeLeft - elapsed, 0) Btw, reload UI fixes the bug, until it bugs out again (can't determine for what reason it bugs out, yet). |
|
09-23-09, 01:14 PM | #13 |
I would recommend using starttime or endtime instead of timeleft. The main reason for this is the fact that it's updated by your OnUpdate all the time, and it usually contains more decimals than any sane person would use . It's really why I recommended customaurafilter in the first place.
__________________
「貴方は1人じゃないよ」 |
|
09-24-09, 09:25 PM | #14 |
Mhm, seems like I can only get this to work with timeleft and preAuraSetPosition, which is buggy as hell.
I tried to fix AuraSort, but can't figure out why it Code:
... attempt to call method 'SetAuraPosition' (a nil value) Code:
oUF:SetAuraPosition(icons, visible) |
|
09-25-09, 07:10 AM | #15 |
:SetAuraPosition() only exists on the frames as of 1.3.0. It was the breaking change in that release I believe. It would really be better to update AuraSort to use the new API instead of just replacing the old one tho'.
__________________
「貴方は1人じゃないよ」 |
|
09-25-09, 11:41 AM | #16 |
Yeah, I've pm'ed Atrophia (author of AuraSort), but I don't know if he's still around and/or willing to maintain it, since he even removed it from WoWi after he started to work on his own unitframes.
|
|
WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » oUF_AuraSort |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|