init
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local mod = E:GetModule("AFK")
|
||||
local CH = E:GetModule("Chat")
|
||||
|
||||
--Lua functions
|
||||
local _G = _G
|
||||
local tostring = tostring
|
||||
local floor = math.floor
|
||||
local format, gsub, sub, upper = string.format, string.gsub, string.sub, string.upper
|
||||
--WoW API / Variables
|
||||
local ChatHistory_GetAccessID = ChatHistory_GetAccessID
|
||||
local Chat_GetChatCategory = Chat_GetChatCategory
|
||||
local CinematicFrame = CinematicFrame
|
||||
local CreateFrame = CreateFrame
|
||||
local GetBattlefieldStatus = GetBattlefieldStatus
|
||||
local GetColoredName = GetColoredName
|
||||
local GetGuildInfo = GetGuildInfo
|
||||
local GetScreenHeight = GetScreenHeight
|
||||
local GetScreenWidth = GetScreenWidth
|
||||
local GetTime = GetTime
|
||||
local InCombatLockdown = InCombatLockdown
|
||||
local IsInGuild = IsInGuild
|
||||
local IsShiftKeyDown = IsShiftKeyDown
|
||||
local MoveViewLeftStart = MoveViewLeftStart
|
||||
local MoveViewLeftStop = MoveViewLeftStop
|
||||
local MovieFrame = MovieFrame
|
||||
local Screenshot = Screenshot
|
||||
local SetCVar = SetCVar
|
||||
local UnitCastingInfo = UnitCastingInfo
|
||||
local UnitIsAFK = UnitIsAFK
|
||||
|
||||
local AFK, DND = AFK, DND
|
||||
local CHAT_BN_CONVERSATION_GET_LINK = CHAT_BN_CONVERSATION_GET_LINK
|
||||
local MAX_WOW_CHAT_CHANNELS = MAX_WOW_CHAT_CHANNELS
|
||||
|
||||
local cameraSpeed = 0.035
|
||||
|
||||
local ignoreKeys = {
|
||||
["LALT"] = true,
|
||||
["LSHIFT"] = true,
|
||||
["RSHIFT"] = true
|
||||
}
|
||||
local printKeys = {
|
||||
["PRINTSCREEN"] = true,
|
||||
}
|
||||
|
||||
if E.isMacClient then
|
||||
printKeys[_G["KEY_PRINTSCREEN_MAC"]] = true
|
||||
end
|
||||
|
||||
function mod:UpdateTimer()
|
||||
local time = GetTime() - self.startTime
|
||||
self.AFKMode.bottom.time:SetFormattedText("%02d:%02d", floor(time / 60), time % 60)
|
||||
end
|
||||
|
||||
local function StopAnimation(self)
|
||||
self:SetSequenceTime(0, 0)
|
||||
self:SetScript("OnUpdate", nil)
|
||||
self:SetScript("OnAnimFinished", nil)
|
||||
end
|
||||
|
||||
local function UpdateAnimation(self, elapsed)
|
||||
self.animTime = self.animTime + (elapsed * 1000)
|
||||
self:SetSequenceTime(67, self.animTime)
|
||||
|
||||
if self.animTime >= 3000 then
|
||||
StopAnimation(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function OnAnimFinished(self)
|
||||
if self.animTime > 500 then
|
||||
StopAnimation(self)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:SetAFK(status)
|
||||
if status and not self.isAFK then
|
||||
if InspectFrame then
|
||||
InspectFrame:Hide()
|
||||
end
|
||||
|
||||
UIParent:Hide()
|
||||
self.AFKMode:Show()
|
||||
|
||||
E.global.afkEnabled = true
|
||||
|
||||
MoveViewLeftStart(cameraSpeed)
|
||||
|
||||
if IsInGuild() then
|
||||
local guildName, guildRankName = GetGuildInfo("player")
|
||||
self.AFKMode.bottom.guild:SetFormattedText("%s - %s", guildName, guildRankName)
|
||||
else
|
||||
self.AFKMode.bottom.guild:SetText(L["No Guild"])
|
||||
end
|
||||
|
||||
self.startTime = GetTime()
|
||||
self.timer = self:ScheduleRepeatingTimer("UpdateTimer", 1)
|
||||
|
||||
self.AFKMode.chat:RegisterEvent("CHAT_MSG_WHISPER")
|
||||
self.AFKMode.chat:RegisterEvent("CHAT_MSG_BN_WHISPER")
|
||||
self.AFKMode.chat:RegisterEvent("CHAT_MSG_BN_CONVERSATION")
|
||||
self.AFKMode.chat:RegisterEvent("CHAT_MSG_GUILD")
|
||||
|
||||
self.AFKMode.bottom.model:SetModelScale(1)
|
||||
self.AFKMode.bottom.model:RefreshUnit()
|
||||
self.AFKMode.bottom.model:SetModelScale(0.8)
|
||||
|
||||
self.AFKMode.bottom.model.animTime = 0
|
||||
self.AFKMode.bottom.model:SetScript("OnUpdate", UpdateAnimation)
|
||||
self.AFKMode.bottom.model:SetScript("OnAnimFinished", OnAnimFinished)
|
||||
|
||||
self.isAFK = true
|
||||
elseif not status and self.isAFK then
|
||||
self.AFKMode:Hide()
|
||||
UIParent:Show()
|
||||
|
||||
E.global.afkEnabled = nil
|
||||
|
||||
MoveViewLeftStop()
|
||||
|
||||
self:CancelTimer(self.timer)
|
||||
self.AFKMode.bottom.time:SetText("00:00")
|
||||
|
||||
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_WHISPER")
|
||||
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_BN_WHISPER")
|
||||
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_BN_CONVERSATION")
|
||||
self.AFKMode.chat:UnregisterEvent("CHAT_MSG_GUILD")
|
||||
self.AFKMode.chat:Clear()
|
||||
|
||||
self.isAFK = false
|
||||
end
|
||||
end
|
||||
|
||||
function mod:OnEvent(event, ...)
|
||||
if event == "PLAYER_REGEN_DISABLED" or event == "LFG_PROPOSAL_SHOW" or event == "UPDATE_BATTLEFIELD_STATUS" then
|
||||
if event == "UPDATE_BATTLEFIELD_STATUS" then
|
||||
local status = GetBattlefieldStatus(...)
|
||||
if status == "confirm" then
|
||||
self:SetAFK(false)
|
||||
end
|
||||
else
|
||||
self:SetAFK(false)
|
||||
end
|
||||
|
||||
if event == "PLAYER_REGEN_DISABLED" then
|
||||
self:RegisterEvent("PLAYER_REGEN_ENABLED", "OnEvent")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == "PLAYER_REGEN_ENABLED" then
|
||||
self:ScheduleTimer("OnEvent", 10)
|
||||
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
|
||||
return
|
||||
end
|
||||
|
||||
if not E.db.general.afk then return end
|
||||
if InCombatLockdown() or CinematicFrame:IsShown() or MovieFrame:IsShown() then return end
|
||||
if UnitCastingInfo("player") ~= nil then
|
||||
--Don't activate afk if player is crafting stuff, check back in 30 seconds
|
||||
self:ScheduleTimer("OnEvent", 30)
|
||||
return
|
||||
end
|
||||
|
||||
self:SetAFK(UnitIsAFK("player"))
|
||||
end
|
||||
|
||||
function mod:Toggle()
|
||||
if E.db.general.afk then
|
||||
self:RegisterEvent("PLAYER_FLAGS_CHANGED", "OnEvent")
|
||||
self:RegisterEvent("PLAYER_REGEN_DISABLED", "OnEvent")
|
||||
self:RegisterEvent("LFG_PROPOSAL_SHOW", "OnEvent")
|
||||
self:RegisterEvent("UPDATE_BATTLEFIELD_STATUS", "OnEvent")
|
||||
|
||||
SetCVar("autoClearAFK", "1")
|
||||
else
|
||||
self:UnregisterEvent("PLAYER_FLAGS_CHANGED")
|
||||
self:UnregisterEvent("PLAYER_REGEN_DISABLED")
|
||||
self:UnregisterEvent("LFG_PROPOSAL_SHOW")
|
||||
self:UnregisterEvent("UPDATE_BATTLEFIELD_STATUS")
|
||||
|
||||
self:CancelAllTimers()
|
||||
end
|
||||
end
|
||||
|
||||
local function OnKeyDown(_, key)
|
||||
if ignoreKeys[key] then return end
|
||||
|
||||
if printKeys[key] then
|
||||
Screenshot()
|
||||
else
|
||||
mod:SetAFK(false)
|
||||
mod:ScheduleTimer("OnEvent", 60)
|
||||
end
|
||||
end
|
||||
|
||||
local function Chat_OnMouseWheel(self, delta)
|
||||
if delta > 0 then
|
||||
if IsShiftKeyDown() then
|
||||
self:ScrollToTop()
|
||||
else
|
||||
self:ScrollUp()
|
||||
end
|
||||
elseif delta < 0 then
|
||||
if IsShiftKeyDown() then
|
||||
self:ScrollToBottom()
|
||||
else
|
||||
self:ScrollDown()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Chat_OnEvent(self, event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)
|
||||
local coloredName = GetColoredName(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
|
||||
local chatType = sub(event, 10)
|
||||
local info = ChatTypeInfo[chatType]
|
||||
|
||||
local chatGroup = Chat_GetChatCategory(chatType)
|
||||
local chatTarget
|
||||
if chatGroup == "BN_CONVERSATION" then
|
||||
chatTarget = tostring(arg8)
|
||||
elseif chatGroup == "WHISPER" or chatGroup == "BN_WHISPER" then
|
||||
chatTarget = upper(arg2)
|
||||
end
|
||||
|
||||
local playerLink
|
||||
if chatType ~= "BN_WHISPER" and chatType ~= "BN_CONVERSATION" then
|
||||
playerLink = "|Hplayer:"..arg2..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h"
|
||||
else
|
||||
playerLink = "|HBNplayer:"..arg2..":"..arg13..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h"
|
||||
end
|
||||
|
||||
arg1 = gsub(arg1, "%%", "%%%%")
|
||||
|
||||
local body = format(_G["CHAT_"..chatType.."_GET"]..arg1, playerLink.."["..coloredName.."]".."|h")
|
||||
|
||||
if chatGroup == "BN_CONVERSATION" then
|
||||
body = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8)..body
|
||||
end
|
||||
|
||||
local accessID = ChatHistory_GetAccessID(chatGroup, chatTarget)
|
||||
local typeID = ChatHistory_GetAccessID(chatType, chatTarget)
|
||||
|
||||
if E.db.chat.shortChannels then
|
||||
body = gsub(body, "|Hchannel:(.-)|h%[(.-)%]|h", CH.ShortChannel)
|
||||
body = gsub(body, "^(.-|h) "..L["whispers"], "%1")
|
||||
body = gsub(body, "<"..AFK..">", "[|cffFF0000"..AFK.."|r] ")
|
||||
body = gsub(body, "<"..DND..">", "[|cffE7E716"..DND.."|r] ")
|
||||
body = gsub(body, "%[BN_CONVERSATION:", "%[".."")
|
||||
end
|
||||
|
||||
if CH.db ~= nil and CH.db.timeStampFormat ~= "NONE" then
|
||||
local timeStamp = BetterDate(CH.db.timeStampFormat, time())
|
||||
|
||||
if CH.db.useCustomTimeColor then
|
||||
local color = CH.db.customTimeColor
|
||||
local hexColor = E:RGBToHex(color.r, color.g, color.b)
|
||||
body = format("%s[%s]|r %s", hexColor, timeStamp, body)
|
||||
else
|
||||
body = format("[%s] %s", timeStamp, body)
|
||||
end
|
||||
end
|
||||
|
||||
self:AddMessage(body, info.r, info.g, info.b, info.id, false, accessID, typeID)
|
||||
end
|
||||
|
||||
function mod:Initialize()
|
||||
self.AFKMode = CreateFrame("Frame", "ElvUIAFKFrame")
|
||||
self.AFKMode:SetFrameLevel(1)
|
||||
self.AFKMode:SetScale(UIParent:GetScale())
|
||||
self.AFKMode:SetAllPoints(UIParent)
|
||||
self.AFKMode:Hide()
|
||||
self.AFKMode:EnableKeyboard(true)
|
||||
self.AFKMode:SetScript("OnKeyDown", OnKeyDown)
|
||||
|
||||
self.AFKMode.chat = CreateFrame("ScrollingMessageFrame", "AFKChat", self.AFKMode)
|
||||
self.AFKMode.chat:Size(500, 200)
|
||||
self.AFKMode.chat:Point("TOPLEFT", self.AFKMode, "TOPLEFT", 4, -3)
|
||||
self.AFKMode.chat:FontTemplate()
|
||||
self.AFKMode.chat:SetJustifyH("LEFT")
|
||||
self.AFKMode.chat:SetMaxLines(500)
|
||||
self.AFKMode.chat:EnableMouseWheel(true)
|
||||
self.AFKMode.chat:SetFading(false)
|
||||
self.AFKMode.chat:SetMovable(true)
|
||||
self.AFKMode.chat:EnableMouse(true)
|
||||
self.AFKMode.chat:SetClampedToScreen(true)
|
||||
self.AFKMode.chat:SetClampRectInsets(-4, 3, 3, -4)
|
||||
self.AFKMode.chat:RegisterForDrag("LeftButton")
|
||||
self.AFKMode.chat:SetScript("OnDragStart", self.AFKMode.chat.StartMoving)
|
||||
self.AFKMode.chat:SetScript("OnDragStop", self.AFKMode.chat.StopMovingOrSizing)
|
||||
self.AFKMode.chat:SetScript("OnMouseWheel", Chat_OnMouseWheel)
|
||||
self.AFKMode.chat:SetScript("OnEvent", Chat_OnEvent)
|
||||
|
||||
self.AFKMode.bottom = CreateFrame("Frame", nil, self.AFKMode)
|
||||
self.AFKMode.bottom:SetFrameLevel(0)
|
||||
self.AFKMode.bottom:SetTemplate("Transparent")
|
||||
self.AFKMode.bottom:Point("BOTTOM", self.AFKMode, "BOTTOM", 0, -E.Border)
|
||||
self.AFKMode.bottom:Width(GetScreenWidth() + (E.Border*2))
|
||||
self.AFKMode.bottom:Height(GetScreenHeight() * 0.1)
|
||||
|
||||
self.AFKMode.bottom.logo = self.AFKMode:CreateTexture(nil, "OVERLAY")
|
||||
self.AFKMode.bottom.logo:Size(320, 150)
|
||||
self.AFKMode.bottom.logo:Point("CENTER", self.AFKMode.bottom, "CENTER", 0, 50)
|
||||
self.AFKMode.bottom.logo:SetTexture(E.Media.Textures.Logo)
|
||||
|
||||
self.AFKMode.bottom.faction = self.AFKMode.bottom:CreateTexture(nil, "OVERLAY")
|
||||
self.AFKMode.bottom.faction:Point("BOTTOMLEFT", self.AFKMode.bottom, "BOTTOMLEFT", -20, -16)
|
||||
self.AFKMode.bottom.faction:SetTexture("Interface\\AddOns\\ElvUI\\media\\textures\\"..E.myfaction.."-Logo")
|
||||
self.AFKMode.bottom.faction:Size(140)
|
||||
|
||||
local classColor = E.media.herocolor
|
||||
self.AFKMode.bottom.name = self.AFKMode.bottom:CreateFontString(nil, "OVERLAY")
|
||||
self.AFKMode.bottom.name:FontTemplate(nil, 20)
|
||||
self.AFKMode.bottom.name:SetFormattedText("%s - %s", E.myname, E.myrealm)
|
||||
self.AFKMode.bottom.name:Point("TOPLEFT", self.AFKMode.bottom.faction, "TOPRIGHT", -10, -28)
|
||||
self.AFKMode.bottom.name:SetTextColor(classColor.r, classColor.g, classColor.b)
|
||||
|
||||
self.AFKMode.bottom.guild = self.AFKMode.bottom:CreateFontString(nil, "OVERLAY")
|
||||
self.AFKMode.bottom.guild:FontTemplate(nil, 20)
|
||||
self.AFKMode.bottom.guild:SetText(L["No Guild"])
|
||||
self.AFKMode.bottom.guild:Point("TOPLEFT", self.AFKMode.bottom.name, "BOTTOMLEFT", 0, -6)
|
||||
self.AFKMode.bottom.guild:SetTextColor(0.7, 0.7, 0.7)
|
||||
|
||||
self.AFKMode.bottom.time = self.AFKMode.bottom:CreateFontString(nil, "OVERLAY")
|
||||
self.AFKMode.bottom.time:FontTemplate(nil, 20)
|
||||
self.AFKMode.bottom.time:SetText("00:00")
|
||||
self.AFKMode.bottom.time:Point("TOPLEFT", self.AFKMode.bottom.guild, "BOTTOMLEFT", 0, -6)
|
||||
self.AFKMode.bottom.time:SetTextColor(0.7, 0.7, 0.7)
|
||||
|
||||
self.AFKMode.bottom.model = CreateFrame("PlayerModel", "ElvUIAFKPlayerModel", self.AFKMode.bottom)
|
||||
self.AFKMode.bottom.model:Point("BOTTOMRIGHT", self.AFKMode.bottom, "BOTTOMRIGHT", 120, -100)
|
||||
self.AFKMode.bottom.model:Size(800)
|
||||
self.AFKMode.bottom.model:SetFacing(6)
|
||||
self.AFKMode.bottom.model:SetUnit("player")
|
||||
|
||||
if E.db.general.afk then
|
||||
self:Toggle()
|
||||
end
|
||||
|
||||
self.Initialized = true
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
mod:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(mod:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,262 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local M = E:GetModule("Misc")
|
||||
local CH = E:GetModule("Chat")
|
||||
|
||||
--Lua functions
|
||||
local select, unpack = select, unpack
|
||||
local format, gmatch, gsub, lower, match = string.format, string.gmatch, string.gsub, string.lower, string.match
|
||||
--WoW API / Variables
|
||||
local GetPlayerInfoByGUID = GetPlayerInfoByGUID
|
||||
local WorldFrame = WorldFrame
|
||||
local WorldGetChildren = WorldFrame.GetChildren
|
||||
local WorldGetNumChildren = WorldFrame.GetNumChildren
|
||||
|
||||
--Message caches
|
||||
local messageToGUID = {}
|
||||
local messageToSender = {}
|
||||
|
||||
function M:UpdateBubbleBorder()
|
||||
if not self.text then return end
|
||||
|
||||
if E.private.general.chatBubbles == "backdrop" then
|
||||
if E.PixelMode then
|
||||
self:SetBackdropBorderColor(self.text:GetTextColor())
|
||||
else
|
||||
local r, g, b = self.text:GetTextColor()
|
||||
self.bordertop:SetTexture(r, g, b)
|
||||
self.borderbottom:SetTexture(r, g, b)
|
||||
self.borderleft:SetTexture(r, g, b)
|
||||
self.borderright:SetTexture(r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
local text = self.text:GetText()
|
||||
if self.Name then
|
||||
self.Name:SetText("") --Always reset it
|
||||
if text and E.private.general.chatBubbleName then
|
||||
M:AddChatBubbleName(self, messageToGUID[text], messageToSender[text])
|
||||
end
|
||||
end
|
||||
|
||||
if E.private.chat.enable and E.private.general.classColorMentionsSpeech then
|
||||
if text and match(text, "%s-%S+%s*") then
|
||||
local classColorTable, lowerCaseWord, isFirstWord, rebuiltString, tempWord, wordMatch, classMatch
|
||||
|
||||
for word in gmatch(text, "%s-%S+%s*") do
|
||||
tempWord = gsub(word, "^[%s%p]-([^%s%p]+)([%-]?[^%s%p]-)[%s%p]*$", "%1%2")
|
||||
lowerCaseWord = lower(tempWord)
|
||||
|
||||
classMatch = CH.ClassNames[lowerCaseWord]
|
||||
wordMatch = classMatch and lowerCaseWord
|
||||
|
||||
if wordMatch and not E.global.chat.classColorMentionExcludedNames[wordMatch] then
|
||||
classColorTable = E.media.herocolor
|
||||
word = gsub(word, gsub(tempWord, "%-", "%%-"), format("\124cff%.2x%.2x%.2x%s\124r", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255, tempWord))
|
||||
end
|
||||
|
||||
if not isFirstWord then
|
||||
rebuiltString = word
|
||||
isFirstWord = true
|
||||
else
|
||||
rebuiltString = format("%s%s", rebuiltString, word)
|
||||
end
|
||||
end
|
||||
|
||||
if rebuiltString then
|
||||
self.text:SetText(rebuiltString)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:AddChatBubbleName(chatBubble, guid, name)
|
||||
if not name then return end
|
||||
|
||||
local color
|
||||
if guid and guid ~= "" then
|
||||
local _, class = GetPlayerInfoByGUID(guid)
|
||||
if class then
|
||||
color = E:RGBToHex(E.media.herocolor.r, E.media.herocolor.g, E.media.herocolor.b)
|
||||
end
|
||||
else
|
||||
color = "|cffffffff"
|
||||
end
|
||||
|
||||
chatBubble.Name:SetFormattedText("%s%s|r", color, name)
|
||||
end
|
||||
|
||||
function M:SkinBubble(frame)
|
||||
local mult = E.mult * UIParent:GetScale()
|
||||
for i = 1, frame:GetNumRegions() do
|
||||
local region = select(i, frame:GetRegions())
|
||||
if region:IsObjectType("Texture") then
|
||||
region:SetTexture(nil)
|
||||
elseif region:IsObjectType("FontString") then
|
||||
frame.text = region
|
||||
end
|
||||
end
|
||||
|
||||
local name = frame:CreateFontString(nil, "OVERLAY")
|
||||
if E.private.general.chatBubbles == "backdrop" then
|
||||
name:SetPoint("TOPLEFT", 5, E.PixelMode and 15 or 18)
|
||||
else
|
||||
name:SetPoint("TOPLEFT", 5, 6)
|
||||
end
|
||||
name:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -5, -5)
|
||||
name:SetJustifyH("LEFT")
|
||||
name:FontTemplate(E.Libs.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize * 0.85, E.private.general.chatBubbleFontOutline)
|
||||
frame.Name = name
|
||||
|
||||
if E.private.general.chatBubbles == "backdrop" then
|
||||
if E.PixelMode then
|
||||
frame:SetBackdrop({
|
||||
bgFile = E.media.blankTex,
|
||||
edgeFile = E.media.blankTex,
|
||||
tile = false, tileSize = 0, edgeSize = mult,
|
||||
insets = {left = 0, right = 0, top = 0, bottom = 0}
|
||||
})
|
||||
frame:SetBackdropColor(unpack(E.media.backdropfadecolor))
|
||||
frame:SetBackdropBorderColor(0, 0, 0)
|
||||
else
|
||||
frame:SetBackdrop(nil)
|
||||
end
|
||||
|
||||
local r, g, b = frame.text:GetTextColor()
|
||||
if not E.PixelMode then
|
||||
local mult2 = mult * 2
|
||||
local mult3 = mult * 3
|
||||
|
||||
frame.backdrop = frame:CreateTexture(nil, "BACKGROUND")
|
||||
frame.backdrop:SetAllPoints(frame)
|
||||
frame.backdrop:SetTexture(unpack(E.media.backdropfadecolor))
|
||||
|
||||
frame.bordertop = frame:CreateTexture(nil, "ARTWORK")
|
||||
frame.bordertop:SetPoint("TOPLEFT", frame, "TOPLEFT", -mult2, mult2)
|
||||
frame.bordertop:SetPoint("TOPRIGHT", frame, "TOPRIGHT", mult2, mult2)
|
||||
frame.bordertop:SetHeight(mult)
|
||||
frame.bordertop:SetTexture(r, g, b)
|
||||
|
||||
frame.bordertop.backdrop = frame:CreateTexture(nil, "BORDER")
|
||||
frame.bordertop.backdrop:SetPoint("TOPLEFT", frame.bordertop, "TOPLEFT", -mult, mult)
|
||||
frame.bordertop.backdrop:SetPoint("TOPRIGHT", frame.bordertop, "TOPRIGHT", mult, mult)
|
||||
frame.bordertop.backdrop:SetHeight(mult3)
|
||||
frame.bordertop.backdrop:SetTexture(0, 0, 0)
|
||||
|
||||
frame.borderbottom = frame:CreateTexture(nil, "ARTWORK")
|
||||
frame.borderbottom:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", -mult2, -mult2)
|
||||
frame.borderbottom:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", mult2, -mult2)
|
||||
frame.borderbottom:SetHeight(mult)
|
||||
frame.borderbottom:SetTexture(r, g, b)
|
||||
|
||||
frame.borderbottom.backdrop = frame:CreateTexture(nil, "BORDER")
|
||||
frame.borderbottom.backdrop:SetPoint("BOTTOMLEFT", frame.borderbottom, "BOTTOMLEFT", -mult, -mult)
|
||||
frame.borderbottom.backdrop:SetPoint("BOTTOMRIGHT", frame.borderbottom, "BOTTOMRIGHT", mult, -mult)
|
||||
frame.borderbottom.backdrop:SetHeight(mult3)
|
||||
frame.borderbottom.backdrop:SetTexture(0, 0, 0)
|
||||
|
||||
frame.borderleft = frame:CreateTexture(nil, "ARTWORK")
|
||||
frame.borderleft:SetPoint("TOPLEFT", frame, "TOPLEFT", -mult2, mult2)
|
||||
frame.borderleft:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", mult2, -mult2)
|
||||
frame.borderleft:SetWidth(mult)
|
||||
frame.borderleft:SetTexture(r, g, b)
|
||||
|
||||
frame.borderleft.backdrop = frame:CreateTexture(nil, "BORDER")
|
||||
frame.borderleft.backdrop:SetPoint("TOPLEFT", frame.borderleft, "TOPLEFT", -mult, mult)
|
||||
frame.borderleft.backdrop:SetPoint("BOTTOMLEFT", frame.borderleft, "BOTTOMLEFT", -mult, -mult)
|
||||
frame.borderleft.backdrop:SetWidth(mult3)
|
||||
frame.borderleft.backdrop:SetTexture(0, 0, 0)
|
||||
|
||||
frame.borderright = frame:CreateTexture(nil, "ARTWORK")
|
||||
frame.borderright:SetPoint("TOPRIGHT", frame, "TOPRIGHT", mult2, mult2)
|
||||
frame.borderright:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -mult2, -mult2)
|
||||
frame.borderright:SetWidth(mult)
|
||||
frame.borderright:SetTexture(r, g, b)
|
||||
|
||||
frame.borderright.backdrop = frame:CreateTexture(nil, "BORDER")
|
||||
frame.borderright.backdrop:SetPoint("TOPRIGHT", frame.borderright, "TOPRIGHT", mult, mult)
|
||||
frame.borderright.backdrop:SetPoint("BOTTOMRIGHT", frame.borderright, "BOTTOMRIGHT", mult, -mult)
|
||||
frame.borderright.backdrop:SetWidth(mult3)
|
||||
frame.borderright.backdrop:SetTexture(0, 0, 0)
|
||||
else
|
||||
frame:SetBackdropColor(unpack(E.media.backdropfadecolor))
|
||||
frame:SetBackdropBorderColor(r, g, b)
|
||||
end
|
||||
|
||||
frame.text:FontTemplate(E.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize, E.private.general.chatBubbleFontOutline)
|
||||
elseif E.private.general.chatBubbles == "backdrop_noborder" then
|
||||
frame:SetBackdrop(nil)
|
||||
|
||||
if not frame.backdrop then
|
||||
frame.backdrop = frame:CreateTexture(nil, "ARTWORK")
|
||||
frame.backdrop:SetInside(frame, 4, 4)
|
||||
frame.backdrop:SetTexture(unpack(E.media.backdropfadecolor))
|
||||
end
|
||||
frame.text:FontTemplate(E.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize, E.private.general.chatBubbleFontOutline)
|
||||
|
||||
frame:SetClampedToScreen(false)
|
||||
elseif E.private.general.chatBubbles == "nobackdrop" then
|
||||
frame:SetBackdrop(nil)
|
||||
frame.text:FontTemplate(E.LSM:Fetch("font", E.private.general.chatBubbleFont), E.private.general.chatBubbleFontSize, E.private.general.chatBubbleFontOutline)
|
||||
frame:SetClampedToScreen(false)
|
||||
end
|
||||
|
||||
frame:HookScript("OnShow", M.UpdateBubbleBorder)
|
||||
frame:SetFrameStrata("DIALOG")
|
||||
M.UpdateBubbleBorder(frame)
|
||||
|
||||
frame.isSkinnedElvUI = true
|
||||
end
|
||||
|
||||
function M:IsChatBubble(frame)
|
||||
for i = 1, frame:GetNumRegions() do
|
||||
local region = select(i, frame:GetRegions())
|
||||
if region.GetTexture and region:GetTexture() and region:GetTexture() == [[Interface\Tooltips\ChatBubble-Background]] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ChatBubble_OnEvent(self, event, msg, sender, _, _, _, _, _, _, _, _, _, guid)
|
||||
if not E.private.general.chatBubbleName then return end
|
||||
|
||||
messageToGUID[msg] = guid
|
||||
messageToSender[msg] = sender
|
||||
end
|
||||
|
||||
local lastChildern, numChildren = 0, 0
|
||||
local function findChatBubbles(...)
|
||||
for i = lastChildern + 1, numChildren do
|
||||
local frame = select(i, ...)
|
||||
if not frame.isSkinnedElvUI and M:IsChatBubble(frame) then
|
||||
M:SkinBubble(frame)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ChatBubble_OnUpdate(self, elapsed)
|
||||
self.lastupdate = self.lastupdate + elapsed
|
||||
if self.lastupdate < .1 then return end
|
||||
self.lastupdate = 0
|
||||
|
||||
numChildren = WorldGetNumChildren(WorldFrame)
|
||||
if lastChildern ~= numChildren then
|
||||
findChatBubbles(WorldGetChildren(WorldFrame))
|
||||
lastChildern = numChildren
|
||||
end
|
||||
end
|
||||
|
||||
function M:LoadChatBubbles()
|
||||
if E.private.general.chatBubbles == "disabled" then return end
|
||||
|
||||
self.BubbleFrame = CreateFrame("Frame")
|
||||
self.BubbleFrame.lastupdate = -2 -- wait 2 seconds before hooking frames
|
||||
|
||||
self.BubbleFrame:RegisterEvent("CHAT_MSG_SAY")
|
||||
self.BubbleFrame:RegisterEvent("CHAT_MSG_YELL")
|
||||
self.BubbleFrame:RegisterEvent("CHAT_MSG_PARTY")
|
||||
self.BubbleFrame:RegisterEvent("CHAT_MSG_PARTY_LEADER")
|
||||
self.BubbleFrame:RegisterEvent("CHAT_MSG_MONSTER_SAY")
|
||||
self.BubbleFrame:RegisterEvent("CHAT_MSG_MONSTER_YELL")
|
||||
self.BubbleFrame:SetScript("OnEvent", ChatBubble_OnEvent)
|
||||
self.BubbleFrame:SetScript("OnUpdate", ChatBubble_OnUpdate)
|
||||
end
|
||||
@@ -0,0 +1,162 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local D = E:GetModule("DebugTools")
|
||||
|
||||
--Lua functions
|
||||
local format = string.format
|
||||
--WoW API / Variables
|
||||
local GetCVarBool = GetCVarBool
|
||||
local InCombatLockdown = InCombatLockdown
|
||||
|
||||
function D:ModifyErrorFrame()
|
||||
ScriptErrorsFrameScrollFrameText.cursorOffset = 0
|
||||
ScriptErrorsFrameScrollFrameText.cursorHeight = 0
|
||||
ScriptErrorsFrameScrollFrameText:SetScript("OnEditFocusGained", nil)
|
||||
|
||||
local Orig_ScriptErrorsFrame_Update = ScriptErrorsFrame_Update
|
||||
ScriptErrorsFrame_Update = function(...)
|
||||
if GetCVarBool("scriptErrors") ~= 1 then
|
||||
Orig_ScriptErrorsFrame_Update(...)
|
||||
return
|
||||
end
|
||||
|
||||
-- Sometimes the locals table does not have an entry for an index, which can cause an argument #6 error
|
||||
-- in Blizzard_DebugTools.lua:430 and then cause a C stack overflow, this will prevent that
|
||||
local index = ScriptErrorsFrame.index
|
||||
if not index or not ScriptErrorsFrame.order[index] then
|
||||
index = #(ScriptErrorsFrame.order)
|
||||
end
|
||||
|
||||
if index > 0 then
|
||||
ScriptErrorsFrame.locals[index] = ScriptErrorsFrame.locals[index] or "No locals to dump"
|
||||
end
|
||||
|
||||
Orig_ScriptErrorsFrame_Update(...)
|
||||
|
||||
-- Stop text highlighting again
|
||||
ScriptErrorsFrameScrollFrameText:HighlightText(0, 0)
|
||||
end
|
||||
|
||||
-- Unhighlight text when focus is hit
|
||||
ScriptErrorsFrameScrollFrameText:HookScript("OnEscapePressed", function(self)
|
||||
self:HighlightText(0, 0)
|
||||
end)
|
||||
|
||||
ScriptErrorsFrame:Size(500, 300)
|
||||
ScriptErrorsFrameScrollFrame:Size(ScriptErrorsFrame:GetWidth() - 45, ScriptErrorsFrame:GetHeight() - 71)
|
||||
|
||||
ScriptErrorsFrameScrollFrameText:Width(ScriptErrorsFrameScrollFrame:GetWidth())
|
||||
|
||||
local BUTTON_WIDTH = 75
|
||||
local BUTTON_HEIGHT = 24
|
||||
local BUTTON_SPACING = 2
|
||||
|
||||
-- Add a first button
|
||||
local firstButton = CreateFrame("Button", nil, ScriptErrorsFrame, "UIPanelButtonTemplate")
|
||||
firstButton:SetPoint("BOTTOM", -((BUTTON_WIDTH + BUTTON_WIDTH/2) + (BUTTON_SPACING * 4)), 8)
|
||||
firstButton:SetText("First")
|
||||
firstButton:SetHeight(BUTTON_HEIGHT)
|
||||
firstButton:SetWidth(BUTTON_WIDTH)
|
||||
firstButton:SetScript("OnClick", function()
|
||||
ScriptErrorsFrame.index = 1
|
||||
ScriptErrorsFrame_Update()
|
||||
end)
|
||||
ScriptErrorsFrame.firstButton = firstButton
|
||||
|
||||
-- Also add a Last button for errors
|
||||
local lastButton = CreateFrame("Button", nil, ScriptErrorsFrame, "UIPanelButtonTemplate")
|
||||
lastButton:SetPoint("BOTTOMLEFT", ScriptErrorsFrame.next, "BOTTOMRIGHT", BUTTON_SPACING, 0)
|
||||
lastButton:SetHeight(BUTTON_HEIGHT)
|
||||
lastButton:SetWidth(BUTTON_WIDTH)
|
||||
lastButton:SetText("Last")
|
||||
lastButton:SetScript("OnClick", function()
|
||||
ScriptErrorsFrame.index = #(ScriptErrorsFrame.order)
|
||||
ScriptErrorsFrame_Update()
|
||||
end)
|
||||
ScriptErrorsFrame.lastButton = lastButton
|
||||
|
||||
ScriptErrorsFrame.previous:ClearAllPoints()
|
||||
ScriptErrorsFrame.previous:SetPoint("BOTTOMLEFT", firstButton, "BOTTOMRIGHT", BUTTON_SPACING, 0)
|
||||
ScriptErrorsFrame.previous:SetWidth(BUTTON_WIDTH)
|
||||
ScriptErrorsFrame.previous:SetHeight(BUTTON_HEIGHT)
|
||||
|
||||
ScriptErrorsFrame.next:ClearAllPoints()
|
||||
ScriptErrorsFrame.next:SetPoint("BOTTOMLEFT", ScriptErrorsFrame.previous, "BOTTOMRIGHT", BUTTON_SPACING, 0)
|
||||
ScriptErrorsFrame.next:SetWidth(BUTTON_WIDTH)
|
||||
ScriptErrorsFrame.next:SetHeight(BUTTON_HEIGHT)
|
||||
|
||||
ScriptErrorsFrame.close:ClearAllPoints()
|
||||
ScriptErrorsFrame.close:SetPoint("BOTTOMRIGHT", -8, 8)
|
||||
ScriptErrorsFrame.close:SetSize(75, BUTTON_HEIGHT)
|
||||
|
||||
ScriptErrorsFrame.indexLabel:ClearAllPoints()
|
||||
ScriptErrorsFrame.indexLabel:SetPoint("BOTTOMLEFT", 0, 12)
|
||||
end
|
||||
|
||||
function D:ScriptErrorsFrame_UpdateButtons()
|
||||
local numErrors = #ScriptErrorsFrame.order
|
||||
local index = ScriptErrorsFrame.index
|
||||
if index == 0 then
|
||||
ScriptErrorsFrame.lastButton:Disable()
|
||||
ScriptErrorsFrame.firstButton:Disable()
|
||||
else
|
||||
if numErrors == 1 then
|
||||
ScriptErrorsFrame.lastButton:Disable()
|
||||
ScriptErrorsFrame.firstButton:Disable()
|
||||
else
|
||||
ScriptErrorsFrame.lastButton:Enable()
|
||||
ScriptErrorsFrame.firstButton:Enable()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function D:ScriptErrorsFrame_OnError(_, keepHidden)
|
||||
if keepHidden or self.MessagePrinted or not InCombatLockdown() or GetCVarBool("scriptErrors") ~= 1 then return end
|
||||
|
||||
E:Print(L["|cFFE30000Lua error recieved. You can view the error message when you exit combat."])
|
||||
self.MessagePrinted = true
|
||||
end
|
||||
|
||||
function D:PLAYER_REGEN_ENABLED()
|
||||
ScriptErrorsFrame:SetParent(UIParent)
|
||||
self.MessagePrinted = nil
|
||||
end
|
||||
|
||||
function D:PLAYER_REGEN_DISABLED()
|
||||
ScriptErrorsFrame:SetParent(self.HideFrame)
|
||||
end
|
||||
|
||||
function D:TaintError(event, addonName, addonFunc)
|
||||
if GetCVarBool("scriptErrors") ~= 1 or E.db.general.taintLog ~= true then return end
|
||||
ScriptErrorsFrame_OnError(format(L["%s: %s tried to call the protected function '%s'."], event, addonName or "<name>", addonFunc or "<func>"), false)
|
||||
end
|
||||
|
||||
function D:StaticPopup_Show(name)
|
||||
if name == "ADDON_ACTION_FORBIDDEN" and E.db.general.taintLog ~= true then
|
||||
StaticPopup_Hide(name)
|
||||
end
|
||||
end
|
||||
|
||||
function D:Initialize()
|
||||
self.Initialized = true
|
||||
self.HideFrame = CreateFrame("Frame")
|
||||
self.HideFrame:Hide()
|
||||
|
||||
if not IsAddOnLoaded("Blizzard_DebugTools") then
|
||||
LoadAddOn("Blizzard_DebugTools")
|
||||
end
|
||||
|
||||
self:ModifyErrorFrame()
|
||||
self:SecureHook("ScriptErrorsFrame_UpdateButtons")
|
||||
self:SecureHook("ScriptErrorsFrame_OnError")
|
||||
self:SecureHook("StaticPopup_Show")
|
||||
self:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
self:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
self:RegisterEvent("ADDON_ACTION_BLOCKED", "TaintError")
|
||||
self:RegisterEvent("ADDON_ACTION_FORBIDDEN", "TaintError")
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
D:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(D:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,13 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Misc.lua"/>
|
||||
<Script file="DebugTools.lua"/>
|
||||
<Script file="ChatBubbles.lua"/>
|
||||
<Script file="Raidmarker.lua"/>
|
||||
<Script file="Loot.lua"/>
|
||||
<Script file="LootRoll.lua"/>
|
||||
<Script file="Raidbuffreminder.lua"/>
|
||||
<Script file="Threat.lua"/>
|
||||
<Script file="TotemBar.lua"/>
|
||||
<Script file="RaidUtility.lua"/>
|
||||
<Script file="AFK.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,352 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local M = E:GetModule("Misc")
|
||||
|
||||
--Lua functions
|
||||
local unpack, pairs = unpack, pairs
|
||||
local max = math.max
|
||||
local find, gsub = string.find, string.gsub
|
||||
local tinsert = table.insert
|
||||
--WoW API / Variables
|
||||
local CloseLoot = CloseLoot
|
||||
local CreateFrame = CreateFrame
|
||||
local CursorOnUpdate = CursorOnUpdate
|
||||
local CursorUpdate = CursorUpdate
|
||||
local GetCVar = GetCVar
|
||||
local GetCursorPosition = GetCursorPosition
|
||||
local GetLootSlotInfo = GetLootSlotInfo
|
||||
local GetLootSlotLink = GetLootSlotLink
|
||||
local GetNumLootItems = GetNumLootItems
|
||||
local GiveMasterLoot = GiveMasterLoot
|
||||
local HandleModifiedItemClick = HandleModifiedItemClick
|
||||
local IsFishingLoot = IsFishingLoot
|
||||
local IsModifiedClick = IsModifiedClick
|
||||
local LootSlot = LootSlot
|
||||
local LootSlotIsItem = LootSlotIsItem
|
||||
local ResetCursor = ResetCursor
|
||||
local StaticPopup_Hide = StaticPopup_Hide
|
||||
local ToggleDropDownMenu = ToggleDropDownMenu
|
||||
local UnitIsDead = UnitIsDead
|
||||
local UnitIsFriend = UnitIsFriend
|
||||
local UnitName = UnitName
|
||||
local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
|
||||
local TEXTURE_ITEM_QUEST_BANG = TEXTURE_ITEM_QUEST_BANG
|
||||
local LOOT = LOOT
|
||||
|
||||
-- Credit Haste
|
||||
local lootFrame, lootFrameHolder
|
||||
local iconSize = 30
|
||||
|
||||
local sq, ss, sn
|
||||
local OnEnter = function(self)
|
||||
local slot = self:GetID()
|
||||
if LootSlotIsItem(slot) then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetLootItem(slot)
|
||||
CursorUpdate(self)
|
||||
end
|
||||
|
||||
self.drop:Show()
|
||||
self.drop:SetVertexColor(1, 1, 1)
|
||||
end
|
||||
|
||||
local OnLeave = function(self)
|
||||
if self.quality and (self.quality > 1) then
|
||||
local color = ITEM_QUALITY_COLORS[self.quality]
|
||||
self.drop:SetVertexColor(color.r, color.g, color.b)
|
||||
else
|
||||
self.drop:Hide()
|
||||
end
|
||||
|
||||
GameTooltip:Hide()
|
||||
ResetCursor()
|
||||
end
|
||||
|
||||
local OnClick = function(self)
|
||||
LootFrame.selectedQuality = self.quality
|
||||
LootFrame.selectedItemName = self.name:GetText()
|
||||
LootFrame.selectedSlot = self:GetID()
|
||||
LootFrame.selectedLootButton = self:GetName()
|
||||
|
||||
if IsModifiedClick() then
|
||||
HandleModifiedItemClick(GetLootSlotLink(self:GetID()))
|
||||
else
|
||||
StaticPopup_Hide("CONFIRM_LOOT_DISTRIBUTION")
|
||||
ss = self:GetID()
|
||||
sq = self.quality
|
||||
sn = self.name:GetText()
|
||||
LootSlot(ss)
|
||||
end
|
||||
end
|
||||
|
||||
local OnShow = function(self)
|
||||
if GameTooltip:IsOwned(self) then
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetLootItem(self:GetID())
|
||||
CursorOnUpdate(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function anchorSlots(self)
|
||||
local shownSlots = 0
|
||||
for i = 1, #self.slots do
|
||||
local frame = self.slots[i]
|
||||
if frame:IsShown() then
|
||||
shownSlots = shownSlots + 1
|
||||
|
||||
frame:Point("TOP", lootFrame, 4, (-8 + iconSize) - (shownSlots * iconSize))
|
||||
end
|
||||
end
|
||||
|
||||
self:Height(max(shownSlots * iconSize + 16, 20))
|
||||
end
|
||||
|
||||
local function createSlot(id)
|
||||
local frame = CreateFrame("Button", "ElvLootSlot"..id, lootFrame)
|
||||
frame:Point("LEFT", 8, 0)
|
||||
frame:Point("RIGHT", -8, 0)
|
||||
frame:Height(iconSize - 2)
|
||||
frame:SetID(id)
|
||||
|
||||
frame:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||||
|
||||
frame:SetScript("OnEnter", OnEnter)
|
||||
frame:SetScript("OnLeave", OnLeave)
|
||||
frame:SetScript("OnClick", OnClick)
|
||||
frame:SetScript("OnShow", OnShow)
|
||||
|
||||
local iconFrame = CreateFrame("Frame", nil, frame)
|
||||
iconFrame:Size(iconSize - 2)
|
||||
iconFrame:Point("RIGHT", frame)
|
||||
iconFrame:SetTemplate("Default")
|
||||
frame.iconFrame = iconFrame
|
||||
E.frames[iconFrame] = nil
|
||||
|
||||
local icon = iconFrame:CreateTexture(nil, "ARTWORK")
|
||||
icon:SetTexCoord(unpack(E.TexCoords))
|
||||
icon:SetInside()
|
||||
frame.icon = icon
|
||||
|
||||
local count = iconFrame:CreateFontString(nil, "OVERLAY")
|
||||
count:SetJustifyH("RIGHT")
|
||||
count:Point("BOTTOMRIGHT", iconFrame, -2, 2)
|
||||
count:FontTemplate(nil, nil, "OUTLINE")
|
||||
count:SetText(1)
|
||||
frame.count = count
|
||||
|
||||
local name = frame:CreateFontString(nil, "OVERLAY")
|
||||
name:SetJustifyH("LEFT")
|
||||
name:Point("LEFT", frame)
|
||||
name:Point("RIGHT", icon, "LEFT")
|
||||
name:SetNonSpaceWrap(true)
|
||||
name:FontTemplate(nil, nil, "OUTLINE")
|
||||
frame.name = name
|
||||
|
||||
local drop = frame:CreateTexture(nil, "ARTWORK")
|
||||
drop:SetTexture(1, 1, 1, 0.15)
|
||||
drop:Point("LEFT", icon, "RIGHT", 0, 0)
|
||||
drop:Point("RIGHT", frame)
|
||||
drop:SetAllPoints(frame)
|
||||
frame.drop = drop
|
||||
|
||||
local questTexture = iconFrame:CreateTexture(nil, "OVERLAY")
|
||||
questTexture:SetInside()
|
||||
questTexture:SetTexture(TEXTURE_ITEM_QUEST_BANG)
|
||||
questTexture:SetTexCoord(unpack(E.TexCoords))
|
||||
frame.questTexture = questTexture
|
||||
|
||||
lootFrame.slots[id] = frame
|
||||
return frame
|
||||
end
|
||||
|
||||
function M:LOOT_SLOT_CLEARED(_, slot)
|
||||
if not lootFrame:IsShown() then return end
|
||||
|
||||
lootFrame.slots[slot]:Hide()
|
||||
anchorSlots(lootFrame)
|
||||
end
|
||||
|
||||
function M:LOOT_CLOSED()
|
||||
StaticPopup_Hide("LOOT_BIND")
|
||||
lootFrame:Hide()
|
||||
|
||||
for _, v in pairs(lootFrame.slots) do
|
||||
v:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function M:OPEN_MASTER_LOOT_LIST()
|
||||
ToggleDropDownMenu(1, nil, GroupLootDropDown, lootFrame.slots[ss], 0, 0)
|
||||
end
|
||||
|
||||
function M:UPDATE_MASTER_LOOT_LIST()
|
||||
UIDropDownMenu_Refresh(GroupLootDropDown)
|
||||
end
|
||||
|
||||
function M:LOOT_OPENED(_, autoLoot)
|
||||
lootFrame:Show()
|
||||
|
||||
if not lootFrame:IsShown() then
|
||||
CloseLoot(autoLoot == 0)
|
||||
end
|
||||
|
||||
local items = GetNumLootItems()
|
||||
|
||||
if IsFishingLoot() then
|
||||
lootFrame.title:SetText(L["Fishy Loot"])
|
||||
elseif not UnitIsFriend("player", "target") and UnitIsDead("target") then
|
||||
lootFrame.title:SetText(UnitName("target"))
|
||||
else
|
||||
lootFrame.title:SetText(LOOT)
|
||||
end
|
||||
|
||||
-- Blizzard uses strings here
|
||||
if GetCVar("lootUnderMouse") == "1" then
|
||||
local x, y = GetCursorPosition()
|
||||
x = x / lootFrame:GetEffectiveScale()
|
||||
y = y / lootFrame:GetEffectiveScale()
|
||||
|
||||
lootFrame:ClearAllPoints()
|
||||
lootFrame:Point("TOPLEFT", UIParent, "BOTTOMLEFT", x - 40, y + 20)
|
||||
lootFrame:GetCenter()
|
||||
lootFrame:Raise()
|
||||
E:DisableMover("LootFrameMover")
|
||||
else
|
||||
lootFrame:ClearAllPoints()
|
||||
lootFrame:Point("TOPLEFT", lootFrameHolder, "TOPLEFT")
|
||||
E:EnableMover("LootFrameMover")
|
||||
end
|
||||
|
||||
local m, w, t = 0, 0, lootFrame.title:GetStringWidth()
|
||||
if items > 0 then
|
||||
for i = 1, items do
|
||||
local slot = lootFrame.slots[i] or createSlot(i)
|
||||
local texture, item, quantity, quality, _, isQuestItem, questId, isActive = GetLootSlotInfo(i)
|
||||
local color = ITEM_QUALITY_COLORS[quality]
|
||||
|
||||
if texture and find(texture, "INV_Misc_Coin") then
|
||||
item = gsub(item, "\n", ", ")
|
||||
end
|
||||
|
||||
if quantity and (quantity > 1) then
|
||||
slot.count:SetText(quantity)
|
||||
slot.count:Show()
|
||||
else
|
||||
slot.count:Hide()
|
||||
end
|
||||
|
||||
if quality and (quality > 1) then
|
||||
slot.drop:SetVertexColor(color.r, color.g, color.b)
|
||||
slot.drop:Show()
|
||||
else
|
||||
slot.drop:Hide()
|
||||
end
|
||||
|
||||
slot.quality = quality
|
||||
slot.name:SetText(item)
|
||||
if color then
|
||||
slot.name:SetTextColor(color.r, color.g, color.b)
|
||||
end
|
||||
slot.icon:SetTexture(texture)
|
||||
|
||||
if quality then
|
||||
m = max(m, quality)
|
||||
end
|
||||
w = max(w, slot.name:GetStringWidth())
|
||||
|
||||
local questTexture = slot.questTexture
|
||||
if questId and not isActive then
|
||||
questTexture:SetTexture(TEXTURE_ITEM_QUEST_BANG)
|
||||
questTexture:Show()
|
||||
elseif questId or isQuestItem then
|
||||
questTexture:SetTexture(TEXTURE_ITEM_QUEST_BORDER)
|
||||
questTexture:Show()
|
||||
else
|
||||
questTexture:Hide()
|
||||
end
|
||||
|
||||
-- Check for FasterLooting scripts or w/e (if bag is full)
|
||||
if texture then
|
||||
slot:Enable()
|
||||
slot:Show()
|
||||
end
|
||||
end
|
||||
else
|
||||
local slot = lootFrame.slots[1] or createSlot(1)
|
||||
local color = ITEM_QUALITY_COLORS[0]
|
||||
|
||||
slot.name:SetText(L["Empty Slot"])
|
||||
if color then
|
||||
slot.name:SetTextColor(color.r, color.g, color.b)
|
||||
end
|
||||
slot.icon:SetTexture[[Interface\Icons\INV_Misc_Herb_AncientLichen]]
|
||||
|
||||
w = max(w, slot.name:GetStringWidth())
|
||||
|
||||
slot.count:Hide()
|
||||
slot.drop:Hide()
|
||||
slot:Disable()
|
||||
slot:Show()
|
||||
end
|
||||
anchorSlots(lootFrame)
|
||||
|
||||
w = w + 60
|
||||
t = t + 5
|
||||
|
||||
local color = ITEM_QUALITY_COLORS[m]
|
||||
lootFrame:SetBackdropBorderColor(color.r, color.g, color.b, .8)
|
||||
lootFrame:Width(max(w, t))
|
||||
end
|
||||
|
||||
function M:LoadLoot()
|
||||
if not E.private.general.loot then return end
|
||||
|
||||
lootFrameHolder = CreateFrame("Frame", "ElvLootFrameHolder", E.UIParent)
|
||||
lootFrameHolder:Point("TOP", 0, -50)
|
||||
lootFrameHolder:Size(150, 22)
|
||||
|
||||
lootFrame = CreateFrame("Button", "ElvLootFrame", lootFrameHolder)
|
||||
lootFrame:SetClampedToScreen(true)
|
||||
lootFrame:SetPoint("TOPLEFT")
|
||||
lootFrame:Size(256, 64)
|
||||
lootFrame:SetTemplate("Transparent")
|
||||
lootFrame:SetFrameStrata("DIALOG")
|
||||
lootFrame:SetToplevel(true)
|
||||
lootFrame.title = lootFrame:CreateFontString(nil, "OVERLAY")
|
||||
lootFrame.title:FontTemplate(nil, nil, "OUTLINE")
|
||||
lootFrame.title:Point("BOTTOMLEFT", lootFrame, "TOPLEFT", 0, 1)
|
||||
lootFrame.slots = {}
|
||||
lootFrame:SetScript("OnHide", function()
|
||||
StaticPopup_Hide("CONFIRM_LOOT_DISTRIBUTION")
|
||||
CloseLoot()
|
||||
end)
|
||||
E.frames[lootFrame] = nil
|
||||
|
||||
self:RegisterEvent("LOOT_OPENED")
|
||||
self:RegisterEvent("LOOT_SLOT_CLEARED")
|
||||
self:RegisterEvent("LOOT_CLOSED")
|
||||
self:RegisterEvent("OPEN_MASTER_LOOT_LIST")
|
||||
self:RegisterEvent("UPDATE_MASTER_LOOT_LIST")
|
||||
|
||||
E:CreateMover(lootFrameHolder, "LootFrameMover", L["Loot Frame"], nil, nil, nil, nil, nil, "general,blizzUIImprovements")
|
||||
|
||||
-- Fuzz
|
||||
LootFrame:UnregisterAllEvents()
|
||||
tinsert(UISpecialFrames, "ElvLootFrame")
|
||||
|
||||
function _G.GroupLootDropDown_GiveLoot(self)
|
||||
if sq >= MASTER_LOOT_THREHOLD then
|
||||
local dialog = StaticPopup_Show("CONFIRM_LOOT_DISTRIBUTION", ITEM_QUALITY_COLORS[sq].hex..sn..FONT_COLOR_CODE_CLOSE, self:GetText())
|
||||
if dialog then
|
||||
dialog.data = self.value
|
||||
end
|
||||
else
|
||||
GiveMasterLoot(ss, self.value)
|
||||
end
|
||||
CloseDropDownMenus()
|
||||
end
|
||||
|
||||
E.PopupDialogs.CONFIRM_LOOT_DISTRIBUTION.OnAccept = function(_, data)
|
||||
GiveMasterLoot(ss, data)
|
||||
end
|
||||
StaticPopupDialogs.CONFIRM_LOOT_DISTRIBUTION.preferredIndex = 3
|
||||
end
|
||||
@@ -0,0 +1,474 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local M = E:GetModule("Misc")
|
||||
|
||||
--Lua functions
|
||||
local pairs, ipairs, unpack = pairs, ipairs, unpack
|
||||
local find, format = string.find, string.format
|
||||
local tinsert, twipe = table.insert, table.wipe
|
||||
--WoW API / Variables
|
||||
local ChatEdit_InsertLink = ChatEdit_InsertLink
|
||||
local CreateFrame = CreateFrame
|
||||
local CursorOnUpdate = CursorOnUpdate
|
||||
local CursorUpdate = CursorUpdate
|
||||
local DressUpItemLink = DressUpItemLink
|
||||
local GetLootRollItemInfo = GetLootRollItemInfo
|
||||
local GetLootRollItemLink = GetLootRollItemLink
|
||||
local GetLootRollTimeLeft = GetLootRollTimeLeft
|
||||
local IsModifiedClick = IsModifiedClick
|
||||
local ResetCursor = ResetCursor
|
||||
local RollOnLoot = RollOnLoot
|
||||
local SetDesaturation = SetDesaturation
|
||||
local UnitClass = UnitClass
|
||||
|
||||
local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS
|
||||
local ROLL_DISENCHANT = ROLL_DISENCHANT
|
||||
|
||||
local POSITION = "TOP"
|
||||
local FRAME_WIDTH, FRAME_HEIGHT = 328, 28
|
||||
|
||||
M.RollBars = {}
|
||||
|
||||
local locale = GetLocale()
|
||||
local rollMessages = locale == "deDE" and {
|
||||
["(.*) passt automatisch bei (.+), weil [ersi]+ den Gegenstand nicht benutzen kann.$"] = 0,
|
||||
["(.*) würfelt nicht für: (.+|r)$"] = 0,
|
||||
["(.*) hat für (.+) 'Bedarf' ausgewählt"] = 1,
|
||||
["(.*) hat für (.+) 'Gier' ausgewählt"] = 2,
|
||||
["(.*) hat für '(.+)' Entzauberung gewählt."] = 3,
|
||||
} or locale == "frFR" and {
|
||||
["(.*) a passé pour : (.+) parce qu'((il)|(elle)) ne peut pas ramasser cette objet.$"] = 0,
|
||||
["(.*) a passé pour : (.+)"] = 0,
|
||||
["(.*) a choisi Besoin pour : (.+)"] = 1,
|
||||
["(.*) a choisi Cupidité pour : (.+)"] = 2,
|
||||
["(.*) a choisi Désenchantement pour : (.+)"] = 3,
|
||||
} or locale == "zhCN" and {
|
||||
["(.*)自动放弃了:(.+),因为他无法拾取该物品$"] = 0,
|
||||
["(.*)自动放弃了:(.+),因为她无法拾取该物品$"] = 0,
|
||||
["(.*)放弃了:(.+)"] = 0,
|
||||
["(.*)选择了需求取向:(.+)"] = 1,
|
||||
["(.*)选择了贪婪取向:(.+)"] = 2,
|
||||
["(.*)选择了分解取向:(.+)"] = 3,
|
||||
} or locale == "zhTW" and {
|
||||
["(.*)自動放棄:(.+),因為他無法拾取該物品$"] = 0,
|
||||
["(.*)自動放棄:(.+),因為她無法拾取該物品$"] = 0,
|
||||
["(.*)放棄了:(.+)"] = 0,
|
||||
["(.*)選擇了需求:(.+)"] = 1,
|
||||
["(.*)選擇了貪婪:(.+)"] = 2,
|
||||
["(.*)選擇了分解:(.+)"] = 3,
|
||||
} or locale == "ruRU" and {
|
||||
["(.*) автоматически передает предмет (.+), поскольку не может его забрать"] = 0,
|
||||
["(.*) пропускает розыгрыш предмета \"(.+)\", поскольку не может его забрать"] = 0,
|
||||
["(.*) отказывается от предмета (.+)%."] = 0,
|
||||
["Разыгрывается: (.+)%. (.*): \"Мне это нужно\""] = 1,
|
||||
["Разыгрывается: (.+)%. (.*): \"Не откажусь\""] = 2,
|
||||
["Разыгрывается: (.+)%. (.*): \"Распылить\""] = 3,
|
||||
} or locale == "koKR" and {
|
||||
["(.*)님이 획득할 수 없는 아이템이어서 자동으로 주사위 굴리기를 포기했습니다: (.+)"] = 0,
|
||||
["(.*)님이 주사위 굴리기를 포기했습니다: (.+)"] = 0,
|
||||
["(.*)님이 입찰을 선택했습니다: (.+)"] = 1,
|
||||
["(.*)님이 차비를 선택했습니다: (.+)"] = 2,
|
||||
["(.*)님이 마력 추출을 선택했습니다: (.+)"] = 3,
|
||||
} or locale == "esES" and {
|
||||
["^(.*) pasó automáticamente de: (.+) porque no puede despojar este objeto.$"] = 0,
|
||||
["^(.*) pasó de: (.+|r)$"] = 0,
|
||||
["(.*) eligió Necesidad para: (.+)"] = 1,
|
||||
["(.*) eligió Codicia para: (.+)"] = 2,
|
||||
["(.*) eligió Desencantar para: (.+)"] = 3,
|
||||
} or locale == "esMX" and {
|
||||
["^(.*) pasó automáticamente de: (.+) porque no puede despojar este objeto.$"] = 0,
|
||||
["^(.*) pasó de: (.+|r)$"] = 0,
|
||||
["(.*) eligió Necesidad para: (.+)"] = 1,
|
||||
["(.*) eligió Codicia para: (.+)"] = 2,
|
||||
["(.*) eligió Desencantar para: (.+)"] = 3,
|
||||
} or {
|
||||
["^(.*) automatically passed on: (.+) because s?he cannot loot that item.$"] = 0,
|
||||
["^(.*) passed on: (.+|r)$"] = 0,
|
||||
["(.*) has selected Need for: (.+)"] = 1,
|
||||
["(.*) has selected Greed for: (.+)"] = 2,
|
||||
["(.*) has selected Disenchant for: (.+)"] = 3
|
||||
}
|
||||
|
||||
local rollTypes = {
|
||||
[0] = {
|
||||
tooltipText = PASS,
|
||||
normalTexture = "Interface\\Buttons\\UI-GroupLoot-Pass-Up",
|
||||
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-Pass-Down",
|
||||
highlightTexture = nil,
|
||||
},
|
||||
[1] = {
|
||||
tooltipText = NEED,
|
||||
newbieText = NEED_NEWBIE,
|
||||
normalTexture = "Interface\\Buttons\\UI-GroupLoot-Dice-Up",
|
||||
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-Dice-Down",
|
||||
highlightTexture = "Interface\\Buttons\\UI-GroupLoot-Dice-Highlight",
|
||||
},
|
||||
[2] = {
|
||||
tooltipText = GREED,
|
||||
newbieText = GREED_NEWBIE,
|
||||
normalTexture = "Interface\\Buttons\\UI-GroupLoot-Coin-Up",
|
||||
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-Coin-Down",
|
||||
highlightTexture = "Interface\\Buttons\\UI-GroupLoot-Coin-Highlight",
|
||||
},
|
||||
[3] = {
|
||||
tooltipText = ROLL_DISENCHANT,
|
||||
newbieText = ROLL_DISENCHANT_NEWBIE,
|
||||
normalTexture = "Interface\\Buttons\\UI-GroupLoot-DE-Up",
|
||||
pushedTexture = "Interface\\Buttons\\UI-GroupLoot-DE-Down",
|
||||
highlightTexture = "Interface\\Buttons\\UI-GroupLoot-DE-Highlight",
|
||||
},
|
||||
}
|
||||
|
||||
local reasons = {
|
||||
LOOT_ROLL_INELIGIBLE_REASON1,
|
||||
LOOT_ROLL_INELIGIBLE_REASON2,
|
||||
LOOT_ROLL_INELIGIBLE_REASON3,
|
||||
LOOT_ROLL_INELIGIBLE_REASON4,
|
||||
LOOT_ROLL_INELIGIBLE_REASON5,
|
||||
}
|
||||
|
||||
local function buttonOnEnter(self)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
|
||||
GameTooltip:SetText(self.tooltipText)
|
||||
|
||||
if self.newbieText and SHOW_NEWBIE_TIPS == "1" then
|
||||
GameTooltip:AddLine(self.newbieText, 1, 0.82, 0, true)
|
||||
end
|
||||
|
||||
if self:IsEnabled() == 0 then
|
||||
GameTooltip:AddLine(self.reason, 1, 0.1, 0.1, true)
|
||||
end
|
||||
|
||||
for playerName, rollData in pairs(self.parent.rollResults) do
|
||||
if self.rollType == rollData[1] and rollData[2] then
|
||||
local classColor = E.media.herocolor
|
||||
GameTooltip:AddLine(playerName, classColor.r, classColor.g, classColor.b)
|
||||
end
|
||||
end
|
||||
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
local function buttonOnLeave()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local function buttonOnClick(self)
|
||||
RollOnLoot(self.parent.rollID, self.rollType)
|
||||
end
|
||||
|
||||
local function toggleLootButton(self, state, reason, reasonValue)
|
||||
if state then
|
||||
self:Enable()
|
||||
self:SetAlpha(1)
|
||||
self.reason = nil
|
||||
SetDesaturation(self:GetNormalTexture(), false)
|
||||
else
|
||||
self:Disable()
|
||||
self:SetAlpha(0.2)
|
||||
self.reason = reasonValue and format(reasons[reason], reasonValue) or reasons[reason]
|
||||
SetDesaturation(self:GetNormalTexture(), true)
|
||||
end
|
||||
end
|
||||
|
||||
local function increaseRollCount(self, count)
|
||||
local text = self.text:GetText()
|
||||
if not text or text == "" then
|
||||
self.text:SetText(count or 1)
|
||||
else
|
||||
self.text:SetText(self.text:GetText() + (count or 1))
|
||||
end
|
||||
end
|
||||
|
||||
function M:CreateRollButton(parent, rollType)
|
||||
local data = rollTypes[rollType]
|
||||
|
||||
local button = CreateFrame("Button", nil, parent)
|
||||
button:Size(FRAME_HEIGHT - 4)
|
||||
button:SetNormalTexture(data.normalTexture)
|
||||
button:SetPushedTexture(data.highlightTexture)
|
||||
button:SetHighlightTexture(data.pushedTexture)
|
||||
|
||||
button:SetMotionScriptsWhileDisabled(true)
|
||||
button:SetScript("OnEnter", buttonOnEnter)
|
||||
button:SetScript("OnLeave", buttonOnLeave)
|
||||
button:SetScript("OnClick", buttonOnClick)
|
||||
|
||||
button.ToggleLootButton = toggleLootButton
|
||||
button.IncreaseRollCount = increaseRollCount
|
||||
button.parent = parent
|
||||
button.rollType = rollType
|
||||
button.tooltipText = data.tooltipText
|
||||
button.newbieText = data.newbieText
|
||||
|
||||
button.text = button:CreateFontString(nil, nil)
|
||||
button.text:FontTemplate(E.Media.Fonts.Homespun, nil, "MONOCHROMEOUTLINE")
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
local function itemOnEnter(self)
|
||||
GameTooltip:SetOwner(self, POSITION == "TOP" and "ANCHOR_BOTTOMLEFT" or "ANCHOR_TOPLEFT")
|
||||
GameTooltip:SetLootRollItem(self.rollID)
|
||||
|
||||
CursorUpdate(self)
|
||||
end
|
||||
|
||||
local function itemOnLeave()
|
||||
GameTooltip:Hide()
|
||||
ResetCursor()
|
||||
end
|
||||
|
||||
local function itemOnUpdate(self)
|
||||
if GameTooltip:IsOwned(self) then
|
||||
GameTooltip:SetOwner(self, POSITION == "TOP" and "ANCHOR_BOTTOMLEFT" or "ANCHOR_TOPLEFT")
|
||||
GameTooltip:SetLootRollItem(self.rollID)
|
||||
end
|
||||
|
||||
CursorOnUpdate(self)
|
||||
end
|
||||
|
||||
local function itemOnClick(self)
|
||||
if IsModifiedClick("CHATLINK") then
|
||||
ChatEdit_InsertLink(self.link)
|
||||
elseif IsModifiedClick("DRESSUP") then
|
||||
DressUpItemLink(self.link)
|
||||
end
|
||||
end
|
||||
|
||||
local function statusbarOnUpdate(self)
|
||||
local timeLeft = GetLootRollTimeLeft(self.parent.rollID)
|
||||
if timeLeft < 0 or timeLeft > self.parent.rollTime then
|
||||
timeLeft = 0
|
||||
else
|
||||
self.spark:Point("CENTER", self, "LEFT", (timeLeft / self.parent.rollTime) * self:GetWidth(), 0)
|
||||
end
|
||||
|
||||
self:SetValue(timeLeft)
|
||||
end
|
||||
|
||||
function M:CreateRollFrame()
|
||||
self.numFrames = self.numFrames + 1
|
||||
|
||||
local frame = CreateFrame("Frame", format("ElvUI_GroupLootFrame%d", self.numFrames), E.UIParent)
|
||||
frame:Size(FRAME_WIDTH, FRAME_HEIGHT)
|
||||
frame:SetTemplate()
|
||||
frame:SetFrameStrata("DIALOG")
|
||||
frame:Hide()
|
||||
|
||||
if POSITION == "TOP" then
|
||||
frame:Point("TOP", self.numFrames > 1 and self.RollBars[self.numFrames - 1] or AlertFrameHolder, "BOTTOM", 0, -4)
|
||||
else
|
||||
frame:Point("BOTTOM", self.numFrames > 1 and self.RollBars[self.numFrames - 1] or AlertFrameHolder, "TOP", 0, 4)
|
||||
end
|
||||
|
||||
local itemButton = CreateFrame("Button", "$parentIconFrame", frame)
|
||||
itemButton:Size(FRAME_HEIGHT - (E.Border * 2))
|
||||
itemButton:Point("RIGHT", frame, "LEFT", -(E.Spacing * 3), 0)
|
||||
itemButton:CreateBackdrop()
|
||||
itemButton:SetScript("OnEnter", itemOnEnter)
|
||||
itemButton:SetScript("OnLeave", itemOnLeave)
|
||||
itemButton:SetScript("OnUpdate", itemOnUpdate)
|
||||
itemButton:SetScript("OnClick", itemOnClick)
|
||||
itemButton.hasItem = 1
|
||||
frame.itemButton = itemButton
|
||||
|
||||
itemButton.icon = itemButton:CreateTexture(nil, "OVERLAY")
|
||||
itemButton.icon:SetAllPoints()
|
||||
itemButton.icon:SetTexCoord(unpack(E.TexCoords))
|
||||
|
||||
local fade = frame:CreateTexture(nil, "BORDER")
|
||||
fade:Point("TOPLEFT", frame, "TOPLEFT", 4, 0)
|
||||
fade:Point("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -4, 0)
|
||||
fade:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
|
||||
fade:SetBlendMode("ADD")
|
||||
fade:SetGradientAlpha("VERTICAL", 0.1, 0.1, 0.1, 0, 0.1, 0.1, 0.1, 0)
|
||||
frame.fade = fade
|
||||
|
||||
local status = CreateFrame("StatusBar", "$parentStatusBar", frame)
|
||||
status:SetInside()
|
||||
status:SetFrameLevel(status:GetFrameLevel() - 1)
|
||||
status:SetStatusBarTexture(E.media.normTex)
|
||||
status:SetStatusBarColor(0.8, 0.8, 0.8, 0.9)
|
||||
status.parent = frame
|
||||
E:RegisterStatusBar(status)
|
||||
status:SetScript("OnUpdate", statusbarOnUpdate)
|
||||
frame.status = status
|
||||
|
||||
status.bg = status:CreateTexture(nil, "BACKGROUND")
|
||||
status.bg:SetAlpha(0.1)
|
||||
status.bg:SetAllPoints()
|
||||
|
||||
local spark = frame:CreateTexture(nil, "OVERLAY")
|
||||
spark:Size(14, FRAME_HEIGHT)
|
||||
spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||
spark:SetBlendMode("ADD")
|
||||
status.spark = spark
|
||||
|
||||
frame.passButton = self:CreateRollButton(frame, 0)
|
||||
frame.needButton = self:CreateRollButton(frame, 1)
|
||||
frame.greedButton = self:CreateRollButton(frame, 2)
|
||||
frame.disenchantButton = self:CreateRollButton(frame, 3)
|
||||
|
||||
frame.needButton:SetHitRectInsets(0, 0, -2, 0)
|
||||
frame.greedButton:SetHitRectInsets(0, 0, -3, 1)
|
||||
frame.disenchantButton:SetHitRectInsets(0, 0, -2, 0)
|
||||
frame.passButton:SetHitRectInsets(0, 0, 0, -2)
|
||||
|
||||
frame.needButton:Point("LEFT", frame.itemButton, "RIGHT", 4, -1)
|
||||
frame.greedButton:Point("LEFT", frame.needButton, "RIGHT", 1, -1)
|
||||
frame.disenchantButton:Point("LEFT", frame.greedButton, "RIGHT", 0, 1)
|
||||
frame.passButton:Point("LEFT", frame.disenchantButton, "RIGHT", 0, 2)
|
||||
|
||||
frame.needButton.text:Point("CENTER", -1, 4)
|
||||
frame.greedButton.text:Point("CENTER", 1, 5)
|
||||
frame.disenchantButton.text:Point("CENTER", 1, 4)
|
||||
frame.passButton.text:Point("CENTER", 1, 2)
|
||||
|
||||
frame.bindText = frame:CreateFontString()
|
||||
frame.bindText:Point("LEFT", frame.passButton, "RIGHT", 2, 0)
|
||||
frame.bindText:FontTemplate(nil, nil, "OUTLINE")
|
||||
|
||||
local itemName = frame:CreateFontString(nil, "ARTWORK")
|
||||
itemName:FontTemplate(nil, nil, "OUTLINE")
|
||||
itemName:Point("LEFT", frame.bindText, "RIGHT", 1, 0)
|
||||
itemName:Point("RIGHT", frame, "RIGHT", -5, 0)
|
||||
itemName:Size(200, 10)
|
||||
itemName:SetJustifyH("LEFT")
|
||||
frame.itemName = itemName
|
||||
|
||||
frame.rollResults = {}
|
||||
frame.rollButtons = {
|
||||
[0] = frame.passButton,
|
||||
[1] = frame.needButton,
|
||||
[2] = frame.greedButton,
|
||||
[3] = frame.disenchantButton,
|
||||
}
|
||||
|
||||
tinsert(self.RollBars, frame)
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
function M:ReleaseFrame(frame)
|
||||
frame:Hide()
|
||||
frame.rollID = nil
|
||||
frame.rollTime = nil
|
||||
|
||||
for i = 0, 3 do
|
||||
frame.rollButtons[i].text:SetText("")
|
||||
end
|
||||
|
||||
twipe(frame.rollResults)
|
||||
end
|
||||
|
||||
function M:GetFrame()
|
||||
for _, frame in ipairs(M.RollBars) do
|
||||
if not frame.rollID then
|
||||
return frame
|
||||
end
|
||||
end
|
||||
|
||||
return self:CreateRollFrame()
|
||||
end
|
||||
|
||||
function M:START_LOOT_ROLL(_, rollID, rollTime)
|
||||
local f = self:GetFrame()
|
||||
f.rollID = rollID
|
||||
f.rollTime = rollTime
|
||||
|
||||
local texture, name, count, quality, bindOnPickUp, canNeed, canGreed, canDisenchant, reasonNeed, reasonGreed, reasonDisenchant, deSkillRequired = GetLootRollItemInfo(rollID)
|
||||
|
||||
f.itemButton.icon:SetTexture(texture)
|
||||
f.itemButton.rollID = rollID
|
||||
f.itemButton.link = GetLootRollItemLink(rollID)
|
||||
|
||||
if count > 1 then
|
||||
f.itemName:SetFormattedText("%dx %s", count, name)
|
||||
else
|
||||
f.itemName:SetText(name)
|
||||
end
|
||||
|
||||
f.status:SetMinMaxValues(0, rollTime)
|
||||
f.status:SetValue(rollTime)
|
||||
|
||||
local color = ITEM_QUALITY_COLORS[quality]
|
||||
f.status:SetStatusBarColor(color.r, color.g, color.b, 0.7)
|
||||
f.status.bg:SetTexture(color.r, color.g, color.b)
|
||||
|
||||
f.bindText:SetText(bindOnPickUp and "BoP" or "BoE")
|
||||
f.bindText:SetVertexColor(bindOnPickUp and 1 or 0.3, bindOnPickUp and 0.3 or 1, bindOnPickUp and 0.1 or 0.3)
|
||||
|
||||
f.needButton:ToggleLootButton(canNeed, reasonNeed)
|
||||
f.greedButton:ToggleLootButton(canGreed, reasonGreed)
|
||||
f.disenchantButton:ToggleLootButton(canDisenchant, reasonDisenchant, deSkillRequired)
|
||||
|
||||
f:Show()
|
||||
|
||||
AlertFrame_FixAnchors()
|
||||
|
||||
if E.db.general.autoRoll and E.mylevel == MAX_PLAYER_LEVEL and quality == 2 and not bindOnPickUp then
|
||||
if canDisenchant then
|
||||
RollOnLoot(rollID, 3)
|
||||
else
|
||||
RollOnLoot(rollID, 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:CANCEL_LOOT_ROLL(_, rollID)
|
||||
for _, frame in ipairs(self.RollBars) do
|
||||
if frame.rollID == rollID then
|
||||
self:ReleaseFrame(frame)
|
||||
E:StaticPopup_Hide("CONFIRM_LOOT_ROLL", self.rollID)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:ParseRollChoice(msg)
|
||||
for regex, rollType in pairs(rollMessages) do
|
||||
local _, _, playerName, itemName = find(msg, regex)
|
||||
|
||||
if playerName and itemName and playerName ~= "Everyone" then
|
||||
if locale == "ruRU" and rollType ~= 0 then
|
||||
playerName, itemName = itemName, playerName
|
||||
end
|
||||
|
||||
return playerName, itemName, rollType
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:CHAT_MSG_LOOT(_, msg)
|
||||
local playerName, itemName, rollType = self:ParseRollChoice(msg)
|
||||
|
||||
if playerName and itemName then
|
||||
local _, class = UnitClass(playerName)
|
||||
|
||||
for _, frame in ipairs(self.RollBars) do
|
||||
if frame.rollID and frame.itemButton.link == itemName and not frame.rollResults[playerName] then
|
||||
frame.rollResults[playerName] = {rollType, class}
|
||||
frame.rollButtons[rollType]:IncreaseRollCount()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:LoadLootRoll()
|
||||
if not E.private.general.lootRoll then return end
|
||||
|
||||
self.numFrames = 0
|
||||
|
||||
self:RegisterEvent("CHAT_MSG_LOOT")
|
||||
self:RegisterEvent("START_LOOT_ROLL")
|
||||
self:RegisterEvent("CANCEL_LOOT_ROLL")
|
||||
|
||||
UIParent:UnregisterEvent("START_LOOT_ROLL")
|
||||
UIParent:UnregisterEvent("CANCEL_LOOT_ROLL")
|
||||
|
||||
for i = 1, NUM_GROUP_LOOT_FRAMES do
|
||||
_G["GroupLootFrame"..i]:UnregisterEvent("CANCEL_LOOT_ROLL")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,355 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local M = E:GetModule("Misc")
|
||||
local Bags = E:GetModule("Bags")
|
||||
|
||||
--Lua functions
|
||||
local ipairs = ipairs
|
||||
local format = string.format
|
||||
--WoW API / Variables
|
||||
local AcceptGroup = AcceptGroup
|
||||
local CanGuildBankRepair = CanGuildBankRepair
|
||||
local CanMerchantRepair = CanMerchantRepair
|
||||
local GetCVarBool, SetCVar = GetCVarBool, SetCVar
|
||||
local GetFriendInfo = GetFriendInfo
|
||||
local GetGuildBankMoney = GetGuildBankMoney
|
||||
local GetGuildBankWithdrawMoney = GetGuildBankWithdrawMoney
|
||||
local GetGuildRosterInfo = GetGuildRosterInfo
|
||||
local GetMoney = GetMoney
|
||||
local GetNumFriends = GetNumFriends
|
||||
local GetNumGuildMembers = GetNumGuildMembers
|
||||
local GetNumPartyMembers = GetNumPartyMembers
|
||||
local GetNumRaidMembers = GetNumRaidMembers
|
||||
local GetPartyMember = GetPartyMember
|
||||
local GetRaidRosterInfo = GetRaidRosterInfo
|
||||
local GetRepairAllCost = GetRepairAllCost
|
||||
local GuildRoster = GuildRoster
|
||||
local HideRepairCursor = HideRepairCursor
|
||||
local InCombatLockdown = InCombatLockdown
|
||||
local IsInGuild = IsInGuild
|
||||
local IsInInstance = IsInInstance
|
||||
local IsShiftKeyDown = IsShiftKeyDown
|
||||
local LeaveParty = LeaveParty
|
||||
local PickupInventoryItem = PickupInventoryItem
|
||||
local RaidNotice_AddMessage = RaidNotice_AddMessage
|
||||
local RepairAllItems = RepairAllItems
|
||||
local SendChatMessage = SendChatMessage
|
||||
local ShowFriends = ShowFriends
|
||||
local ShowRepairCursor = ShowRepairCursor
|
||||
local StaticPopup_Hide = StaticPopup_Hide
|
||||
local UninviteUnit = UninviteUnit
|
||||
local UnitGUID = UnitGUID
|
||||
local UnitName = UnitName
|
||||
|
||||
local MAX_PARTY_MEMBERS = MAX_PARTY_MEMBERS
|
||||
|
||||
do
|
||||
local function EventHandler(event)
|
||||
if event == "PLAYER_REGEN_DISABLED" then
|
||||
UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE")
|
||||
else
|
||||
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")
|
||||
end
|
||||
end
|
||||
|
||||
function M:ToggleErrorHandling()
|
||||
if E.db.general.hideErrorFrame then
|
||||
self:RegisterEvent("PLAYER_REGEN_ENABLED", EventHandler)
|
||||
self:RegisterEvent("PLAYER_REGEN_DISABLED", EventHandler)
|
||||
else
|
||||
self:UnregisterEvent("PLAYER_REGEN_ENABLED", EventHandler)
|
||||
self:UnregisterEvent("PLAYER_REGEN_DISABLED", EventHandler)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local interruptMsg = INTERRUPTED.." %s's \124cff71d5ff\124Hspell:%d\124h[%s]\124h\124r!"
|
||||
|
||||
function M:ToggleInterruptAnnounce()
|
||||
if E.db.general.interruptAnnounce == "NONE" then
|
||||
self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
else
|
||||
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
end
|
||||
end
|
||||
|
||||
function M:COMBAT_LOG_EVENT_UNFILTERED(_, _, event, sourceGUID, _, _, _, destName, _, _, _, _, spellID, spellName)
|
||||
if not (event == "SPELL_INTERRUPT" and (sourceGUID == E.myguid or sourceGUID == UnitGUID("pet"))) then return end
|
||||
|
||||
if E.db.general.interruptAnnounce == "SAY" then
|
||||
SendChatMessage(format(interruptMsg, destName, spellID, spellName), "SAY")
|
||||
elseif E.db.general.interruptAnnounce == "EMOTE" then
|
||||
SendChatMessage(format(interruptMsg, destName, spellID, spellName), "EMOTE")
|
||||
else
|
||||
local _, instanceType = IsInInstance()
|
||||
local battleground = instanceType == "pvp"
|
||||
|
||||
if E.db.general.interruptAnnounce == "PARTY" then
|
||||
if GetNumPartyMembers() > 0 then
|
||||
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "PARTY")
|
||||
end
|
||||
elseif E.db.general.interruptAnnounce == "RAID" then
|
||||
if GetNumRaidMembers() > 0 then
|
||||
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "RAID")
|
||||
elseif GetNumPartyMembers() > 0 then
|
||||
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "PARTY")
|
||||
end
|
||||
elseif E.db.general.interruptAnnounce == "RAID_ONLY" then
|
||||
if GetNumRaidMembers() > 0 then
|
||||
SendChatMessage(format(interruptMsg, destName, spellID, spellName), battleground and "BATTLEGROUND" or "RAID")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local repairInventoryPriority = {
|
||||
16, -- MainHandSlot
|
||||
17, -- SecondaryHandSlot
|
||||
18, -- RangedSlot
|
||||
1, -- HeadSlot
|
||||
5, -- ChestSlot
|
||||
7, -- LegsSlot
|
||||
3, -- ShoulderSlot
|
||||
10, -- HandsSlot
|
||||
6, -- WaistSlot
|
||||
8, -- FeetSlot
|
||||
9, -- WristSlot
|
||||
}
|
||||
|
||||
local function RepairInventoryByPriority(playerMoney)
|
||||
local money = playerMoney
|
||||
|
||||
ShowRepairCursor()
|
||||
|
||||
for _, slotID in ipairs(repairInventoryPriority) do
|
||||
local hasItem, _, repairCost = GameTooltip:SetInventoryItem("player", slotID)
|
||||
|
||||
if hasItem and repairCost and repairCost > 0 and repairCost <= money then
|
||||
PickupInventoryItem(slotID)
|
||||
money = money - repairCost
|
||||
end
|
||||
end
|
||||
|
||||
HideRepairCursor()
|
||||
GameTooltip:Hide()
|
||||
|
||||
return playerMoney - money
|
||||
end
|
||||
|
||||
local function FullRepairMessage(repairAllCost)
|
||||
E:Print(format("%s%s", L["Your items have been repaired for: "], E:FormatMoney(repairAllCost, "SMART", true)))
|
||||
end
|
||||
|
||||
function M:AutoRepair(repairMode, greyValue)
|
||||
if not CanMerchantRepair() or IsShiftKeyDown() then return end
|
||||
|
||||
local repairAllCost, canRepair = GetRepairAllCost()
|
||||
if not canRepair or repairAllCost <= 0 then return end
|
||||
|
||||
if repairMode == "GUILD" then
|
||||
if not CanGuildBankRepair() then
|
||||
repairMode = "PLAYER"
|
||||
else
|
||||
local guildWithdrawMoney = GetGuildBankWithdrawMoney()
|
||||
local guildMoney = GetGuildBankMoney()
|
||||
local availableGuildMoney
|
||||
|
||||
if guildWithdrawMoney == -1 or guildMoney < guildWithdrawMoney then
|
||||
availableGuildMoney = guildMoney
|
||||
else
|
||||
availableGuildMoney = guildWithdrawMoney
|
||||
end
|
||||
|
||||
if repairAllCost > availableGuildMoney then
|
||||
repairMode = "PLAYER"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if repairMode == "GUILD" then
|
||||
RepairAllItems(true)
|
||||
|
||||
E:Print(format("%s%s", L["Your items have been repaired using guild bank funds for: "], E:FormatMoney(repairAllCost, "SMART", true)))
|
||||
else
|
||||
local playerMoney = GetMoney()
|
||||
|
||||
if playerMoney >= repairAllCost then
|
||||
RepairAllItems()
|
||||
FullRepairMessage(repairAllCost)
|
||||
elseif greyValue and playerMoney + greyValue >= repairAllCost then
|
||||
self.playerMoney = playerMoney
|
||||
self.repairAllCost = repairAllCost
|
||||
|
||||
self:RegisterEvent("MERCHANT_CLOSED")
|
||||
E.RegisterCallback(M, "VendorGreys_ItemSold")
|
||||
elseif playerMoney > 0 then
|
||||
local spent = RepairInventoryByPriority(playerMoney)
|
||||
|
||||
if spent > 0 then
|
||||
E:Print(format("%s%s", L["Your items have been repaired for: "], E:FormatMoney(spent, "SMART", true)))
|
||||
E:Print(L["You don't have enough money to repair all items."])
|
||||
else
|
||||
E:Print(L["You don't have enough money to repair."])
|
||||
end
|
||||
else
|
||||
E:Print(L["You don't have enough money to repair."])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:VendorGreys_ItemSold(_, moneyGained)
|
||||
self.playerMoney = self.playerMoney + moneyGained
|
||||
|
||||
if self.playerMoney >= self.repairAllCost then
|
||||
if self.playerMoney > GetMoney() then
|
||||
self:RegisterEvent("PLAYER_MONEY")
|
||||
E.UnregisterCallback(M, "VendorGreys_ItemSold")
|
||||
else
|
||||
RepairAllItems()
|
||||
FullRepairMessage(self.repairAllCost)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:PLAYER_MONEY()
|
||||
if self.playerMoney <= GetMoney() then
|
||||
RepairAllItems()
|
||||
FullRepairMessage(self.repairAllCost)
|
||||
|
||||
self:MERCHANT_CLOSED()
|
||||
end
|
||||
end
|
||||
|
||||
function M:MERCHANT_CLOSED()
|
||||
self.playerMoney = nil
|
||||
self.repairAllCost = nil
|
||||
|
||||
self:UnregisterEvent("PLAYER_MONEY")
|
||||
self:UnregisterEvent("MERCHANT_CLOSED")
|
||||
E.UnregisterCallback(M, "VendorGreys_ItemSold")
|
||||
end
|
||||
end
|
||||
|
||||
function M:MERCHANT_SHOW()
|
||||
local greyValue
|
||||
|
||||
if E.db.bags.vendorGrays.enable then
|
||||
local itemCount
|
||||
itemCount, greyValue = Bags:GetGraysInfo()
|
||||
|
||||
if itemCount > 0 then
|
||||
Bags:VendorGrays()
|
||||
end
|
||||
end
|
||||
|
||||
local repairMode = E.db.general.autoRepair
|
||||
if repairMode ~= "NONE" then
|
||||
E:Delay(0.03, self.AutoRepair, self, repairMode, greyValue)
|
||||
end
|
||||
end
|
||||
|
||||
function M:DisbandRaidGroup()
|
||||
if InCombatLockdown() then return end -- Prevent user error in combat
|
||||
|
||||
local numRaid = GetNumRaidMembers()
|
||||
|
||||
if numRaid > 0 then
|
||||
for i = 1, numRaid do
|
||||
local name, _, _, _, _, _, _, online = GetRaidRosterInfo(i)
|
||||
if online and name ~= E.myname then
|
||||
UninviteUnit(name)
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = MAX_PARTY_MEMBERS, 1, -1 do
|
||||
if GetPartyMember(i) then
|
||||
UninviteUnit(UnitName("party"..i))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
LeaveParty()
|
||||
end
|
||||
|
||||
function M:PVPMessageEnhancement(_, msg)
|
||||
if not E.db.general.enhancedPvpMessages then return end
|
||||
|
||||
local _, instanceType = IsInInstance()
|
||||
if instanceType == "pvp" or instanceType == "arena" then
|
||||
RaidNotice_AddMessage(RaidBossEmoteFrame, msg, ChatTypeInfo.RAID_BOSS_EMOTE)
|
||||
end
|
||||
end
|
||||
|
||||
function M:AutoInvite(event, leaderName)
|
||||
if not E.db.general.autoAcceptInvite then return end
|
||||
|
||||
if MiniMapLFGFrame:IsShown() then return end
|
||||
if GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 then return end
|
||||
|
||||
local numFriends = GetNumFriends()
|
||||
|
||||
if numFriends > 0 then
|
||||
ShowFriends()
|
||||
|
||||
for i = 1, numFriends do
|
||||
if GetFriendInfo(i) == leaderName then
|
||||
AcceptGroup()
|
||||
StaticPopup_Hide("PARTY_INVITE")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not IsInGuild() then return end
|
||||
|
||||
GuildRoster()
|
||||
|
||||
for i = 1, GetNumGuildMembers() do
|
||||
if GetGuildRosterInfo(i) == leaderName then
|
||||
AcceptGroup()
|
||||
StaticPopup_Hide("PARTY_INVITE")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M:ForceCVars(event)
|
||||
if not GetCVarBool("lockActionBars") then
|
||||
SetCVar("lockActionBars", 1)
|
||||
end
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
|
||||
end
|
||||
end
|
||||
|
||||
function M:Initialize()
|
||||
self:LoadRaidMarker()
|
||||
self:LoadLoot()
|
||||
self:LoadLootRoll()
|
||||
self:LoadChatBubbles()
|
||||
|
||||
self:ToggleErrorHandling()
|
||||
self:ToggleInterruptAnnounce()
|
||||
|
||||
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE", "PVPMessageEnhancement")
|
||||
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE", "PVPMessageEnhancement")
|
||||
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL", "PVPMessageEnhancement")
|
||||
self:RegisterEvent("PARTY_INVITE_REQUEST", "AutoInvite")
|
||||
self:RegisterEvent("MERCHANT_SHOW")
|
||||
|
||||
if E.private.actionbar.enable then
|
||||
self:RegisterEvent("CVAR_UPDATE", "ForceCVars")
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD", "ForceCVars")
|
||||
end
|
||||
|
||||
self.Initialized = true
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
M:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(M:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,395 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local RB = E:GetModule("ReminderBuffs")
|
||||
local LSM = E.Libs.LSM
|
||||
|
||||
--Lua functions
|
||||
local ipairs, unpack = ipairs, unpack
|
||||
--WoW API / Variables
|
||||
local CooldownFrame_SetTimer = CooldownFrame_SetTimer
|
||||
local CreateFrame = CreateFrame
|
||||
local GetSpellInfo = GetSpellInfo
|
||||
local GetTime = GetTime
|
||||
local UnitAura = UnitAura
|
||||
|
||||
RB.Spell1Buffs = {
|
||||
67016, -- Flask of the North (SP)
|
||||
67017, -- Flask of the North (AP)
|
||||
67018, -- Flask of the North (STR)
|
||||
53755, -- Flask of the Frost Wyrm
|
||||
53758, -- Flask of Stoneblood
|
||||
53760, -- Flask of Endless Rage
|
||||
54212, -- Flask of Pure Mojo
|
||||
53752, -- Lesser Flask of Toughness (50 Resilience)
|
||||
17627, -- Flask of Distilled Wisdom
|
||||
|
||||
33721, -- Spellpower Elixir
|
||||
53746, -- Wrath Elixir
|
||||
28497, -- Elixir of Mighty Agility
|
||||
53748, -- Elixir of Mighty Strength
|
||||
60346, -- Elixir of Lightning Speed
|
||||
60344, -- Elixir of Expertise
|
||||
60341, -- Elixir of Deadly Strikes
|
||||
60345, -- Elixir of Armor Piercing
|
||||
60340, -- Elixir of Accuracy
|
||||
53749, -- Guru's Elixir
|
||||
|
||||
60343, -- Elixir of Mighty Defense
|
||||
53751, -- Elixir of Mighty Fortitude
|
||||
53764, -- Elixir of Mighty Mageblood
|
||||
60347, -- Elixir of Mighty Thoughts
|
||||
53763, -- Elixir of Protection
|
||||
53747, -- Elixir of Spirit
|
||||
}
|
||||
|
||||
RB.Spell2Buffs = {
|
||||
57325, -- 80 AP
|
||||
57327, -- 46 SP
|
||||
57329, -- 40 Critical Strike Rating
|
||||
57332, -- 40 Haste Rating
|
||||
57334, -- 20 MP5
|
||||
57356, -- 40 Expertise Rating
|
||||
57358, -- 40 ARP
|
||||
57360, -- 40 Hit Rating
|
||||
57363, -- Tracking Humanoids
|
||||
57365, -- 40 Spirit
|
||||
57367, -- 40 AGI
|
||||
57371, -- 40 STR
|
||||
57373, -- Tracking Beasts
|
||||
57399, -- 80 AP, 46 SP
|
||||
59230, -- 40 Dodge Rating
|
||||
65247, -- 20 STR
|
||||
}
|
||||
|
||||
RB.Spell3Buffs = {
|
||||
72588, -- Gift of the Wild
|
||||
48469, -- Mark of the Wild
|
||||
}
|
||||
|
||||
RB.Spell4Buffs = {
|
||||
25898, -- Greater Blessing of Kings
|
||||
20217, -- Blessing of Kings
|
||||
72586, -- Blessing of Forgotten Kings
|
||||
}
|
||||
|
||||
RB.Spell5Buffs = {
|
||||
48162, -- Prayer of Fortitude
|
||||
48161, -- Power Word: Fortitude
|
||||
72590, -- Fortitude
|
||||
}
|
||||
|
||||
RB.Spell6Buffs = {
|
||||
20911, -- Blessing of Sanctuary
|
||||
25899, -- Greater Blessing of Sanctuary
|
||||
}
|
||||
|
||||
RB.CasterSpell7Buffs = {
|
||||
61316, -- Dalaran Brilliance
|
||||
43002, -- Arcane Brilliance
|
||||
42995, -- Arcane Intellect
|
||||
}
|
||||
|
||||
RB.AttackSpell7Buffs = {
|
||||
48934, -- Greater Blessing of Might
|
||||
48932, -- Blessing of Might
|
||||
47436, -- Battle Shout
|
||||
}
|
||||
|
||||
RB.Spell8Buffs = {
|
||||
6307, -- Blood Pact
|
||||
469, -- Commanding Shout
|
||||
}
|
||||
|
||||
-- Armor buffs
|
||||
RB.Spell9Buffs = {
|
||||
25506, -- Stoneskin Totem
|
||||
465, -- Devotion Aura
|
||||
}
|
||||
|
||||
-- Concentration / Thorns
|
||||
RB.CasterSpell10Buffs = {
|
||||
19746, -- Concentration Aura
|
||||
}
|
||||
RB.AttackSpell10Buffs = {
|
||||
467, -- Thorns
|
||||
7294, -- Retribution Aura
|
||||
}
|
||||
|
||||
-- SP / Str+Dex totems
|
||||
RB.CasterSpell11Buffs = {
|
||||
30706, -- Totem of Wrath
|
||||
8227, -- Flametongue Totem
|
||||
47236, -- Demonic Pact
|
||||
}
|
||||
RB.AttackSpell11Buffs = {
|
||||
25527, -- Strength of Earth Totem
|
||||
}
|
||||
|
||||
-- Mana regen
|
||||
RB.Spell12Buffs = {
|
||||
48938, -- Greater Blessing of Wisdom
|
||||
48936, -- Blessing of Wisdom
|
||||
58777, -- Mana Spring
|
||||
}
|
||||
|
||||
-- Crit % Increase
|
||||
RB.CasterSpell13Buffs = {
|
||||
51471, -- Elemental Oath
|
||||
24907, -- Moonkin Aura
|
||||
}
|
||||
RB.AttackSpell13Buffs = {
|
||||
17007, -- Leader of the Pack
|
||||
29801, -- Rampage
|
||||
}
|
||||
|
||||
-- Haste % Increase
|
||||
RB.CasterSpell14Buffs = {
|
||||
50172, -- Moonkin's Presence
|
||||
2895, -- Wrath of Air
|
||||
853648, -- Swift Retribution
|
||||
}
|
||||
RB.AttackSpell14Buffs = {
|
||||
8512, -- Windfury Totem
|
||||
}
|
||||
|
||||
-- Spirit Buff
|
||||
RB.CasterSpell15Buffs = {
|
||||
14752, -- Divine Spirit
|
||||
27681, -- Prayer of Spirit
|
||||
}
|
||||
-- Percent AP
|
||||
RB.AttackSpell15Buffs = {
|
||||
19506, -- Trueshot Aura
|
||||
30802, -- Unleashed Rage
|
||||
53137, -- Abomination's Might
|
||||
}
|
||||
|
||||
-- Percent Damage
|
||||
RB.Spell16Buffs = {
|
||||
31579, -- Arcane Empowerment
|
||||
31869, -- Sanctified Retribution
|
||||
34455, -- Ferocious Inspiration
|
||||
}
|
||||
|
||||
function RB:CheckFilterForActiveBuff(filter)
|
||||
for _, spell in ipairs(filter) do
|
||||
local spellName = GetSpellInfo(spell)
|
||||
local name, _, texture, _, _, duration, expirationTime = UnitAura("player", spellName)
|
||||
|
||||
if name then
|
||||
return texture, duration, expirationTime
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RB:UpdateReminderTime(elapsed)
|
||||
self.expiration = self.expiration - elapsed
|
||||
|
||||
if self.nextUpdate > 0 then
|
||||
self.nextUpdate = self.nextUpdate - elapsed
|
||||
return
|
||||
end
|
||||
|
||||
if self.expiration <= 0 then
|
||||
self.timer:SetText("")
|
||||
self:SetScript("OnUpdate", nil)
|
||||
return
|
||||
end
|
||||
|
||||
local value, id, nextUpdate, remainder = E:GetTimeInfo(self.expiration, 4)
|
||||
self.nextUpdate = nextUpdate
|
||||
|
||||
local style = E.TimeFormats[id]
|
||||
if style then
|
||||
self.timer:SetFormattedText(style[1], value, remainder)
|
||||
end
|
||||
end
|
||||
|
||||
function RB:UpdateReminder(event, unit)
|
||||
if event == "UNIT_AURA" and unit ~= "player" then return end
|
||||
|
||||
for i = 1, 16 do
|
||||
local texture, duration, expirationTime = self:CheckFilterForActiveBuff(self["Spell"..i.."Buffs"])
|
||||
local button = self.frame[i]
|
||||
|
||||
if texture then
|
||||
button.t:SetTexture(texture)
|
||||
|
||||
if (duration == 0 and expirationTime == 0) or E.db.general.reminder.durations ~= true then
|
||||
button.t:SetAlpha(E.db.general.reminder.reverse and 1 or 0.3)
|
||||
button:SetScript("OnUpdate", nil)
|
||||
button.timer:SetText(nil)
|
||||
CooldownFrame_SetTimer(button.cd, 0, 0, 0)
|
||||
else
|
||||
button.expiration = expirationTime - GetTime()
|
||||
button.nextUpdate = 0
|
||||
button.t:SetAlpha(1)
|
||||
CooldownFrame_SetTimer(button.cd, expirationTime - duration, duration, 1)
|
||||
button.cd:SetReverse(E.db.general.reminder.reverse)
|
||||
button:SetScript("OnUpdate", self.UpdateReminderTime)
|
||||
end
|
||||
else
|
||||
CooldownFrame_SetTimer(button.cd, 0, 0, 0)
|
||||
button.t:SetAlpha(E.db.general.reminder.reverse and 0.3 or 1)
|
||||
button:SetScript("OnUpdate", nil)
|
||||
button.timer:SetText(nil)
|
||||
button.t:SetTexture(self.DefaultIcons[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RB:CreateButton()
|
||||
local button = CreateFrame("Button", nil, ElvUI_ReminderBuffs)
|
||||
button:SetTemplate("Default")
|
||||
|
||||
button.t = button:CreateTexture(nil, "OVERLAY")
|
||||
button.t:SetTexCoord(unpack(E.TexCoords))
|
||||
button.t:SetInside()
|
||||
button.t:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
|
||||
|
||||
button.cd = CreateFrame("Cooldown", nil, button, "CooldownFrameTemplate")
|
||||
button.cd:SetInside()
|
||||
button.cd.noOCC = true
|
||||
button.cd.noCooldownCount = true
|
||||
|
||||
button.timer = button.cd:CreateFontString(nil, "OVERLAY")
|
||||
button.timer:SetPoint("CENTER")
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
function RB:EnableRB()
|
||||
ElvUI_ReminderBuffs:Show()
|
||||
self:RegisterEvent("UNIT_AURA", "UpdateReminder")
|
||||
self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", "UpdateReminder")
|
||||
self:RegisterEvent("CHARACTER_POINTS_CHANGED", "UpdateReminder")
|
||||
E.RegisterCallback(self, "RoleChanged", "UpdateSettings")
|
||||
self:UpdateReminder()
|
||||
end
|
||||
|
||||
function RB:DisableRB()
|
||||
ElvUI_ReminderBuffs:Hide()
|
||||
self:UnregisterEvent("UNIT_AURA")
|
||||
self:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
|
||||
self:UnregisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
E.UnregisterCallback(self, "RoleChanged", "UpdateSettings")
|
||||
end
|
||||
|
||||
function RB:UpdateSettings(isCallback)
|
||||
local frame = self.frame
|
||||
frame:Width(E.RBRWidth * 2)
|
||||
|
||||
self:UpdateDefaultIcons()
|
||||
|
||||
for i = 1, 16 do
|
||||
local button = frame[i]
|
||||
button:ClearAllPoints()
|
||||
button:SetWidth(E.RBRWidth)
|
||||
button:SetHeight(E.RBRWidth)
|
||||
|
||||
if i == 1 then
|
||||
button:SetPoint("TOPLEFT", ElvUI_ReminderBuffs, "TOPLEFT", 0, -1)
|
||||
elseif i == 9 then
|
||||
button:SetPoint("TOPRIGHT", ElvUI_ReminderBuffs, "TOPRIGHT", 0, -1)
|
||||
else
|
||||
button:Point("TOP", frame[i - 1], "BOTTOM", 0, E.Border - E.Spacing*3)
|
||||
end
|
||||
|
||||
if E.db.general.reminder.durations then
|
||||
button.cd:SetAlpha(1)
|
||||
else
|
||||
button.cd:SetAlpha(0)
|
||||
end
|
||||
|
||||
button.timer:FontTemplate(LSM:Fetch("font", E.db.general.reminder.font), E.db.general.reminder.fontSize, E.db.general.reminder.fontOutline)
|
||||
end
|
||||
|
||||
if not isCallback then
|
||||
if E.db.general.reminder.enable then
|
||||
RB:EnableRB()
|
||||
else
|
||||
RB:DisableRB()
|
||||
end
|
||||
else
|
||||
self:UpdateReminder()
|
||||
end
|
||||
end
|
||||
|
||||
function RB:UpdatePosition()
|
||||
Minimap:ClearAllPoints()
|
||||
ElvConfigToggle:ClearAllPoints()
|
||||
ElvUI_ReminderBuffs:ClearAllPoints()
|
||||
if E.db.general.reminder.position == "LEFT" then
|
||||
Minimap:Point("TOPRIGHT", MMHolder, "TOPRIGHT", -E.Border, -E.Border)
|
||||
ElvConfigToggle:SetPoint("TOPRIGHT", LeftMiniPanel, "TOPLEFT", E.Border - E.Spacing*3, 0)
|
||||
ElvConfigToggle:SetPoint("BOTTOMRIGHT", LeftMiniPanel, "BOTTOMLEFT", E.Border - E.Spacing*3, 0)
|
||||
ElvUI_ReminderBuffs:SetPoint("TOPRIGHT", Minimap.backdrop, "TOPLEFT", E.Border - E.Spacing*3, 0)
|
||||
ElvUI_ReminderBuffs:SetPoint("BOTTOMRIGHT", Minimap.backdrop, "BOTTOMLEFT", E.Border - E.Spacing*3, 0)
|
||||
else
|
||||
Minimap:Point("TOPLEFT", MMHolder, "TOPLEFT", E.Border, -E.Border)
|
||||
ElvConfigToggle:SetPoint("TOPLEFT", RightMiniPanel, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
ElvConfigToggle:SetPoint("BOTTOMLEFT", RightMiniPanel, "BOTTOMRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
ElvUI_ReminderBuffs:SetPoint("TOPLEFT", Minimap.backdrop, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
ElvUI_ReminderBuffs:SetPoint("BOTTOMLEFT", Minimap.backdrop, "BOTTOMRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function RB:UpdateDefaultIcons()
|
||||
local isCaster = E.private.general.reminder.classtype == "Caster"
|
||||
self.DefaultIcons = {
|
||||
[1] = "Interface\\Icons\\INV_Potion_97",
|
||||
[2] = "Interface\\Icons\\Spell_Misc_Food",
|
||||
[3] = "Interface\\Icons\\Spell_Nature_Regeneration",
|
||||
[4] = "Interface\\Icons\\Spell_Magic_GreaterBlessingofKings",
|
||||
[5] = "Interface\\Icons\\Spell_Holy_WordFortitude",
|
||||
[6] = "Interface\\Icons\\spell_nature_lightningshield",
|
||||
[7] = (isCaster and "Interface\\Icons\\Spell_Holy_MagicalSentry") or "Interface\\Icons\\spell_holy_fistofjustice",
|
||||
[8] = "Interface\\Icons\\ability_warrior_rallyingcry",
|
||||
[9] = "Interface\\Icons\\spell_nature_stoneskintotem",
|
||||
[10] = (isCaster and "Interface\\Icons\\spell_holy_mindsooth") or "Interface\\Icons\\spell_nature_thorns",
|
||||
[11] = (isCaster and "Interface\\Icons\\spell_fire_totemofwrath") or "Interface\\Icons\\spell_nature_earthbindtotem",
|
||||
[12] = "Interface\\Icons\\Spell_Holy_GreaterBlessingofWisdom",
|
||||
[13] = (isCaster and "Interface\\Icons\\spell_nature_moonglow") or "Interface\\Icons\\spell_nature_unyeildingstamina",
|
||||
[14] = (isCaster and "Interface\\Icons\\spell_nature_forceofnature") or "Interface\\Icons\\spell_nature_windfury",
|
||||
[15] = (isCaster and "Interface\\Icons\\spell_holy_prayerofspirit") or "Interface\\Icons\\ability_trueshot",
|
||||
[16] = "Interface\\Icons\\spell_nature_starfall",
|
||||
}
|
||||
|
||||
self.Spell7Buffs = isCaster and self.CasterSpell7Buffs or self.AttackSpell7Buffs
|
||||
|
||||
self.Spell10Buffs = isCaster and self.CasterSpell10Buffs or self.AttackSpell10Buffs
|
||||
self.Spell11Buffs = isCaster and self.CasterSpell11Buffs or self.AttackSpell11Buffs
|
||||
|
||||
self.Spell13Buffs = isCaster and self.CasterSpell13Buffs or self.AttackSpell13Buffs
|
||||
self.Spell14Buffs = isCaster and self.CasterSpell14Buffs or self.AttackSpell14Buffs
|
||||
self.Spell15Buffs = isCaster and self.CasterSpell15Buffs or self.AttackSpell15Buffs
|
||||
end
|
||||
|
||||
function RB:Initialize()
|
||||
if not E.private.general.minimap.enable then return end
|
||||
|
||||
self.db = E.db.general.reminder
|
||||
|
||||
local frame = CreateFrame("Frame", "ElvUI_ReminderBuffs", Minimap)
|
||||
frame:Width(E.RBRWidth)
|
||||
if E.db.general.reminder.position == "LEFT" then
|
||||
frame:Point("TOPRIGHT", Minimap.backdrop, "TOPLEFT", E.Border - E.Spacing*3, 0)
|
||||
frame:Point("BOTTOMRIGHT", Minimap.backdrop, "BOTTOMLEFT", E.Border - E.Spacing*3, 0)
|
||||
else
|
||||
frame:Point("TOPLEFT", Minimap.backdrop, "TOPRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
frame:Point("BOTTOMLEFT", Minimap.backdrop, "BOTTOMRIGHT", -E.Border + E.Spacing*3, 0)
|
||||
end
|
||||
self.frame = frame
|
||||
|
||||
for i = 1, 16 do
|
||||
frame[i] = self:CreateButton()
|
||||
frame[i]:SetID(i)
|
||||
end
|
||||
|
||||
self:UpdateSettings()
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
RB:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(RB:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,104 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local M = E:GetModule("Misc")
|
||||
|
||||
--Lua functions
|
||||
local sin, cos, pi = math.sin, math.cos, math.pi
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local GetNumPartyMembers = GetNumPartyMembers
|
||||
local UnitInRaid = UnitInRaid
|
||||
local UnitIsPartyLeader = UnitIsPartyLeader
|
||||
local UnitIsRaidOfficer = UnitIsRaidOfficer
|
||||
local UnitExists, UnitIsDead = UnitExists, UnitIsDead
|
||||
local GetCursorPosition = GetCursorPosition
|
||||
local PlaySound = PlaySound
|
||||
local SetRaidTarget = SetRaidTarget
|
||||
local SetRaidTargetIconTexture = SetRaidTargetIconTexture
|
||||
local UIErrorsFrame = UIErrorsFrame
|
||||
|
||||
local ButtonIsDown
|
||||
|
||||
function M:RaidMarkCanMark()
|
||||
if not self.RaidMarkFrame then return false end
|
||||
|
||||
if GetNumPartyMembers() > 0 then
|
||||
if UnitIsPartyLeader("player") or (UnitInRaid("player") and UnitIsRaidOfficer("player") and not UnitIsPartyLeader("player")) then
|
||||
return true
|
||||
else
|
||||
UIErrorsFrame:AddMessage(L["You don't have permission to mark targets."], 1.0, 0.1, 0.1, 1.0)
|
||||
return false
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function M:RaidMarkShowIcons()
|
||||
if not UnitExists("target") or UnitIsDead("target") then return end
|
||||
|
||||
local x, y = GetCursorPosition()
|
||||
local scale = E.UIParent:GetEffectiveScale()
|
||||
self.RaidMarkFrame:Point("CENTER", E.UIParent, "BOTTOMLEFT", x / scale, y / scale)
|
||||
self.RaidMarkFrame:Show()
|
||||
end
|
||||
|
||||
function RaidMark_HotkeyPressed(keystate)
|
||||
ButtonIsDown = (keystate == "down") and M:RaidMarkCanMark()
|
||||
if ButtonIsDown and M.RaidMarkFrame then
|
||||
M:RaidMarkShowIcons()
|
||||
elseif M.RaidMarkFrame then
|
||||
M.RaidMarkFrame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function M:RaidMark_OnEvent()
|
||||
if ButtonIsDown and self.RaidMarkFrame then
|
||||
self:RaidMarkShowIcons()
|
||||
end
|
||||
end
|
||||
M:RegisterEvent("PLAYER_TARGET_CHANGED", "RaidMark_OnEvent")
|
||||
|
||||
function M:RaidMarkButton_OnEnter()
|
||||
self.Texture:ClearAllPoints()
|
||||
self.Texture:Point("TOPLEFT", -10, 10)
|
||||
self.Texture:Point("BOTTOMRIGHT", 10, -10)
|
||||
end
|
||||
|
||||
function M:RaidMarkButton_OnLeave()
|
||||
self.Texture:SetAllPoints()
|
||||
end
|
||||
|
||||
function M:RaidMarkButton_OnClick(button)
|
||||
PlaySound("UChatScrollButton")
|
||||
SetRaidTarget("target", (button ~= "RightButton") and self:GetID() or 0)
|
||||
self:GetParent():Hide()
|
||||
end
|
||||
|
||||
function M:LoadRaidMarker()
|
||||
local marker = CreateFrame("Frame", nil, E.UIParent)
|
||||
marker:EnableMouse(true)
|
||||
marker:Size(100)
|
||||
marker:SetFrameStrata("DIALOG")
|
||||
|
||||
for i = 1, 8 do
|
||||
local button = CreateFrame("Button", "RaidMarkIconButton"..i, marker)
|
||||
button:Size(40)
|
||||
button:SetID(i)
|
||||
button.Texture = button:CreateTexture(button:GetName().."NormalTexture", "ARTWORK")
|
||||
button.Texture:SetTexture([[Interface\TargetingFrame\UI-RaidTargetingIcons]])
|
||||
button.Texture:SetAllPoints()
|
||||
SetRaidTargetIconTexture(button.Texture, i)
|
||||
button:RegisterForClicks("LeftbuttonUp","RightbuttonUp")
|
||||
button:SetScript("OnClick", M.RaidMarkButton_OnClick)
|
||||
button:SetScript("OnEnter", M.RaidMarkButton_OnEnter)
|
||||
button:SetScript("OnLeave", M.RaidMarkButton_OnLeave)
|
||||
if i == 8 then
|
||||
button:Point("CENTER")
|
||||
else
|
||||
local angle = pi / 0.7 * i
|
||||
button:Point("CENTER", sin(angle) * 60, cos(angle) * 60)
|
||||
end
|
||||
end
|
||||
|
||||
M.RaidMarkFrame = marker
|
||||
end
|
||||
@@ -0,0 +1,225 @@
|
||||
local E, L = unpack(select(2, ...)); --Import: Engine, Locales
|
||||
local RU = E:GetModule("RaidUtility")
|
||||
local S = E:GetModule("Skins")
|
||||
|
||||
--Lua functions
|
||||
local find = string.find
|
||||
--WoW API / Variables
|
||||
local CreateFrame = CreateFrame
|
||||
local IsInInstance = IsInInstance
|
||||
local GetNumRaidMembers = GetNumRaidMembers
|
||||
local GetNumPartyMembers = GetNumPartyMembers
|
||||
local IsPartyLeader = IsPartyLeader
|
||||
local IsRaidLeader = IsRaidLeader
|
||||
local IsRaidOfficer = IsRaidOfficer
|
||||
local InCombatLockdown = InCombatLockdown
|
||||
local DoReadyCheck = DoReadyCheck
|
||||
local ToggleFriendsFrame = ToggleFriendsFrame
|
||||
|
||||
local PANEL_HEIGHT = 100
|
||||
|
||||
local function CheckRaidStatus()
|
||||
local inInstance, instanceType = IsInInstance()
|
||||
if (((IsRaidLeader() or IsRaidOfficer()) and GetNumRaidMembers() > 0) or (IsPartyLeader() and GetNumPartyMembers() > 0)) and not (inInstance and (instanceType == "pvp" or instanceType == "arena")) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Function to create buttons in this module
|
||||
function RU:CreateUtilButton(name, parent, template, width, height, point, relativeto, point2, xOfs, yOfs, text, texture)
|
||||
local button = CreateFrame("Button", name, parent, template)
|
||||
button:Width(width)
|
||||
button:Height(height)
|
||||
button:Point(point, relativeto, point2, xOfs, yOfs)
|
||||
S:HandleButton(button)
|
||||
|
||||
if text then
|
||||
button.text = button:CreateFontString(nil, "OVERLAY", button)
|
||||
button.text:FontTemplate()
|
||||
button.text:Point("CENTER", button, "CENTER", 0, -1)
|
||||
button.text:SetJustifyH("CENTER")
|
||||
button.text:SetText(text)
|
||||
button:SetFontString(button.text)
|
||||
elseif texture then
|
||||
button.texture = button:CreateTexture(nil, "OVERLAY", nil)
|
||||
button.texture:SetTexture(texture)
|
||||
button.texture:Point("TOPLEFT", button, "TOPLEFT", E.mult, -E.mult)
|
||||
button.texture:Point("BOTTOMRIGHT", button, "BOTTOMRIGHT", -E.mult, E.mult)
|
||||
end
|
||||
end
|
||||
|
||||
function RU:ToggleRaidUtil(event)
|
||||
if InCombatLockdown() then
|
||||
self:RegisterEvent("PLAYER_REGEN_ENABLED", "ToggleRaidUtil")
|
||||
return
|
||||
end
|
||||
|
||||
if CheckRaidStatus() then
|
||||
if RaidUtilityPanel.toggled == true then
|
||||
RaidUtility_ShowButton:Hide()
|
||||
RaidUtilityPanel:Show()
|
||||
else
|
||||
RaidUtility_ShowButton:Show()
|
||||
RaidUtilityPanel:Hide()
|
||||
end
|
||||
else
|
||||
RaidUtility_ShowButton:Hide()
|
||||
RaidUtilityPanel:Hide()
|
||||
end
|
||||
|
||||
if event == "PLAYER_REGEN_ENABLED" then
|
||||
self:UnregisterEvent("PLAYER_REGEN_ENABLED", "ToggleRaidUtil")
|
||||
end
|
||||
end
|
||||
|
||||
function RU:Initialize()
|
||||
if not E.private.general.raidUtility then return end
|
||||
self.Initialized = true
|
||||
|
||||
--Create main frame
|
||||
local RaidUtilityPanel = CreateFrame("Frame", "RaidUtilityPanel", E.UIParent, "SecureHandlerClickTemplate")
|
||||
RaidUtilityPanel:SetTemplate("Transparent")
|
||||
RaidUtilityPanel:Width(230)
|
||||
RaidUtilityPanel:Height(PANEL_HEIGHT)
|
||||
RaidUtilityPanel:Point("TOP", E.UIParent, "TOP", -400, 1)
|
||||
RaidUtilityPanel:SetFrameLevel(3)
|
||||
RaidUtilityPanel.toggled = false
|
||||
RaidUtilityPanel:SetFrameStrata("HIGH")
|
||||
|
||||
self:CreateUtilButton("RaidUtility_ShowButton", E.UIParent, "SecureHandlerClickTemplate", 136, 18, "TOP", E.UIParent, "TOP", -400, E.Border, RAID_CONTROL, nil)
|
||||
RaidUtility_ShowButton:SetFrameRef("RaidUtilityPanel", RaidUtilityPanel)
|
||||
RaidUtility_ShowButton:SetAttribute("_onclick", ([=[
|
||||
local raidUtil = self:GetFrameRef("RaidUtilityPanel")
|
||||
local closeButton = raidUtil:GetFrameRef("RaidUtility_CloseButton")
|
||||
|
||||
self:Hide()
|
||||
raidUtil:Show()
|
||||
|
||||
local point = self:GetPoint()
|
||||
local raidUtilPoint, closeButtonPoint, yOffset
|
||||
|
||||
if string.find(point, "BOTTOM") then
|
||||
raidUtilPoint = "BOTTOM"
|
||||
closeButtonPoint = "TOP"
|
||||
yOffset = 1
|
||||
else
|
||||
raidUtilPoint = "TOP"
|
||||
closeButtonPoint = "BOTTOM"
|
||||
yOffset = -1
|
||||
end
|
||||
|
||||
yOffset = yOffset * (tonumber(%d))
|
||||
|
||||
raidUtil:ClearAllPoints()
|
||||
closeButton:ClearAllPoints()
|
||||
raidUtil:SetPoint(raidUtilPoint, self, raidUtilPoint)
|
||||
closeButton:SetPoint(raidUtilPoint, raidUtil, closeButtonPoint, 0, yOffset)
|
||||
]=]):format(-E.Border + E.Spacing * 3))
|
||||
RaidUtility_ShowButton:SetScript("OnMouseUp", function()
|
||||
RaidUtilityPanel.toggled = true
|
||||
end)
|
||||
RaidUtility_ShowButton:SetMovable(true)
|
||||
RaidUtility_ShowButton:SetClampedToScreen(true)
|
||||
RaidUtility_ShowButton:SetClampRectInsets(0, 0, -1, 1)
|
||||
RaidUtility_ShowButton:RegisterForDrag("RightButton")
|
||||
RaidUtility_ShowButton:SetFrameStrata("HIGH")
|
||||
RaidUtility_ShowButton:SetScript("OnDragStart", function(self)
|
||||
if InCombatLockdown() then E:Print(ERR_NOT_IN_COMBAT) return end
|
||||
self:StartMoving()
|
||||
end)
|
||||
|
||||
RaidUtility_ShowButton:SetScript("OnDragStop", function(self)
|
||||
self:StopMovingOrSizing()
|
||||
local point = self:GetPoint()
|
||||
local xOffset = self:GetCenter()
|
||||
local screenWidth = E.UIParent:GetWidth() / 2
|
||||
xOffset = xOffset - screenWidth
|
||||
self:ClearAllPoints()
|
||||
if find(point, "BOTTOM") then
|
||||
self:Point("BOTTOM", E.UIParent, "BOTTOM", xOffset, -1)
|
||||
else
|
||||
self:Point("TOP", E.UIParent, "TOP", xOffset, 1)
|
||||
end
|
||||
end)
|
||||
|
||||
self:CreateUtilButton("RaidUtility_CloseButton", RaidUtilityPanel, "SecureHandlerClickTemplate", 136, 18, "TOP", RaidUtilityPanel, "BOTTOM", 0, -1, CLOSE, nil)
|
||||
RaidUtility_CloseButton:SetFrameRef("RaidUtility_ShowButton", RaidUtility_ShowButton)
|
||||
RaidUtility_CloseButton:SetAttribute("_onclick", [=[self:GetParent():Hide(); self:GetFrameRef("RaidUtility_ShowButton"):Show();]=])
|
||||
RaidUtility_CloseButton:SetScript("OnMouseUp", function() RaidUtilityPanel.toggled = false end)
|
||||
RaidUtilityPanel:SetFrameRef("RaidUtility_CloseButton", RaidUtility_CloseButton)
|
||||
|
||||
self:CreateUtilButton("DisbandRaidButton", RaidUtilityPanel, nil, RaidUtilityPanel:GetWidth() * 0.8, 18, "TOP", RaidUtilityPanel, "TOP", 0, -5, L["Disband Group"], nil)
|
||||
DisbandRaidButton:SetScript("OnMouseUp", function()
|
||||
if CheckRaidStatus() then
|
||||
E:StaticPopup_Show("DISBAND_RAID")
|
||||
end
|
||||
end)
|
||||
|
||||
self:CreateUtilButton("MainTankButton", RaidUtilityPanel, "SecureActionButtonTemplate", (DisbandRaidButton:GetWidth() / 2) - 2, 18, "TOPLEFT", DisbandRaidButton, "BOTTOMLEFT", 0, -5, MAINTANK, nil)
|
||||
MainTankButton:SetAttribute("type", "maintank")
|
||||
MainTankButton:SetAttribute("unit", "target")
|
||||
MainTankButton:SetAttribute("action", "toggle")
|
||||
|
||||
self:CreateUtilButton("MainAssistButton", RaidUtilityPanel, "SecureActionButtonTemplate", (DisbandRaidButton:GetWidth() / 2) - 2, 18, "TOPRIGHT", DisbandRaidButton, "BOTTOMRIGHT", 0, -5, MAINASSIST, nil)
|
||||
MainAssistButton:SetAttribute("type", "mainassist")
|
||||
MainAssistButton:SetAttribute("unit", "target")
|
||||
MainAssistButton:SetAttribute("action", "toggle")
|
||||
|
||||
self:CreateUtilButton("ReadyCheckButton", RaidUtilityPanel, nil, RaidUtilityPanel:GetWidth() * 0.8, 18, "TOPLEFT", MainTankButton, "BOTTOMLEFT", 0, -5, READY_CHECK, nil)
|
||||
ReadyCheckButton:SetScript("OnMouseUp", function()
|
||||
if CheckRaidStatus() then
|
||||
DoReadyCheck()
|
||||
end
|
||||
end)
|
||||
ReadyCheckButton:SetScript("OnEvent", function(btn)
|
||||
if not (IsRaidLeader("player") or IsRaidOfficer("player")) then
|
||||
btn:Disable()
|
||||
else
|
||||
btn:Enable()
|
||||
end
|
||||
end)
|
||||
ReadyCheckButton:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||
ReadyCheckButton:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
ReadyCheckButton:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
|
||||
self:CreateUtilButton("RaidControlButton", RaidUtilityPanel, nil, MainTankButton:GetWidth(), 18, "TOPLEFT", ReadyCheckButton, "BOTTOMLEFT", 0, -5, L["Raid Menu"], nil)
|
||||
RaidControlButton:SetScript("OnMouseUp", function()
|
||||
if InCombatLockdown() then E:Print(ERR_NOT_IN_COMBAT) return end
|
||||
ToggleFriendsFrame(5)
|
||||
end)
|
||||
|
||||
self:CreateUtilButton("ConvertRaidButton", RaidUtilityPanel, nil, MainAssistButton:GetWidth(), 18, "TOPRIGHT", ReadyCheckButton, "BOTTOMRIGHT", 0, -5, CONVERT_TO_RAID, nil)
|
||||
ConvertRaidButton:SetScript("OnMouseUp", function()
|
||||
if CheckRaidStatus() then
|
||||
ConvertToRaid()
|
||||
SetLootMethod("master", "player")
|
||||
end
|
||||
end)
|
||||
ConvertRaidButton:SetScript("OnEvent", function(btn)
|
||||
if GetNumRaidMembers() == 0 and GetNumPartyMembers() > 0 and IsPartyLeader() then
|
||||
if not btn:IsShown() then
|
||||
RaidControlButton:Width(MainAssistButton:GetWidth())
|
||||
btn:Show()
|
||||
end
|
||||
elseif btn:IsShown() then
|
||||
RaidControlButton:Width(DisbandRaidButton:GetWidth())
|
||||
btn:Hide()
|
||||
end
|
||||
end)
|
||||
ConvertRaidButton:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||
ConvertRaidButton:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
ConvertRaidButton:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
|
||||
--Automatically show/hide the frame if we have RaidLeader or RaidOfficer
|
||||
self:RegisterEvent("RAID_ROSTER_UPDATE", "ToggleRaidUtil")
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD", "ToggleRaidUtil")
|
||||
self:RegisterEvent("PARTY_MEMBERS_CHANGED", "ToggleRaidUtil")
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
RU:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterInitialModule(RU:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,176 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local THREAT = E:GetModule("Threat")
|
||||
local DT = E:GetModule("DataTexts")
|
||||
|
||||
--Lua functions
|
||||
local pairs, select = pairs, select
|
||||
local wipe = table.wipe
|
||||
--WoW API / Variables
|
||||
local GetNumPartyMembers = GetNumPartyMembers
|
||||
local GetNumRaidMembers = GetNumRaidMembers
|
||||
local GetThreatStatusColor = GetThreatStatusColor
|
||||
local UnitDetailedThreatSituation = UnitDetailedThreatSituation
|
||||
local UnitExists = UnitExists
|
||||
local UnitIsPlayer = UnitIsPlayer
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
local UnitName = UnitName
|
||||
local UnitReaction = UnitReaction
|
||||
|
||||
local UNKNOWN = UNKNOWN
|
||||
|
||||
local partyUnits, raidUnits = {}, {}
|
||||
for i = 1, 4 do partyUnits[i] = "party"..i end
|
||||
for i = 1, 40 do raidUnits[i] = "raid"..i end
|
||||
|
||||
function THREAT:UpdatePosition()
|
||||
if self.db.position == "RIGHTCHAT" then
|
||||
self.bar:SetInside(RightChatDataPanel)
|
||||
self.bar:SetParent(RightChatDataPanel)
|
||||
else
|
||||
self.bar:SetInside(LeftChatDataPanel)
|
||||
self.bar:SetParent(LeftChatDataPanel)
|
||||
end
|
||||
|
||||
self.bar.text:FontTemplate(nil, self.db.textSize)
|
||||
self.bar:SetFrameStrata("MEDIUM")
|
||||
end
|
||||
|
||||
function THREAT:GetLargestThreatOnList(percent)
|
||||
local largestValue, largestUnit = 0
|
||||
for unit, threatPercent in pairs(self.list) do
|
||||
if threatPercent > largestValue then
|
||||
largestValue = threatPercent
|
||||
largestUnit = unit
|
||||
end
|
||||
end
|
||||
|
||||
return (percent - largestValue), largestUnit
|
||||
end
|
||||
|
||||
function THREAT:GetColor(unit)
|
||||
if UnitIsPlayer(unit) then
|
||||
local class = E.media.herocolor
|
||||
if not class then
|
||||
return 194, 194, 194
|
||||
end
|
||||
|
||||
return class.r*255, class.g*255, class.b*255
|
||||
end
|
||||
|
||||
local unitReaction = UnitReaction(unit, "player")
|
||||
if unitReaction then
|
||||
local reaction = ElvUF.colors.reaction[unitReaction]
|
||||
return reaction[1]*255, reaction[2]*255, reaction[3]*255
|
||||
else
|
||||
return 194, 194, 194
|
||||
end
|
||||
end
|
||||
|
||||
function THREAT:Update()
|
||||
if not UnitExists("target") or (DT and DT.ShowingBGStats) then
|
||||
if self.bar:IsShown() then
|
||||
self.bar:Hide()
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local _, status, percent = UnitDetailedThreatSituation("player", "target")
|
||||
local petExists = HasPetUI()
|
||||
|
||||
if percent and percent > 0 and (GetNumPartyMembers() > 0 or petExists == 1) then
|
||||
local name = UnitName("target")
|
||||
self.bar:Show()
|
||||
|
||||
if percent == 100 then
|
||||
if petExists == 1 then
|
||||
self.list.pet = select(3, UnitDetailedThreatSituation("pet", "target"))
|
||||
end
|
||||
|
||||
if GetNumRaidMembers() > 0 then
|
||||
for i = 1, 40 do
|
||||
if UnitExists(raidUnits[i]) and not UnitIsUnit(raidUnits[i], "player") then
|
||||
self.list[raidUnits[i]] = select(3, UnitDetailedThreatSituation(raidUnits[i], "target"))
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = 1, 4 do
|
||||
if UnitExists(partyUnits[i]) then
|
||||
self.list[partyUnits[i]] = select(3, UnitDetailedThreatSituation(partyUnits[i], "target"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local leadPercent, largestUnit = self:GetLargestThreatOnList(percent)
|
||||
if leadPercent > 0 and largestUnit then
|
||||
local r, g, b = self:GetColor(largestUnit)
|
||||
self.bar.text:SetFormattedText(L["ABOVE_THREAT_FORMAT"], name, percent, leadPercent, r, g, b, UnitName(largestUnit) or UNKNOWN)
|
||||
|
||||
if E.Role == "Tank" then
|
||||
self.bar:SetStatusBarColor(0, 0.839, 0)
|
||||
self.bar:SetValue(leadPercent)
|
||||
else
|
||||
self.bar:SetStatusBarColor(GetThreatStatusColor(status))
|
||||
self.bar:SetValue(percent)
|
||||
end
|
||||
else
|
||||
self.bar:SetStatusBarColor(GetThreatStatusColor(status))
|
||||
self.bar:SetValue(percent)
|
||||
self.bar.text:SetFormattedText("%s: %.0f%%", name, percent)
|
||||
end
|
||||
else
|
||||
self.bar:SetStatusBarColor(GetThreatStatusColor(status))
|
||||
self.bar:SetValue(percent)
|
||||
self.bar.text:SetFormattedText("%s: %.0f%%", name, percent)
|
||||
end
|
||||
else
|
||||
self.bar:Hide()
|
||||
end
|
||||
|
||||
wipe(self.list)
|
||||
end
|
||||
|
||||
function THREAT:ToggleEnable()
|
||||
if self.db.enable then
|
||||
self:RegisterEvent("PLAYER_TARGET_CHANGED", "Update")
|
||||
self:RegisterEvent("UNIT_THREAT_LIST_UPDATE", "Update")
|
||||
self:RegisterEvent("PARTY_MEMBERS_CHANGED", "Update")
|
||||
self:RegisterEvent("RAID_ROSTER_UPDATE", "Update")
|
||||
self:RegisterEvent("UNIT_PET", "Update")
|
||||
self:Update()
|
||||
else
|
||||
self.bar:Hide()
|
||||
self:UnregisterEvent("PLAYER_TARGET_CHANGED")
|
||||
self:UnregisterEvent("UNIT_THREAT_LIST_UPDATE")
|
||||
self:UnregisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
self:UnregisterEvent("RAID_ROSTER_UPDATE")
|
||||
self:UnregisterEvent("UNIT_PET")
|
||||
end
|
||||
end
|
||||
|
||||
function THREAT:Initialize()
|
||||
self.db = E.db.general.threat
|
||||
|
||||
self.bar = CreateFrame("StatusBar", "ElvUI_ThreatBar", E.UIParent)
|
||||
self.bar:CreateBackdrop("Default")
|
||||
self.bar:SetMinMaxValues(0, 100)
|
||||
self.bar:SetStatusBarTexture(E.media.normTex)
|
||||
E:RegisterStatusBar(self.bar)
|
||||
|
||||
self.bar.text = self.bar:CreateFontString(nil, "OVERLAY")
|
||||
self.bar.text:FontTemplate(nil, self.db.textSize)
|
||||
self.bar.text:Point("CENTER", self.bar, "CENTER")
|
||||
|
||||
self.list = {}
|
||||
|
||||
self:UpdatePosition()
|
||||
self:ToggleEnable()
|
||||
|
||||
self.Initialized = true
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
THREAT:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(THREAT:GetName(), InitializeCallback)
|
||||
@@ -0,0 +1,181 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local TOTEMS = E:GetModule("Totems")
|
||||
|
||||
--Lua functions
|
||||
local unpack = unpack
|
||||
--WoW API / Variables
|
||||
local CooldownFrame_SetTimer = CooldownFrame_SetTimer
|
||||
local CreateFrame = CreateFrame
|
||||
local DestroyTotem = DestroyTotem
|
||||
local GetTotemInfo = GetTotemInfo
|
||||
|
||||
local MAX_TOTEMS = MAX_TOTEMS
|
||||
local TOTEM_PRIORITIES = TOTEM_PRIORITIES
|
||||
|
||||
local SLOT_BORDER_COLORS = {
|
||||
[EARTH_TOTEM_SLOT] = {r = 0.23, g = 0.45, b = 0.13}, -- [2]
|
||||
[FIRE_TOTEM_SLOT] = {r = 0.58, g = 0.23, b = 0.10}, -- [1]
|
||||
[WATER_TOTEM_SLOT] = {r = 0.19, g = 0.48, b = 0.60}, -- [3]
|
||||
[AIR_TOTEM_SLOT] = {r = 0.42, g = 0.18, b = 0.74} -- [4]
|
||||
}
|
||||
|
||||
function TOTEMS:UpdateAllTotems()
|
||||
for i = 1, MAX_TOTEMS do
|
||||
self:UpdateTotem(nil, i)
|
||||
end
|
||||
end
|
||||
|
||||
function TOTEMS:UpdateTotem(event, slot)
|
||||
local slotID = TOTEM_PRIORITIES[slot]
|
||||
local _, _, startTime, duration, icon = GetTotemInfo(slot)
|
||||
|
||||
if icon ~= "" then
|
||||
local color = SLOT_BORDER_COLORS[slot]
|
||||
self.bar[slotID].iconTexture:SetTexture(icon)
|
||||
self.bar[slotID]:SetBackdropBorderColor(color.r, color.g, color.b)
|
||||
|
||||
CooldownFrame_SetTimer(self.bar[slotID].cooldown, startTime, duration, 1)
|
||||
|
||||
self.bar[slotID]:Show()
|
||||
else
|
||||
self.bar[slotID]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function TOTEMS:ToggleEnable()
|
||||
if E.db.general.totems.enable then
|
||||
if self.Initialized then
|
||||
self.bar:Show()
|
||||
self:RegisterEvent("PLAYER_TOTEM_UPDATE", "UpdateTotem")
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateAllTotems")
|
||||
self:UpdateAllTotems()
|
||||
E:EnableMover("TotemBarMover")
|
||||
else
|
||||
self:Initialize()
|
||||
self:UpdateAllTotems()
|
||||
end
|
||||
elseif self.Initialized then
|
||||
self.bar:Hide()
|
||||
self:UnregisterEvent("PLAYER_TOTEM_UPDATE")
|
||||
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
|
||||
E:DisableMover("TotemBarMover")
|
||||
end
|
||||
end
|
||||
|
||||
function TOTEMS:PositionAndSize()
|
||||
if not self.Initialized then return end
|
||||
|
||||
for i = 1, MAX_TOTEMS do
|
||||
local button = self.bar[i]
|
||||
local prevButton = self.bar[i - 1]
|
||||
|
||||
button:Size(self.db.size)
|
||||
button:ClearAllPoints()
|
||||
|
||||
if self.db.growthDirection == "HORIZONTAL" and self.db.sortDirection == "ASCENDING" then
|
||||
if i == 1 then
|
||||
button:Point("LEFT", self.bar, "LEFT", self.db.spacing, 0)
|
||||
elseif prevButton then
|
||||
button:Point("LEFT", prevButton, "RIGHT", self.db.spacing, 0)
|
||||
end
|
||||
elseif self.db.growthDirection == "VERTICAL" and self.db.sortDirection == "ASCENDING" then
|
||||
if i == 1 then
|
||||
button:Point("TOP", self.bar, "TOP", 0, -self.db.spacing)
|
||||
elseif prevButton then
|
||||
button:Point("TOP", prevButton, "BOTTOM", 0, -self.db.spacing)
|
||||
end
|
||||
elseif self.db.growthDirection == "HORIZONTAL" and self.db.sortDirection == "DESCENDING" then
|
||||
if i == 1 then
|
||||
button:Point("RIGHT", self.bar, "RIGHT", -self.db.spacing, 0)
|
||||
elseif prevButton then
|
||||
button:Point("RIGHT", prevButton, "LEFT", -self.db.spacing, 0)
|
||||
end
|
||||
else
|
||||
if i == 1 then
|
||||
button:Point("BOTTOM", self.bar, "BOTTOM", 0, self.db.spacing)
|
||||
elseif prevButton then
|
||||
button:Point("BOTTOM", prevButton, "TOP", 0, self.db.spacing)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.db.growthDirection == "HORIZONTAL" then
|
||||
self.bar:Width(self.db.size*(MAX_TOTEMS) + self.db.spacing*(MAX_TOTEMS) + self.db.spacing)
|
||||
self.bar:Height(self.db.size + self.db.spacing * 2)
|
||||
else
|
||||
self.bar:Height(self.db.size*(MAX_TOTEMS) + self.db.spacing*(MAX_TOTEMS) + self.db.spacing)
|
||||
self.bar:Width(self.db.size + self.db.spacing * 2)
|
||||
end
|
||||
end
|
||||
|
||||
local function Button_OnClick(self)
|
||||
DestroyTotem(self.slot)
|
||||
end
|
||||
local function Button_OnEnter(self)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
|
||||
self:UpdateTooltip()
|
||||
end
|
||||
local function Button_OnLeave(self)
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
local function UpdateTooltip(self)
|
||||
if GameTooltip:IsOwned(self) then
|
||||
GameTooltip:SetTotem(self.slot)
|
||||
end
|
||||
end
|
||||
|
||||
function TOTEMS:Initialize()
|
||||
if not E.db.general.totems.enable then return end
|
||||
|
||||
self.db = E.db.general.totems
|
||||
|
||||
local bar = CreateFrame("Frame", "ElvUI_TotemBar", E.UIParent)
|
||||
bar:Point("TOPLEFT", LeftChatPanel, "TOPRIGHT", 14, 0)
|
||||
self.bar = bar
|
||||
|
||||
for i = 1, MAX_TOTEMS do
|
||||
local frame = CreateFrame("Button", "$parentTotem"..i, bar)
|
||||
frame.slot = TOTEM_PRIORITIES[i]
|
||||
frame:SetTemplate("Default")
|
||||
frame:StyleButton()
|
||||
frame.ignoreBorderColors = true
|
||||
frame:Hide()
|
||||
|
||||
frame.UpdateTooltip = UpdateTooltip
|
||||
|
||||
frame:RegisterForClicks("RightButtonUp")
|
||||
frame:SetScript("OnClick", Button_OnClick)
|
||||
frame:SetScript("OnEnter", Button_OnEnter)
|
||||
frame:SetScript("OnLeave", Button_OnLeave)
|
||||
|
||||
frame.holder = CreateFrame("Frame", nil, frame)
|
||||
frame.holder:SetAlpha(0)
|
||||
frame.holder:SetAllPoints()
|
||||
|
||||
frame.iconTexture = frame:CreateTexture(nil, "ARTWORK")
|
||||
frame.iconTexture:SetTexCoord(unpack(E.TexCoords))
|
||||
frame.iconTexture:SetInside()
|
||||
|
||||
frame.cooldown = CreateFrame("Cooldown", "$parentCooldown", frame, "CooldownFrameTemplate")
|
||||
frame.cooldown:SetReverse(true)
|
||||
frame.cooldown:SetInside()
|
||||
E:RegisterCooldown(frame.cooldown)
|
||||
|
||||
self.bar[i] = frame
|
||||
end
|
||||
|
||||
self.Initialized = true
|
||||
|
||||
self:PositionAndSize()
|
||||
|
||||
E:CreateMover(bar, "TotemBarMover", TUTORIAL_TITLE47, nil, nil, nil, nil, nil, "general,totems")
|
||||
|
||||
self:RegisterEvent("PLAYER_TOTEM_UPDATE", "UpdateTotem")
|
||||
self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateAllTotems")
|
||||
end
|
||||
|
||||
local function InitializeCallback()
|
||||
TOTEMS:Initialize()
|
||||
end
|
||||
|
||||
E:RegisterModule(TOTEMS:GetName(), InitializeCallback)
|
||||
Reference in New Issue
Block a user