|
09-10-13, 10:12 PM | #1 |
Need some help on totembar please
I tried to add a timer on the ouf_totembar, but the problem is that I can't make it update itself well,
and when I destroyed the totem, the timer would stop at the time it left instead of disppear. Please help! Code:
local _, ns = ... local oUF = ns.oUF or oUF if not oUF then return end local _, pClass = UnitClass("player") local total = 0 local delay = 0.01 -- In the order, fire, earth, water, air local colors = { [1] = {.58,.23,.10}, [2] = {.23,.45,.13}, [3] = {.19,.48,.60}, [4] = {.42,.18,.74}, } local GetTotemInfo, SetValue, GetTime = GetTotemInfo, SetValue, GetTime local Timer local Abbrev = function(name) return (string.len(name) > 10) and string.gsub(name, "%s*(.)%S*%s*", "%1. ") or name end local function TotemOnClick(self,...) local id = self.ID local mouse = ... if IsShiftKeyDown() then for j = 1,4 do DestroyTotem(j) end else DestroyTotem(id) end end local function InitDestroy(self) local totem = self.TotemBar for i = 1 , 4 do local Destroy = CreateFrame("Button",nil, totem[i]) Destroy:SetAllPoints(totem[i]) Destroy:RegisterForClicks("LeftButtonUp", "RightButtonUp") Destroy.ID = i Destroy:SetScript("OnClick", TotemOnClick) end end local function UpdateSlot(self, slot) local totem = self.TotemBar local haveTotem, name, startTime, duration, totemIcon = GetTotemInfo(slot) totem[slot]:SetStatusBarColor(unpack(totem.colors[slot])) totem[slot]:SetValue(0) totem[slot].Time = totem[slot]:CreateFontString(nil, "OVERLAY") totem[slot].Time:SetPoint('CENTER', totem[slot], 'CENTER', 0, 1) totem[slot].Time:SetFont(NAMEPLATE_FONT, 14, "THINOUTLINE") -- Multipliers if (totem[slot].bg.multiplier) then local mu = totem[slot].bg.multiplier local r, g, b = totem[slot]:GetStatusBarColor() r, g, b = r*mu, g*mu, b*mu totem[slot].bg:SetVertexColor(r, g, b) end totem[slot].ID = slot -- If we have a totem then set his value if(haveTotem) then if totem[slot].Name then totem[slot].Name:SetText(Abbrev(name)) end if(duration >= 0) then if duration == 0 then totem[slot]:SetValue(0) else totem[slot]:SetValue(1 - ((GetTime() - startTime) / duration)) end -- Status bar update totem[slot]:SetScript("OnUpdate", function(self,elapsed) total = total + elapsed if total >= delay then total = 0 haveTotem, name, startTime, duration, totemIcon = GetTotemInfo(self.ID) if ((GetTime() - startTime) == 0) or (duration == 0) then self:SetValue(0) else self:SetValue(1 - ((GetTime() - startTime) / duration)) end end Timer = startTime + duration - GetTime() if haveTotem then if Timer > 0 then self.Time:SetFormattedText("%d", Timer) else self.Time:SetText(" ") end else self.Time:SetText(" ") end end) else -- There's no need to update because it doesn't have any duration totem[slot]:SetScript("OnUpdate",nil) totem[slot]:SetValue(0) end else -- No totem = no time if totem[slot].Name then totem[slot].Name:SetText(" ") end totem[slot]:SetValue(0) end end local function Update(self, unit) -- Update every slot on login, still have issues with it for i = 1, 4 do UpdateSlot(self, i) end end local function Event(self,event,...) if event == "PLAYER_TOTEM_UPDATE" then UpdateSlot(self, ...) end end local function Enable(self, unit) local totem = self.TotemBar if(totem) then self:RegisterEvent("PLAYER_TOTEM_UPDATE" , Event, true) totem.colors = setmetatable(totem.colors or {}, {__index = colors}) delay = totem.delay or delay if totem.Destroy then InitDestroy(self) end TotemFrame:UnregisterAllEvents() return true end end local function Disable(self,unit) local totem = self.TotemBar if(totem) then self:UnregisterEvent("PLAYER_TOTEM_UPDATE", Event) TotemFrame:Show() end end oUF:AddElement("TotemBar",Update,Enable,Disable) |
|
09-10-13, 10:54 PM | #2 |
I'm not at home and can't review your code in detail at the moment, but:
1) DestroyTotem has been a protected function for several major patches now -- addons and macros can't call it, and trying to do so, even using a secure button or macro, will result in an "action blocked" error -- and is now in the same category of "completely off-limits" as CastSpellByName etc. You should remove your OnClick script, as it cannot be made to work. 2) Why are you trying to create your own totem bars element instead of using the totem bars element that is already included in oUF?
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
|
09-11-13, 02:08 AM | #3 | |
Did the totem bar in ouf have the timer thing for totem? Last edited by siweia : 09-11-13 at 04:01 AM. |
||
09-12-13, 11:53 PM | #4 |
By default, no, but it's trivial to add your own OnUpdate script, which you need to do anyway if you want a moving statusbar.
Outside your spawn function: Code:
local TOTEM_COLORS = { [1] = { 0.6, 1, 0.2 }, -- Earth [2] = { 1, 0.6, 0.2 }, -- Fire [3] = { 0.2, 0.8, 1 }, -- Water [4] = { 0.8, 0.4, 1 }, -- Air } local function Totem_OnUpdate(bar, elapsed) local duration = bar.duration - elapsed bar.duration = timeLeft if duration > 0 then bar:SetValue(duration) bar.value:SetFormattedText(SecondsToTimeAbbrev(duration)) end end local function Totems_PostUpdate(element, id, _, name, start, duration, icon) local bar = element[id] bar.duration = duration local color = TOTEM_COLORS[id] bar:SetStatusBarColor(color[1], color[2], color[3]) if duration > 0 then bar:SetAlpha(1) bar:SetMinMaxValues(0, duration) bar:SetScript("OnUpdate", Totem_OnUpdate) else bar:SetAlpha(0.25) bar:SetMinMaxValues(0, 1) bar:SetScript("OnUpdate", nil) bar:SetValue(1) bar.value:SetText("") end end Code:
local Totems = {} for i = 1, MAX_TOTEMS do local bar = CreateFrame("StatusBar", nil, self) bar:SetWidth(50) bar:SetHeight(10) bar:SetPoint("BOTTOMLEFT", self, "TOPLEFT", i * 50, 10) bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar") local value = bar:CreateFontString(nil, "OVERLAY", "TextStatusBarText") value:SetPoint("CENTER") bar.value = value Totems[i] = bar end Totems.PostUpdate = Totems_PostUpdate self.Totems = Totems
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
|
09-13-13, 09:42 AM | #5 | |
Code:
local _, ns = ... local oUF = ns.oUF or oUF if not oUF then return end local total = 0 local delay = 0.01 -- In the order, fire, earth, water, air local colors = { [1] = {.58,.23,.10}, [2] = {.23,.45,.13}, [3] = {.19,.48,.60}, [4] = {.42,.18,.74}, } local GetTotemInfo, SetValue, GetTime = GetTotemInfo, SetValue, GetTime local Timer local function UpdateSlot(self, slot) local totem = self.TotemBar local haveTotem, name, startTime, duration, totemIcon = GetTotemInfo(slot) totem[slot]:SetStatusBarColor(unpack(totem.colors[slot])) totem[slot]:SetValue(0) totem[slot].Time = totem[slot]:CreateFontString(nil, "OVERLAY") totem[slot].Time:SetPoint('CENTER', totem[slot], 'CENTER', 0, 1) totem[slot].Time:SetFont(NAMEPLATE_FONT, 14, "THINOUTLINE") -- If we have a totem then set his value if duration > 0 then -- Status bar update totem[slot]:SetAlpha(1) totem[slot]:SetMinMaxValues(0, duration) totem[slot]:SetScript("OnUpdate", function(self,elapsed) Timer = startTime + duration - GetTime() if Timer > 0 then self:SetValue(Timer) self.Time:SetFormattedText(SecondsToTimeAbbrev(Timer)) end end) else -- There's no need to update because it doesn't have any duration totem[slot]:SetAlpha(0.25) totem[slot]:SetMinMaxValues(0, 1) totem[slot]:SetScript("OnUpdate",nil) totem[slot]:SetValue(1) totem[slot].Time:SetText("") end end local function Update(self, unit) -- Update every slot on login, still have issues with it for i = 1, 4 do UpdateSlot(self, i) end end local function Event(self,event,...) if event == "PLAYER_TOTEM_UPDATE" then UpdateSlot(self, ...) end end local function Enable(self, unit) local totem = self.TotemBar if(totem) then self:RegisterEvent("PLAYER_TOTEM_UPDATE" , Event, true) totem.colors = setmetatable(totem.colors or {}, {__index = colors}) delay = totem.delay or delay TotemFrame:UnregisterAllEvents() return true end end local function Disable(self,unit) local totem = self.TotemBar if(totem) then self:UnregisterEvent("PLAYER_TOTEM_UPDATE", Event) TotemFrame:Show() end end oUF:AddElement("TotemBar",Update,Enable,Disable) This is what I can do on the original code, but the timer would still remain when totem disable. As in the picture, the old timer didn't disapper when the new timer of new totem came out. Last edited by siweia : 09-13-13 at 12:46 PM. |
||
09-13-13, 01:29 PM | #6 |
Don't move the creation of functions, fontstrings, etc. into a function that is called repeatedly -- your code will re-create the same function and create an additional font string every time a totem is cast or destroyed. Both are complete wastes of system resources, and the latter will result in tons of overlapping visible fontstrings that no longer update. Just use the code I gave you. The first section goes directly in your file, outside of any functions, and before your layout's spawn function, so it is loaded exactly one time. The second section goes inside your layout's spawn function, so it is loaded once per frame created, and should be surrounded by a check to make sure it only runs when the frame being created belongs to the player unit. You do not need Enable/Disable functions or any other code, since the code I posted uses oUF's native totem element, and does not create a new element.
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
|
WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Need some help on totembar please |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Switch to Linear Mode |
Hybrid Mode |
Switch to Threaded Mode |
|
|