local DEBUGMODE=false local BUTTONNAME = {buff="BuffaloButton", debuff="DebuffaloButton", weapon = "WeaponBuffaloButton"} local BUTTON_TEMPLATE_NAME = {buff="BuffaloButton", debuff="DebuffaloButton", weapon = "WeaponBuffaloButton"} local FRAME_NAME = {buff="BuffaloFrame", debuff="DebuffaloFrame", weapon = "WeaponBuffaloFrame"} local MININDEX = {buff=0, debuff=0, weapon=0} local MAXINDEX = {buff=31, debuff=15, weapon=1} local TEMPENCHANTGHOSTTEXT = {"MH", "OH"} local BUFF, DEBUFF, WEAPON = "buff", "debuff", "weapon" --cats local GHOST_COLOR = { buff = {r=0.2, g=0.8, b=0.2}, debuff= {r=0.8, g=0.2, b=0.2}, weapon= {r=0.2, g=0.2, b=0.8}, warning={r=1.0, g=0.2, b=0.2}, alpha=0.8} local BUFF_FILTER={buff="HELPFUL", debuff="HARMFUL"} local UPDATETIME = 0.2 local timeSinceWeaponUpdate = 0 local timeSinceBuffUpdate = 0 Buffalo = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceDB-2.0", "AceEvent-2.0", "AceDebug-2.0") Buffalo:RegisterDB("BuffaloDB") Buffalo:RegisterDefaults("profile", BUFFALO_DEFAULT_OPTIONS) local L = AceLibrary("AceLocale-2.2"):new("Buffalo") local slashOptions = { type = 'group', args={ reset = { type='execute', name=L["Reset"], desc=L["Reset"], func = function() Buffalo.Reset(Buffalo) end }, config = { type='execute', name=L["config"], desc=L["Config"], func = function() Buffalo.dewdrop:Open(UIParent, 'children', Buffalo_OptionsTable, 'cursorX', true, 'cursorY', true) end }, } } Buffalo:RegisterChatCommand({"/buffalo"}, slashOptions) local abacus=AceLibrary("Abacus-2.0") local anchors = { buff = {{point="TOPRIGHT", relativeTo="BuffaloFrame" , relativePoint="TOPRIGHT", xOffs=0, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton0" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton1" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton2" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton3" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton4" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton5" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton6" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="TOP", relativeTo="BuffaloButton0" , relativePoint="BOTTOM", xOffs=0, yOffs=-15}, {point="RIGHT", relativeTo="BuffaloButton8" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton9" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton10", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton11", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton12", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton13", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton14", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="TOP", relativeTo="BuffaloButton8" , relativePoint="BOTTOM", xOffs=0, yOffs=-15}, {point="RIGHT", relativeTo="BuffaloButton16" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton17" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton18", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton19", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton20", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton21", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton22", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="TOP", relativeTo="BuffaloButton16" , relativePoint="BOTTOM", xOffs=0, yOffs=-15}, {point="RIGHT", relativeTo="BuffaloButton23" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton24" , relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton25", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton26", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton27", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton28", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="BuffaloButton29", relativePoint="LEFT", xOffs=-5, yOffs=0}, }, debuff = { {point="TOPRIGHT", relativeTo="DebuffaloFrame", relativePoint="TOPRIGHT", xOffs=0, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton0", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton1", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton2", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton3", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton4", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton5", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton6", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="TOP", relativeTo="DebuffButton0", relativePoint="BOTTOM", xOffs=0, yOffs=-15}, {point="RIGHT", relativeTo="DebuffButton8", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton9", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton10", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton11", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton12", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton13", relativePoint="LEFT", xOffs=-5, yOffs=0}, {point="RIGHT", relativeTo="DebuffButton14", relativePoint="LEFT", xOffs=-5, yOffs=0}, }, weapon = { {point="TOPRIGHT", relativeTo="WeaponBuffaloFrame", relativePoint="TOPRIGHT", xOffs=0, yOffs=0}, {point="RIGHT", relativeTo="WeaponBuffalo1", relativePoint="LEFT", xOffs=-5, yOffs=0}, } } function Buffalo.ButtonIterator(cat, n) self=Buffalo -- self:Debug("n:",n) -- self:Debug("min",MININDEX[cat]) -- self:Debug("max",MAXINDEX[cat]) local buttonName, ghostButtonLabel if(not n) then n=MININDEX[cat] buttonName=BUTTONNAME[cat].."0" elseif(MININDEX[cat]<=n and n 0) then buffDuration:Show(); else buffDuration:Hide(); end end local icon = getglobal(button:GetName().."Icon"); icon:SetTexture(GetPlayerBuffTexture(buffIndex)); -- Set color of debuff border based on dispel class. local color; local debuffType = GetPlayerBuffDispelType(GetPlayerBuff(button:GetID(), "HARMFUL")); local debuffSlot = getglobal(button:GetName().."Border"); -- self:Debug("debuffType:",debuffType) -- self:Debug("debuffSlot:",debuffSlot) if ( debuffType ) then color = DebuffTypeColor[debuffType]; color.a=1 elseif(buffIndex >= 0) then color = DebuffTypeColor["none"]; color.a=1 else color = {r=0, g=0, b=0, a=0} end if ( debuffSlot ) then debuffSlot:SetVertexColor(color.r, color.g, color.b, color.a); end -- Set the number of applications of an aura if its a debuff local buffCount = getglobal(button:GetName().."Count"); local count = GetPlayerBuffApplications(buffIndex); if ( count > 1 ) then buffCount:SetText(count); buffCount:Show(); else buffCount:Hide(); end if ( GameTooltip:IsOwned(button) ) then GameTooltip:SetPlayerBuff(buffIndex); end self.printnext=DebuffaloButton1 and (button:GetName() == "DebuffaloButton1") self:Test("Nach _Update") end function Buffalo:WeaponBuffaloFrame_OnUpdate(elapsed) timeSinceWeaponUpdate = timeSinceWeaponUpdate + elapsed if(timeSinceWeaponUpdate > UPDATETIME) then local hasMainHandEnchant, mainHandExpiration, mainHandCharges, hasOffHandEnchant, offHandExpiration, offHandCharges = GetWeaponEnchantInfo(); if(hasMainHandEnchant) then local textureName = GetInventoryItemTexture("player", 16) WeaponBuffaloButton0Icon:SetTexture(textureName) WeaponBuffaloButton0Duration:SetText(self:GetDurationString(mainHandExpiration/1000, "weapon")) WeaponBuffaloButton0Duration:Show() if(mainHandCharges > 0) then WeaponBuffaloButton0Count:SetText(mainHandCharges) WeaponBuffaloButton0Count:Show() else WeaponBuffaloButton0Count:Hide() end WeaponBuffaloButton0:SetID(16) WeaponBuffaloButton0:Show() elseif(self.db.profile.locked) then WeaponBuffaloButton0:Hide() else WeaponBuffaloButton0Icon:SetTexture(nil) end if(hasOffHandEnchant) then local textureName = GetInventoryItemTexture("player", 17) WeaponBuffaloButton1Icon:SetTexture(textureName) WeaponBuffaloButton1Duration:SetText(self:GetDurationString(offHandExpiration/1000, "weapon")) WeaponBuffaloButton1Duration:Show() if(offHandCharges > 0) then WeaponBuffaloButton1Count:SetText(offHandCharges) WeaponBuffaloButton1Count:Show() else WeaponBuffaloButton1Count:Hide() end WeaponBuffaloButton1:SetID(17) WeaponBuffaloButton1:Show() elseif(self.db.profile.locked) then WeaponBuffaloButton1:Hide() else WeaponBuffaloButton1Icon:SetTexture(nil) end timeSinceWeaponUpdate = 0 end end function Buffalo:BuffButton_OnUpdate(elapsed, button) button.timeSinceLastUpdate = button.timeSinceLastUpdate + elapsed if(button.timeSinceLastUpdate > UPDATETIME) then local buffDuration = getglobal(button:GetName().."Duration"); if ( button.untilCancelled == 1 ) then buffDuration:Hide(); return; end local buffIndex = button.buffIndex; local timeLeft = GetPlayerBuffTimeLeft(buffIndex); if ( timeLeft < BUFF_WARNING_TIME and self.db.profile.locked and self.db.profile.flashes[button.cat]) then -- local ghost = getglobal(button:GetName().."_Ghost_Texture") -- ghost:SetTexture(GHOST_COLOR.warning.r, GHOST_COLOR.warning.g, GHOST_COLOR.warning.b) UIFrameFlash(button, 2, 2, timeLeft, false, 0, 0) else UIFrameFlashRemoveFrame(button) button:SetAlpha(1.0); end -- Update duration if(timeLeft>0) then buffDuration:SetText(self:GetDurationString(timeLeft, button.cat)) buffDuration:Show() else buffDuration:Hide() end if ( BuffFrameUpdateTime > 0 ) then return; end if ( GameTooltip:IsOwned(button) ) then GameTooltip:SetPlayerBuff(buffIndex); end button.timeSinceLastUpdate = 0 end end function Buffalo:GetDurationString(seconds, cat) if(not self.db.profile.verboseTimers[cat])then return SecondsToTimeAbbrev(seconds) else if(seconds > 3600) then return abacus:FormatDurationCondensed(seconds, self.db.profile.whiteTimers[cat], true) else return abacus:FormatDurationCondensed(seconds, self.db.profile.whiteTimers[cat], false) end end end function Buffalo:SetShowGhostBuffFrames(value) if(value) then for cat, templateName in pairs(BUTTON_TEMPLATE_NAME) do for _, buttonName, ghostButtonLabel in self.ButtonIterator, cat, nil do local label = getglobal(buttonName.."_Ghost_Label") local ghost = getglobal(buttonName.."_Ghost_Texture") getglobal(buttonName):Show() label:SetText(ghostButtonLabel) label:Show() ghost:SetTexture(GHOST_COLOR[cat].r, GHOST_COLOR[cat].g, GHOST_COLOR[cat].b, GHOST_COLOR.alpha) ghost:Show() end end else for cat, templateName in pairs(BUTTON_TEMPLATE_NAME) do for _, buttonName in self.ButtonIterator, cat, nil do local label = getglobal(buttonName.."_Ghost_Label") local ghost = getglobal(buttonName.."_Ghost_Texture") label:Hide() ghost:Hide() end end end end function Buffalo:SavePos(cat) local frame=getglobal(FRAME_NAME[cat]) self.db.profile.xPos[cat] = frame:GetLeft() self.db.profile.yPos[cat] = frame:GetBottom() end function Buffalo:SetScale(scale, cat) for i, buttonName in self.ButtonIterator, cat, nil do getglobal(buttonName):SetScale(scale) end local frame = getglobal(FRAME_NAME[cat]) frame:ClearAllPoints() frame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", self.db.profile.xPos[cat], self.db.profile.yPos[cat]) self.db.profile.scale[cat] = scale end --[[ Sets the distance between the buff buttons. padding - the distance in pixels cat - either "buff", "debuff" or "weapon" direction - either "x" or "y" ]] function Buffalo:SetPadding(padding, cat, direction) self.db.profile.padding[cat][direction] = padding self:FillAnchors(cat) end function Buffalo:GetGrowRightCoeff(cat) if self.db.profile.growRight[cat] then return 1 else return -1 end end function Buffalo:GetGrowUpwardsCoeff(cat) if self.db.profile.growUpwards[cat] then return 1 else return -1 end end --[[ Sets the direction in which the buffs grow direction - either "right", "left", "up" or "down" cat - either "buff", "debuff" or "weapon" ]] function Buffalo:SetGrowthDirection(direction, cat) if(direction == "right") then self.db.profile.growRight[cat] = true elseif(direction == "left") then self.db.profile.growRight[cat] = nil elseif(direction == "up") then self.db.profile.growUpwards[cat] = true elseif(direction == "down") then self.db.profile.growUpwards[cat] = nil end self:FillAnchors(cat) end --[[ These set the number of rows/cols for the given cat cat - either "buff", "debuff" or "weapon" ]] function Buffalo:SetRows(rows, cat) self.db.profile.rows[cat] = rows self:FillAnchors(cat) end function Buffalo:SetCols(cols, cat) self.db.profile.cols[cat] = cols self:FillAnchors(cat) end function Buffalo:SetGrowHorizontalFirst(value, cat) self.db.profile.growHorizontalFirst[cat] = value or false self:FillAnchors(cat) end function Buffalo:ApplyAnchors(cat) if(self.db.profile.locked) then BuffButton0:SetMovable(true) BuffButton16:SetMovable(true) TempEnchant1:SetMovable(true) end if(type(cat) == "nil") then self:ApplyAnchors("buff") self:ApplyAnchors("debuff") self:ApplyAnchors("weapon") return end local frame = getglobal(FRAME_NAME[cat]) frame:ClearAllPoints() frame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", self.db.profile.xPos[cat], self.db.profile.yPos[cat]) for i, buttonName in self.ButtonIterator, cat, nil do local button = getglobal(buttonName) local anchor = anchors[cat][i+1] button:ClearAllPoints() button:SetPoint(anchor.point, anchor.relativeTo, anchor.relativePoint, anchor.xOffs, anchor.yOffs) end if(self.db.profile.locked) then BuffButton0:SetMovable(false) BuffButton16:SetMovable(false) TempEnchant1:SetMovable(false) end for cat, _ in pairs(BUTTON_TEMPLATE_NAME) do self:SetScale(self.db.profile.scale[cat], cat) end end function Buffalo:FillAnchors(cat) if(type(cat) == "nil") then self:FillAnchors("buff") self:FillAnchors("debuff") self:FillAnchors("weapon") return end for i, buttonName in self.ButtonIterator, cat, nil do -- self:Debug("cat: ", cat) -- self:Debug("i+1: ", i+1) local anchor = anchors[cat][i+1] if(i==MININDEX[cat]) then -- first button in this category anchor.point="TOPRIGHT" anchor.relativeTo=FRAME_NAME[cat] anchor.relativePoint="TOPRIGHT" anchor.xOffs=0 anchor.yOffs=0 else local anchorPoint, relativePoint, switchAnchorPoint, switchRelativePoint, limit = self:GetAnchorInfo(cat) if i==15 and false then self:Debug("Button: ", i) self:Debug("MinIndex: ", MININDEX[cat]) self:Debug("limit: ", limit) end if(mod((i-MININDEX[cat]), limit) == 0 or (limit==1)) then --[[and not (i==MAXINDEX[cat])]] anchor.point = switchAnchorPoint anchor.relativeTo = BUTTONNAME[cat]..(i-limit) anchor.relativePoint = switchRelativePoint anchor.xOffs = (not self.db.profile.growHorizontalFirst[cat] and self:GetGrowRightCoeff(cat)*self.db.profile.padding[cat].x) or 0 anchor.yOffs = (self.db.profile.growHorizontalFirst[cat] and self:GetGrowUpwardsCoeff(cat)*self.db.profile.padding[cat].y) or 0 else anchor.point = anchorPoint anchor.relativeTo = BUTTONNAME[cat]..(i-1) anchor.relativePoint = relativePoint anchor.xOffs = (self.db.profile.growHorizontalFirst[cat] and self:GetGrowRightCoeff(cat)*self.db.profile.padding[cat].x) or 0 anchor.yOffs = (not self.db.profile.growHorizontalFirst[cat] and self:GetGrowUpwardsCoeff(cat)*self.db.profile.padding[cat].y) or 0 end end end self:ApplyAnchors(cat) end --[[ returns the needed information to determine which button is to be attached to which button in what way. wwwwwww *anchorPoint - the anchorpoint of the current button *relativePoint - the point where we attach it to *switchAnchorPoint, switchRelativePoint - like above, but for when the row / column switches ("linebreak") *limit - the number of columns / rows where to perform a switch ]] function Buffalo:GetAnchorInfo(cat) local anchorPoint, relativePoint local switchAnchorPoint, switchRelativePoint local limit if(self.db.profile.growHorizontalFirst[cat]) then limit = self.db.profile.cols[cat] if(self.db.profile.growRight[cat]) then anchorPoint = "LEFT" relativePoint = "RIGHT" else anchorPoint = "RIGHT" relativePoint = "LEFT" end if(self.db.profile.growUpwards[cat]) then switchAnchorPoint = "BOTTOM" switchRelativePoint = "TOP" else switchAnchorPoint = "TOP" switchRelativePoint = "BOTTOM" end else limit = self.db.profile.rows[cat] if(self.db.profile.growRight[cat]) then switchAnchorPoint = "LEFT" switchRelativePoint = "RIGHT" else switchAnchorPoint = "RIGHT" switchRelativePoint = "LEFT" end if(self.db.profile.growUpwards[cat]) then anchorPoint = "BOTTOM" relativePoint = "TOP" else anchorPoint = "TOP" relativePoint = "BOTTOM" end end return anchorPoint, relativePoint, switchAnchorPoint, switchRelativePoint, limit end function Buffalo:ToggleLock(value) for cat, frameName in pairs(FRAME_NAME) do local frame = getglobal(frameName) frame:SetMovable(not value) end self.db.profile.locked = value self:SetShowGhostBuffFrames(not value) end function Buffalo:ToggleHide(value, cat) local frame = getglobal(FRAME_NAME[cat]) self.db.profile.hide[cat] = value if(value) then frame:Hide() else frame:Show() end end function Buffalo:Reset() self:ResetDB("profile") self:OnProfileEnable() end function Buffalo:BuffButton_OnClick(button) if(IsAltKeyDown())then if(not button.buffFilter) then self.dewdrop:Open(button, 'children', Buffalo_OptionsTable.args.weapon) elseif(button.buffFilter == "HELPFUL") then self.dewdrop:Open(button, 'children', Buffalo_OptionsTable.args.buffs) elseif(button.buffFilter == "HARMFUL") then self.dewdrop:Open(button, 'children', Buffalo_OptionsTable.args.debuffs) end else CancelPlayerBuff(button.buffIndex); end end function Buffalo:PrintAnchor(frame) if(not self:IsDebugging()) then return end point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint() self:Debug("Point: ", point or "nil") self:Debug("RelativeTo: ", (relativeTo and relativeTo:GetName()) or "nil") self:Debug("RelativePoint: ", relativePoint or "nil") self:Debug("X-Offset:", xOfs or "nil") self:Debug("Y-Offset:", yOfs or "nil") local cx, cy = frame:GetCenter() self:Debug("Center: ", cx, cy) end function Buffalo:Test(position) if true then return end if(DebuffaloButton1Border) then local r,g,b,a = DebuffaloButton1Border:GetVertexColor() self:Debug(position, a) self.printnext=false end end