1201 lines
33 KiB
Lua
1201 lines
33 KiB
Lua
--[[
|
|
Copyright (C) 2006-2007 Nymbia
|
|
Copyright (C) 2010 Hendrik "Nevcairiel" Leppkes < h.leppkes@gmail.com >
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
]]
|
|
local Quartz3 = LibStub("AceAddon-3.0"):GetAddon("Quartz3")
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("Quartz3")
|
|
|
|
local MODNAME = "Mirror"
|
|
local Mirror = Quartz3:NewModule(MODNAME, "AceHook-3.0", "AceEvent-3.0", "AceTimer-3.0")
|
|
local Player = Quartz3:GetModule("Player")
|
|
local Focus = Quartz3:GetModule("Focus")
|
|
local Target = Quartz3:GetModule("Target")
|
|
|
|
local TimeFmt = Quartz3.Util.TimeFormat
|
|
|
|
local media = LibStub("LibSharedMedia-3.0")
|
|
local lsmlist = AceGUIWidgetLSMlists
|
|
|
|
----------------------------
|
|
-- Upvalues
|
|
-- GLOBALS: MIRRORTIMER_NUMTIMERS
|
|
local _G = _G
|
|
local CreateFrame, GetTime, UIParent, StaticPopupDialogs = CreateFrame, GetTime, UIParent, StaticPopupDialogs
|
|
local GetMirrorTimerProgress, GetMirrorTimerInfo, GetCorpseRecoveryDelay = GetMirrorTimerProgress, GetMirrorTimerInfo, GetCorpseRecoveryDelay
|
|
local UnitHealth = UnitHealth
|
|
local pairs, unpack, next, wipe, error = pairs, unpack, next, wipe, error
|
|
local table_sort = table.sort
|
|
|
|
|
|
local gametimebase, gametimetostart
|
|
local lfgshowbase, readycheckshowbase, readycheckshowduration
|
|
local locked = true
|
|
|
|
local db, getOptions
|
|
|
|
local new, del
|
|
|
|
local defaults = {
|
|
profile = {
|
|
mirroricons = true,
|
|
mirroriconside = "left",
|
|
|
|
mirroranchor = "player",--L["Free"], L["Target"], L["Focus"]
|
|
|
|
mirrorx = 500,
|
|
mirrory = 700,
|
|
mirrorgrowdirection = "up", --L["Down"]
|
|
|
|
mirrorposition = "topleft",
|
|
|
|
mirrorgap = 1,
|
|
mirrorspacing = 1,
|
|
mirroroffset = 3,
|
|
|
|
mirrornametext = true,
|
|
mirrortimetext = true,
|
|
|
|
mirrortexture = "LiteStep",
|
|
mirrorwidth = 120,
|
|
mirrorheight = 12,
|
|
mirrorfont = "Friz Quadrata TT",
|
|
mirrorfontsize = 9,
|
|
mirroralpha = 1,
|
|
|
|
mirrortextcolor = {1, 1, 1},
|
|
BREATH = {0, 0.5, 1},
|
|
EXHAUSTION = {1.00, 0.9, 0},
|
|
FEIGNDEATH = {1, 0.7, 0},
|
|
CAMP = {1, 0.7, 0},
|
|
DEATH = {1, 0.1, 0.1},
|
|
QUIT = {1, 0.7, 0},
|
|
DUEL_OUTOFBOUNDS = {0.2, 0.8, 0.2},
|
|
INSTANCE_BOOT = {1, 0, 0},
|
|
CONFIRM_SUMMON = {1, 0.3, 1},
|
|
AREA_SPIRIT_HEAL = {0, 0.22, 1},
|
|
REZTIMER = {1, 0, 0.5},
|
|
RESURRECT_NO_SICKNESS = {0.47, 1, 0},
|
|
RESURRECT_NO_TIMER = {0.47, 1, 0},
|
|
PARTY_INVITE = {1, 0.9, 0},
|
|
DUEL_REQUESTED = {1, 0.13, 0},
|
|
GAMESTART = {0,1,0},
|
|
READYCHECK = {0,1,0},
|
|
|
|
hideblizzmirrors = true,
|
|
|
|
showmirror = true,
|
|
showstatic = true,
|
|
showpvp = true,
|
|
showreadycheck = true,
|
|
}
|
|
}
|
|
|
|
local icons = {
|
|
BREATH = "Interface\\Icons\\Spell_Shadow_DemonBreath",
|
|
EXHAUSTION = "Interface\\Icons\\Ability_Suffocate",
|
|
FEIGNDEATH = "Interface\\Icons\\Ability_Rogue_FeignDeath",
|
|
CAMP = "Interface\\Icons\\INV_Misc_GroupLooking",
|
|
DEATH = "Interface\\Icons\\Ability_Vanish",
|
|
QUIT = "Interface\\Icons\\INV_Misc_GroupLooking",
|
|
DUEL_OUTOFBOUNDS = "Interface\\Icons\\Ability_Rogue_Sprint",
|
|
INSTANCE_BOOT = "Interface\\Icons\\INV_Misc_Rune_01",
|
|
CONFIRM_SUMMON = "Interface\\Icons\\Spell_Shadow_Twilight",
|
|
AREA_SPIRIT_HEAL = "Interface\\Icons\\Spell_Holy_Resurrection",
|
|
REZTIMER = "",
|
|
RESURRECT_NO_SICKNESS = "",
|
|
PARTY_INVITE = "",
|
|
DUEL_REQUESTED = "",
|
|
GAMESTART = "",
|
|
READYCHECK = "",
|
|
}
|
|
|
|
local popups = {
|
|
CAMP = L["Logout"],
|
|
DEATH = L["Release"],
|
|
QUIT = L["Quit"],
|
|
DUEL_OUTOFBOUNDS = L["Forfeit Duel"],
|
|
INSTANCE_BOOT = L["Instance Boot"],
|
|
CONFIRM_SUMMON = L["Summon"],
|
|
AREA_SPIRIT_HEAL = L["AOE Rez"],
|
|
REZTIMER = L["Resurrect Timer"], --GetCorpseRecoveryDelay
|
|
RESURRECT_NO_SICKNESS = L["Resurrect"], --only show if timeleft < delay
|
|
RESURRECT_NO_TIMER = L["Resurrect"],
|
|
PARTY_INVITE = L["Party Invite"],
|
|
DUEL_REQUESTED = L["Duel Request"],
|
|
GAMESTART = L["Game Start"],
|
|
READYCHECK = READY_CHECK,
|
|
}
|
|
|
|
local timeoutoverrides = {
|
|
DEATH = 360,
|
|
AREA_SPIRIT_HEAL = 30,
|
|
INSTANCE_BOOT = 60,
|
|
CONFIRM_SUMMON = 120,
|
|
GAMESTART = 60,
|
|
READYCHECK = 40,
|
|
}
|
|
|
|
Mirror.ExternalTimers = setmetatable({}, {__index = function(t,k)
|
|
local v = new()
|
|
t[k] = v
|
|
return v
|
|
--[[
|
|
startTime
|
|
endTime
|
|
icon
|
|
color
|
|
]]
|
|
end})
|
|
|
|
local mirrorOnUpdate, fakeOnUpdate
|
|
do
|
|
function mirrorOnUpdate(frame)
|
|
local progress = GetMirrorTimerProgress(frame.mode) / 1000
|
|
progress = progress > frame.duration and frame.duration or progress
|
|
frame:SetValue(progress)
|
|
frame.TimeText:SetFormattedText(TimeFmt(progress))
|
|
end
|
|
|
|
function fakeOnUpdate(frame)
|
|
local currentTime = GetTime()
|
|
local endTime = frame.endTime
|
|
|
|
if frame.framenum > 0 then
|
|
local popup = _G["StaticPopup"..frame.framenum] -- hate to do this, but I can"t think of a better way.
|
|
if popup.which ~= frame.which or not popup:IsVisible() then
|
|
return Mirror:UpdateBars()
|
|
end
|
|
end
|
|
|
|
if currentTime > endTime then
|
|
Mirror:UpdateBars()
|
|
else
|
|
local remaining = currentTime - frame.startTime
|
|
frame:SetValue(endTime - remaining)
|
|
frame.TimeText:SetFormattedText(TimeFmt(endTime - currentTime))
|
|
end
|
|
end
|
|
end
|
|
local function OnHide(frame)
|
|
frame:SetScript("OnUpdate", nil)
|
|
end
|
|
local mirrorbars = setmetatable({}, {
|
|
__index = function(t,k)
|
|
local bar = CreateFrame("StatusBar", nil, UIParent)
|
|
t[k] = bar
|
|
bar:SetFrameStrata("MEDIUM")
|
|
bar:Hide()
|
|
bar:SetScript("OnHide", OnHide)
|
|
bar:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16})
|
|
bar:SetBackdropColor(0,0,0)
|
|
bar.Text = bar:CreateFontString(nil, "OVERLAY")
|
|
bar.TimeText = bar:CreateFontString(nil, "OVERLAY")
|
|
bar.Icon = bar:CreateTexture(nil, "DIALOG")
|
|
if k == 1 then
|
|
bar:SetMovable(true)
|
|
bar:RegisterForDrag("LeftButton")
|
|
bar:SetClampedToScreen(true)
|
|
end
|
|
Mirror:ApplySettings()
|
|
return bar
|
|
end
|
|
})
|
|
|
|
function Mirror:OnInitialize()
|
|
self.db = Quartz3.db:RegisterNamespace(MODNAME, defaults)
|
|
db = self.db.profile
|
|
|
|
self:SetEnabledState(Quartz3:GetModuleEnabled(MODNAME))
|
|
Quartz3:RegisterModuleOptions(MODNAME, getOptions, L["Mirror"])
|
|
|
|
end
|
|
|
|
function Mirror:OnEnable()
|
|
self:RegisterEvent("MIRROR_TIMER_PAUSE", "UpdateBars")
|
|
self:RegisterEvent("MIRROR_TIMER_START", "UpdateBars")
|
|
self:RegisterEvent("MIRROR_TIMER_STOP", "UpdateBars")
|
|
self:RegisterEvent("PLAYER_UNGHOST", "UpdateBars")
|
|
self:RegisterEvent("PLAYER_ALIVE", "UpdateBars")
|
|
self:RegisterMessage("Quartz3Mirror_UpdateCustom", "UpdateBars")
|
|
self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL")
|
|
self:RegisterEvent("LFG_PROPOSAL_SHOW")
|
|
self:RegisterEvent("READY_CHECK")
|
|
self:RegisterEvent("READY_CHECK_FINISHED")
|
|
self:RegisterEvent("LFG_PROPOSAL_FAILED", "LFG_PROPOSAL_End")
|
|
self:RegisterEvent("LFG_PROPOSAL_SUCCEEDED", "LFG_PROPOSAL_End")
|
|
self:SecureHook("StaticPopup_Show", "UpdateBars")
|
|
media.RegisterCallback(self, "LibSharedMedia_SetGlobal", function(mtype, override)
|
|
if mtype == "statusbar" then
|
|
for i, v in pairs(mirrorbars) do
|
|
v:SetStatusBarTexture(media:Fetch("statusbar", override))
|
|
end
|
|
end
|
|
end)
|
|
|
|
media.RegisterCallback(self, "LibSharedMedia_Registered", function(mtype, key)
|
|
if mtype == "statusbar" and key == self.config.mirrortexture then
|
|
for i, v in pairs(mirrorbars) do
|
|
v:SetStatusBarTexture(media:Fetch("statusbar", self.config.mirrortexture))
|
|
end
|
|
end
|
|
end)
|
|
|
|
self:ApplySettings()
|
|
end
|
|
|
|
function Mirror:OnDisable()
|
|
mirrorbars[1].Hide = nil
|
|
mirrorbars[1]:EnableMouse(false)
|
|
mirrorbars[1]:SetScript("OnDragStart", nil)
|
|
mirrorbars[1]:SetScript("OnDragStop", nil)
|
|
|
|
for _, v in pairs(mirrorbars) do
|
|
v:Hide()
|
|
end
|
|
|
|
for i = 1, 3 do
|
|
_G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_PAUSE")
|
|
_G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_STOP")
|
|
end
|
|
UIParent:RegisterEvent("MIRROR_TIMER_START")
|
|
|
|
media.UnregisterCallback(self, "LibSharedMedia_SetGlobal")
|
|
media.UnregisterCallback(self, "LibSharedMedia_Registered")
|
|
end
|
|
|
|
do
|
|
local tblCache = setmetatable({}, {__mode="k"})
|
|
function new()
|
|
local entry = next(tblCache)
|
|
if entry then tblCache[entry] = nil else entry = {} end
|
|
return entry
|
|
end
|
|
function del(tbl)
|
|
wipe(tbl)
|
|
tblCache[tbl] = true
|
|
end
|
|
|
|
local function sort(a,b)
|
|
return a.name < b.name
|
|
end
|
|
|
|
local tmp = {}
|
|
local reztimermax = 0
|
|
local function update()
|
|
Mirror.updateMirrorBar = nil
|
|
local currentTime = GetTime()
|
|
for k in pairs(tmp) do
|
|
tmp[k] = del(tmp[k])
|
|
end
|
|
|
|
if db.showpvp then
|
|
if gametimebase then
|
|
local endTime = gametimebase + gametimetostart
|
|
if endTime > currentTime then
|
|
local which = "GAMESTART"
|
|
local t = new()
|
|
tmp[#tmp+1] = t
|
|
t.name = popups[which]
|
|
t.texture = icons[which]
|
|
t.mode = which
|
|
t.startTime = endTime - timeoutoverrides[which]
|
|
t.endTime = endTime
|
|
t.isfake = true
|
|
t.framenum = 0
|
|
else
|
|
gametimebase = nil
|
|
gametimetostart = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
if db.showreadycheck then
|
|
if lfgshowbase or readycheckshowbase then
|
|
local which = "READYCHECK"
|
|
local endTime
|
|
if readycheckshowbase then
|
|
endTime = readycheckshowbase + readycheckshowduration
|
|
else
|
|
endTime = lfgshowbase + timeoutoverrides[which]
|
|
end
|
|
if endTime > currentTime then
|
|
local t = new()
|
|
tmp[#tmp+1] = t
|
|
t.name = popups[which]
|
|
t.texture = icons[which]
|
|
t.mode = which
|
|
t.startTime = lfgshowbase or readycheckshowbase
|
|
t.endTime = endTime
|
|
t.isfake = true
|
|
t.framenum = 0
|
|
else
|
|
lfgshowbase = nil
|
|
readycheckshowbase = nil
|
|
readycheckshowduration = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
if db.showmirror then
|
|
for i = 1, MIRRORTIMER_NUMTIMERS do
|
|
local timer, value, maxvalue, scale, paused, label = GetMirrorTimerInfo(i)
|
|
if timer ~= "UNKNOWN" then
|
|
local t = new()
|
|
tmp[#tmp+1] = t
|
|
t.name = label
|
|
t.texture = icons[timer]
|
|
t.mode = timer
|
|
t.duration = maxvalue / 1000
|
|
t.isfake = false
|
|
end
|
|
end
|
|
end
|
|
|
|
if db.showstatic then
|
|
local recoverydelay = GetCorpseRecoveryDelay()
|
|
if recoverydelay > 0 and UnitHealth("player") < 2 then
|
|
if reztimermax == 0 then
|
|
reztimermax = recoverydelay
|
|
end
|
|
local which = "REZTIMER"
|
|
local t = new()
|
|
tmp[#tmp+1] = t
|
|
t.name = popups[which]
|
|
t.texture = icons[which]
|
|
t.mode = which
|
|
t.startTime = currentTime - (reztimermax - recoverydelay)
|
|
t.endTime = currentTime + recoverydelay
|
|
t.isfake = true
|
|
t.framenum = 0
|
|
else
|
|
reztimermax = 0
|
|
end
|
|
|
|
for i = 1, 4 do
|
|
local popup = _G["StaticPopup"..i]
|
|
local which = popup.which
|
|
local timeleft = popup.timeleft
|
|
local name = popups[which]
|
|
|
|
--special case for a timered rez
|
|
if which == "RESURRECT_NO_SICKNESS" then
|
|
if timeleft > 60 then
|
|
name = nil
|
|
end
|
|
end
|
|
|
|
if popup:IsVisible() and name and timeleft and timeleft > 0 then
|
|
local t = new()
|
|
tmp[#tmp+1] = t
|
|
t.name = name
|
|
t.texture = icons[which]
|
|
t.mode = which
|
|
local timeout = StaticPopupDialogs[which].timeout
|
|
if not timeout or timeout == 0 then
|
|
timeout = timeoutoverrides[which]
|
|
end
|
|
t.startTime = currentTime - (timeout - timeleft)
|
|
t.endTime = currentTime + timeleft
|
|
t.isfake = true
|
|
t.framenum = i
|
|
end
|
|
end
|
|
end
|
|
|
|
local external = Mirror.ExternalTimers
|
|
for name, v in pairs(external) do
|
|
local endTime = v.endTime
|
|
if not v.startTime or not endTime then
|
|
error("bad custom table")
|
|
end
|
|
if endTime > currentTime then
|
|
local t = new()
|
|
tmp[#tmp+1] = t
|
|
t.name = name
|
|
t.texture = v.icon or icons[name]
|
|
t.startTime = v.startTime
|
|
t.endTime = v.endTime
|
|
t.isfake = true
|
|
t.framenum = 0
|
|
if v.color then
|
|
t.color = v.color
|
|
end
|
|
else
|
|
external[name] = del(v)
|
|
end
|
|
end
|
|
|
|
table_sort(tmp, sort)
|
|
local maxindex = 0
|
|
for k=1,#tmp do
|
|
local v = tmp[k]
|
|
maxindex = k
|
|
local bar = mirrorbars[k]
|
|
bar.Text:SetText(v.name)
|
|
bar.Icon:SetTexture(v.texture)
|
|
bar.mode = v.mode
|
|
if v.isfake then
|
|
local startTime, endTime = v.startTime, v.endTime
|
|
bar:SetMinMaxValues(startTime, endTime)
|
|
bar.startTime = startTime
|
|
bar.endTime = endTime
|
|
bar.framenum = v.framenum
|
|
bar.which = v.mode
|
|
bar:Show()
|
|
bar:SetScript("OnUpdate", fakeOnUpdate)
|
|
if v.mode then
|
|
bar:SetStatusBarColor(unpack(db[v.mode]))
|
|
elseif v.color then
|
|
bar:SetStatusBarColor(unpack(v.color))
|
|
else
|
|
bar:SetStatusBarColor(1,1,1) --!! add option
|
|
end
|
|
else
|
|
local duration = v.duration
|
|
bar:SetMinMaxValues(0, duration)
|
|
bar.duration = duration
|
|
bar:Show()
|
|
bar:SetScript("OnUpdate", mirrorOnUpdate)
|
|
bar:SetStatusBarColor(unpack(db[v.mode]))
|
|
end
|
|
end
|
|
for i = maxindex+1, #mirrorbars do
|
|
mirrorbars[i]:Hide()
|
|
end
|
|
end
|
|
|
|
function Mirror:UpdateBars()
|
|
if not self.updateMirrorBar then
|
|
self.updateMirrorBar = self:ScheduleTimer(update, 0) -- API funcs dont return helpful crap until after the event.
|
|
end
|
|
end
|
|
end
|
|
function Mirror:CHAT_MSG_BG_SYSTEM_NEUTRAL(event, msg)
|
|
if msg:match(L["1 minute"]) or msg:match(L["One minute until"]) then
|
|
gametimebase = GetTime()
|
|
gametimetostart = 60
|
|
elseif msg:match(L["30 seconds"]) or msg:match(L["Thirty seconds until"]) then
|
|
gametimebase = GetTime()
|
|
gametimetostart = 30
|
|
elseif msg:match(L["15 seconds"]) or msg:match(L["Fifteen seconds until"]) then
|
|
gametimebase = GetTime()
|
|
gametimetostart = 15
|
|
end
|
|
self:UpdateBars()
|
|
end
|
|
|
|
function Mirror:LFG_PROPOSAL_SHOW(event, msg)
|
|
lfgshowbase = GetTime()
|
|
self:UpdateBars()
|
|
end
|
|
function Mirror:LFG_PROPOSAL_End(event, msg)
|
|
lfgshowbase = nil
|
|
self:UpdateBars()
|
|
end
|
|
function Mirror:READY_CHECK(event, msg, duration)
|
|
readycheckshowbase = GetTime()
|
|
readycheckshowduration = duration
|
|
self:UpdateBars()
|
|
end
|
|
function Mirror:READY_CHECK_FINISHED(event, msg)
|
|
readycheckshowbase = nil
|
|
self:UpdateBars()
|
|
end
|
|
do
|
|
local function apply(i, bar, db, direction)
|
|
local position, showicons, iconside, gap, spacing, offset
|
|
local qpdb = Player.db.profile
|
|
|
|
position = db.mirrorposition
|
|
showicons = db.mirroricons
|
|
iconside = db.mirroriconside
|
|
gap = db.mirrorgap
|
|
spacing = db.mirrorspacing
|
|
offset = db.mirroroffset
|
|
|
|
bar:ClearAllPoints()
|
|
bar:SetStatusBarTexture(media:Fetch("statusbar", db.mirrortexture))
|
|
bar:GetStatusBarTexture():SetHorizTile(false)
|
|
bar:GetStatusBarTexture():SetVertTile(false)
|
|
bar:SetWidth(db.mirrorwidth)
|
|
bar:SetHeight(db.mirrorheight)
|
|
bar:SetScale(qpdb.scale)
|
|
bar:SetAlpha(db.mirroralpha)
|
|
|
|
if db.mirroranchor == "free" then
|
|
if i == 1 then
|
|
bar:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", db.mirrorx, db.mirrory)
|
|
if db.mirrorgrowdirection == "up" then
|
|
direction = 1
|
|
else --L["Down"]
|
|
direction = -1
|
|
end
|
|
else
|
|
if direction == 1 then
|
|
bar:SetPoint("BOTTOMRIGHT", mirrorbars[i-1], "TOPRIGHT", 0, spacing)
|
|
else -- -1
|
|
bar:SetPoint("TOPRIGHT", mirrorbars[i-1], "BOTTOMRIGHT", 0, -1 * spacing)
|
|
end
|
|
end
|
|
else
|
|
if i == 1 then
|
|
local anchorframe
|
|
local anchor = db.mirroranchor
|
|
if anchor == "focus" and Focus.Bar then
|
|
anchorframe = Focus.Bar
|
|
elseif anchor == "target" and Target.Bar then
|
|
anchorframe = Target.Bar
|
|
else -- L["Player"]
|
|
anchorframe = Player.Bar
|
|
end
|
|
|
|
if position == "top" then
|
|
direction = 1
|
|
bar:SetPoint("BOTTOM", anchorframe, "TOP", 0, gap)
|
|
elseif position == "bottom" then
|
|
direction = -1
|
|
bar:SetPoint("TOP", anchorframe, "BOTTOM", 0, -1 * gap)
|
|
elseif position == "topright" then
|
|
direction = 1
|
|
bar:SetPoint("BOTTOMRIGHT", anchorframe, "TOPRIGHT", -1 * offset, gap)
|
|
elseif position == "bottomright" then
|
|
direction = -1
|
|
bar:SetPoint("TOPRIGHT", anchorframe, "BOTTOMRIGHT", -1 * offset, -1 * gap)
|
|
elseif position == "topleft" then
|
|
direction = 1
|
|
bar:SetPoint("BOTTOMLEFT", anchorframe, "TOPLEFT", offset, gap)
|
|
elseif position == "bottomleft" then
|
|
direction = -1
|
|
bar:SetPoint("TOPLEFT", anchorframe, "BOTTOMLEFT", offset, -1 * gap)
|
|
elseif position == "leftup" then
|
|
if iconside == "right" and showicons then
|
|
offset = offset + db.mirrorheight
|
|
end
|
|
if qpdb.iconposition == "left" and not qpdb.hideicon then
|
|
offset = offset + qpdb.h
|
|
end
|
|
direction = 1
|
|
bar:SetPoint("BOTTOMRIGHT", anchorframe, "BOTTOMLEFT", -1 * offset, gap)
|
|
elseif position == "leftdown" then
|
|
if iconside == "right" and showicons then
|
|
offset = offset + db.mirrorheight
|
|
end
|
|
if qpdb.iconposition == "left" and not qpdb.hideicon then
|
|
offset = offset + qpdb.h
|
|
end
|
|
direction = -1
|
|
bar:SetPoint("TOPRIGHT", anchorframe, "TOPLEFT", -3 * offset, -1 * gap)
|
|
elseif position == "rightup" then
|
|
if iconside == "left" and showicons then
|
|
offset = offset + db.mirrorheight
|
|
end
|
|
if qpdb.iconposition == "right" and not qpdb.hideicon then
|
|
offset = offset + qpdb.h
|
|
end
|
|
direction = 1
|
|
bar:SetPoint("BOTTOMLEFT", anchorframe, "BOTTOMRIGHT", offset, gap)
|
|
elseif position == "rightdown" then
|
|
if iconside == "left" and showicons then
|
|
offset = offset + db.mirrorheight
|
|
end
|
|
if qpdb.iconposition == "right" and not qpdb.hideicon then
|
|
offset = offset + qpdb.h
|
|
end
|
|
direction = -1
|
|
bar:SetPoint("TOPLEFT", anchorframe, "TOPRIGHT", offset, -1 * gap)
|
|
end
|
|
else
|
|
if direction == 1 then
|
|
bar:SetPoint("BOTTOMRIGHT", mirrorbars[i-1], "TOPRIGHT", 0, spacing)
|
|
else -- -1
|
|
bar:SetPoint("TOPRIGHT", mirrorbars[i-1], "BOTTOMRIGHT", 0, -1 * spacing)
|
|
end
|
|
end
|
|
end
|
|
|
|
local timetext = bar.TimeText
|
|
if db.mirrortimetext then
|
|
timetext:Show()
|
|
timetext:ClearAllPoints()
|
|
timetext:SetWidth(db.mirrorwidth)
|
|
timetext:SetPoint("RIGHT", bar, "RIGHT", -2, 0)
|
|
timetext:SetJustifyH("RIGHT")
|
|
else
|
|
timetext:Hide()
|
|
end
|
|
timetext:SetFont(media:Fetch("font", db.mirrorfont), db.mirrorfontsize)
|
|
timetext:SetShadowColor( 0, 0, 0, 1)
|
|
timetext:SetShadowOffset( 0.8, -0.8 )
|
|
timetext:SetTextColor(unpack(db.mirrortextcolor))
|
|
timetext:SetNonSpaceWrap(false)
|
|
timetext:SetHeight(db.mirrorheight)
|
|
|
|
local temptext = timetext:GetText()
|
|
timetext:SetText("10.0")
|
|
local normaltimewidth = timetext:GetStringWidth()
|
|
timetext:SetText(temptext)
|
|
|
|
local text = bar.Text
|
|
if db.mirrornametext then
|
|
text:Show()
|
|
text:ClearAllPoints()
|
|
text:SetPoint("LEFT", bar, "LEFT", 2, 0)
|
|
text:SetJustifyH("LEFT")
|
|
if db.mirrortimetext then
|
|
text:SetWidth(db.mirrorwidth - normaltimewidth)
|
|
else
|
|
text:SetWidth(db.mirrorwidth)
|
|
end
|
|
else
|
|
text:Hide()
|
|
end
|
|
text:SetFont(media:Fetch("font", db.mirrorfont), db.mirrorfontsize)
|
|
text:SetShadowColor( 0, 0, 0, 1)
|
|
text:SetShadowOffset( 0.8, -0.8 )
|
|
text:SetTextColor(unpack(db.mirrortextcolor))
|
|
text:SetNonSpaceWrap(false)
|
|
text:SetHeight(db.mirrorheight)
|
|
|
|
local icon = bar.Icon
|
|
if showicons then
|
|
icon:Show()
|
|
icon:SetWidth(db.mirrorheight-1)
|
|
icon:SetHeight(db.mirrorheight-1)
|
|
icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)
|
|
icon:ClearAllPoints()
|
|
if iconside == "left" then
|
|
icon:SetPoint("RIGHT", bar, "LEFT", -1, 0)
|
|
else
|
|
icon:SetPoint("LEFT", bar, "RIGHT", 1, 0)
|
|
end
|
|
else
|
|
icon:Hide()
|
|
end
|
|
|
|
return direction
|
|
end
|
|
|
|
function Mirror:ApplySettings()
|
|
db = self.db.profile
|
|
if self:IsEnabled() then
|
|
local direction
|
|
if db.mirroranchor ~= "free" then
|
|
mirrorbars[1].Hide = nil
|
|
mirrorbars[1]:EnableMouse(false)
|
|
mirrorbars[1]:SetScript("OnDragStart", nil)
|
|
mirrorbars[1]:SetScript("OnDragStop", nil)
|
|
end
|
|
for i, v in pairs(mirrorbars) do
|
|
direction = apply(i, v, db, direction)
|
|
end
|
|
if db.hideblizzmirrors then
|
|
for i = 1, 3 do
|
|
_G["MirrorTimer"..i]:UnregisterAllEvents()
|
|
_G["MirrorTimer"..i]:Hide()
|
|
end
|
|
UIParent:UnregisterEvent("MIRROR_TIMER_START")
|
|
else
|
|
for i = 1, 3 do
|
|
_G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_PAUSE")
|
|
_G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_STOP")
|
|
end
|
|
UIParent:RegisterEvent("MIRROR_TIMER_START")
|
|
end
|
|
db.RESURRECT_NO_TIMER = db.RESURRECT_NO_SICKNESS
|
|
self:UpdateBars()
|
|
end
|
|
end
|
|
end
|
|
|
|
do
|
|
local function getmirrorhidden()
|
|
return not db.showmirror
|
|
end
|
|
|
|
local function getstatichidden()
|
|
return not db.showstatic
|
|
end
|
|
|
|
local function getpvphidden()
|
|
return not db.showpvp
|
|
end
|
|
|
|
local function getreadycheckhidden()
|
|
return not db.showreadycheck
|
|
end
|
|
|
|
local function getfreeoptionshidden()
|
|
return db.mirroranchor ~= "free"
|
|
end
|
|
|
|
local function getnotfreeoptionshidden()
|
|
return db.mirroranchor == "free"
|
|
end
|
|
|
|
local function dragstart()
|
|
mirrorbars[1]:StartMoving()
|
|
end
|
|
|
|
local function dragstop()
|
|
db.mirrorx = mirrorbars[1]:GetLeft()
|
|
db.mirrory = mirrorbars[1]:GetBottom()
|
|
mirrorbars[1]:StopMovingOrSizing()
|
|
end
|
|
|
|
local function nothing()
|
|
mirrorbars[1]:SetAlpha(db.mirroralpha)
|
|
end
|
|
|
|
local positions = {
|
|
["bottom"] = L["Bottom"],
|
|
["top"] = L["Top"],
|
|
["topleft"] = L["Top Left"],
|
|
["topright"] = L["Top Right"],
|
|
["bottomleft"] = L["Bottom Left"],
|
|
["bottomright"] = L["Bottom Right"],
|
|
["leftup"] = L["Left (grow up)"],
|
|
["leftdown"] = L["Left (grow down)"],
|
|
["rightup"] = L["Right (grow up)"],
|
|
["rightdown"] = L["Right (grow down)"],
|
|
}
|
|
|
|
local function setOpt(info, value)
|
|
db[info[#info]] = value
|
|
Mirror:ApplySettings()
|
|
end
|
|
|
|
local function getOpt(info)
|
|
return db[info[#info]]
|
|
end
|
|
|
|
local function getColor(info)
|
|
return unpack(getOpt(info))
|
|
end
|
|
|
|
local function setColor(info, r, g, b, a)
|
|
setOpt(info, {r, g, b, a})
|
|
end
|
|
|
|
local options
|
|
function getOptions()
|
|
if not options then
|
|
options = {
|
|
type = "group",
|
|
name = L["Mirror"],
|
|
order = 600,
|
|
set = setOpt,
|
|
get = getOpt,
|
|
childGroups = "tab",
|
|
args = {
|
|
toggle = {
|
|
type = "toggle",
|
|
name = L["Enable"],
|
|
desc = L["Enable"],
|
|
get = function()
|
|
return Quartz3:GetModuleEnabled(MODNAME)
|
|
end,
|
|
set = function(info, v)
|
|
Quartz3:SetModuleEnabled(MODNAME, v)
|
|
end,
|
|
order = 96,
|
|
width = "full",
|
|
},
|
|
settings = {
|
|
type = "group",
|
|
name = L["Settings"],
|
|
args = {
|
|
mirroranchor = {
|
|
type = "select",
|
|
name = L["Anchor Frame"],
|
|
desc = L["Select where to anchor the mirror bars"],
|
|
values = {["player"] = L["Player"], ["free"] = L["Free"], ["target"] = L["Target"], ["focus"] = L["Focus"]},
|
|
},
|
|
-- free
|
|
mirrorlock = {
|
|
type = "toggle",
|
|
name = L["Lock"],
|
|
desc = L["Toggle mirror bar lock"],
|
|
get = function()
|
|
return locked
|
|
end,
|
|
set = function(info, v)
|
|
if v then
|
|
mirrorbars[1].Hide = nil
|
|
mirrorbars[1]:EnableMouse(false)
|
|
mirrorbars[1]:SetScript("OnDragStart", nil)
|
|
mirrorbars[1]:SetScript("OnDragStop", nil)
|
|
Mirror:UpdateBars()
|
|
else
|
|
mirrorbars[1]:Show()
|
|
mirrorbars[1]:EnableMouse(true)
|
|
mirrorbars[1]:SetScript("OnDragStart", dragstart)
|
|
mirrorbars[1]:SetScript("OnDragStop", dragstop)
|
|
mirrorbars[1]:SetAlpha(1)
|
|
mirrorbars[1].Hide = nothing
|
|
end
|
|
locked = v
|
|
end,
|
|
hidden = getfreeoptionshidden,
|
|
order = 98,
|
|
},
|
|
mirrorgrowdirection = {
|
|
type = "select",
|
|
name = L["Grow Direction"],
|
|
desc = L["Set the grow direction of the mirror bars"],
|
|
values = {["up"] = L["Up"], ["down"] = L["Down"]},
|
|
hidden = getfreeoptionshidden,
|
|
order = 102,
|
|
},
|
|
mirrorx = {
|
|
type = "range",
|
|
name = L["X"],
|
|
desc = L["Set an exact X value for this bar's position."],
|
|
min = 0, max = 2560, bigStep = 1,
|
|
order = 103,
|
|
hidden = getfreeoptionshidden,
|
|
},
|
|
mirrory = {
|
|
type = "range",
|
|
name = L["Y"],
|
|
desc = L["Set an exact Y value for this bar's position."],
|
|
min = 0, max = 1600, bigStep = 1,
|
|
order = 103,
|
|
hidden = getfreeoptionshidden,
|
|
},
|
|
-- anchored to a cast bar
|
|
mirrorposition = {
|
|
type = "select",
|
|
name = L["Position"],
|
|
desc = L["Position the mirror bars"],
|
|
values = positions,
|
|
hidden = getnotfreeoptionshidden,
|
|
order = 101,
|
|
},
|
|
mirrorgap = {
|
|
type = "range",
|
|
name = L["Gap"],
|
|
desc = L["Tweak the vertical position of the mirror bars"],
|
|
min = -35, max = 35, step = 1,
|
|
hidden = getnotfreeoptionshidden,
|
|
order = 102,
|
|
},
|
|
mirroroffset = {
|
|
type = "range",
|
|
name = L["Offset"],
|
|
desc = L["Tweak the horizontal position of the mirror bars"],
|
|
min = -35, max = 35, step = 1,
|
|
hidden = getnotfreeoptionshidden,
|
|
order = 103,
|
|
},
|
|
mirrorspacing = {
|
|
type = "range",
|
|
name = L["Spacing"],
|
|
desc = L["Tweak the space between mirror bars"],
|
|
min = -35, max = 35, step = 1,
|
|
order = 104,
|
|
},
|
|
nl4 = {
|
|
type = "description",
|
|
name = "",
|
|
order = 109,
|
|
},
|
|
mirroricons = {
|
|
type = "toggle",
|
|
name = L["Show Icons"],
|
|
desc = L["Show icons on mirror bars"],
|
|
order = 110,
|
|
},
|
|
mirroriconside = {
|
|
type = "select",
|
|
name = L["Icon Position"],
|
|
desc = L["Set the side of the mirror bar that the icon appears on"],
|
|
values = {["left"] = L["Left"], ["right"] = L["Right"]},
|
|
order = 111,
|
|
},
|
|
mirrortexture = {
|
|
type = "select",
|
|
dialogControl = "LSM30_Statusbar",
|
|
name = L["Texture"],
|
|
desc = L["Set the mirror bar Texture"],
|
|
values = lsmlist.statusbar,
|
|
order = 112,
|
|
},
|
|
nl5 = {
|
|
type = "description",
|
|
name = "",
|
|
order = 113,
|
|
},
|
|
mirrorwidth = {
|
|
type = "range",
|
|
name = L["Mirror Bar Width"],
|
|
desc = L["Set the width of the mirror bars"],
|
|
min = 50, max = 300, step = 1,
|
|
order = 114,
|
|
},
|
|
mirrorheight = {
|
|
type = "range",
|
|
name = L["Mirror Bar Height"],
|
|
desc = L["Set the height of the mirror bars"],
|
|
min = 4, max = 25, step = 1,
|
|
order = 115,
|
|
},
|
|
mirroralpha = {
|
|
type = "range",
|
|
name = L["Alpha"],
|
|
desc = L["Set the alpha of the mirror bars"],
|
|
min = 0.05, max = 1, bigStep = 0.05,
|
|
isPercent = true,
|
|
order = 116,
|
|
},
|
|
nl6 = {
|
|
type = "description",
|
|
name = "",
|
|
order = 119,
|
|
},
|
|
mirrornametext = {
|
|
type = "toggle",
|
|
name = L["Mirror Name Text"],
|
|
desc = L["Display the names of Mirror Bar Types on their bars"],
|
|
order = 120,
|
|
},
|
|
mirrortimetext = {
|
|
type = "toggle",
|
|
name = L["Mirror Time Text"],
|
|
desc = L["Display the time remaining on mirror bars"],
|
|
order = 121,
|
|
},
|
|
mirrorfont = {
|
|
type = "select",
|
|
dialogControl = "LSM30_Font",
|
|
name = L["Font"],
|
|
desc = L["Set the font used in the mirror bars"],
|
|
values = lsmlist.font,
|
|
order = 122,
|
|
},
|
|
mirrorfontsize = {
|
|
type = "range",
|
|
name = L["Font Size"],
|
|
desc = L["Set the font size for the mirror bars"],
|
|
min = 3, max = 15, step = 1,
|
|
order = 123,
|
|
},
|
|
mirrortextcolor = {
|
|
type = "color",
|
|
name = L["Text Color"],
|
|
desc = L["Set the color of the text for the mirror bars"],
|
|
get = getColor,
|
|
set = setColor,
|
|
order = 124,
|
|
},
|
|
hideblizzmirrors = {
|
|
type = "toggle",
|
|
name = L["Hide Blizz Mirror Bars"],
|
|
desc = L["Hide Blizzard's mirror bars"],
|
|
order = 130,
|
|
},
|
|
}
|
|
},
|
|
bars = {
|
|
type = "group",
|
|
name = L["Bars and Colors"],
|
|
order = -1,
|
|
args = {
|
|
-- mirror
|
|
showmirror = {
|
|
type = "toggle",
|
|
name = L["Show Mirror"],
|
|
desc = L["Show mirror bars such as breath and feign death"],
|
|
order = 97,
|
|
width = "full",
|
|
},
|
|
BREATH = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Breath"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Breath"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getmirrorhidden,
|
|
order = 101,
|
|
},
|
|
EXHAUSTION = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Exhaustion"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Exhaustion"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getmirrorhidden,
|
|
order = 101,
|
|
},
|
|
FEIGNDEATH = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Feign Death"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Feign Death"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getmirrorhidden,
|
|
order = 101,
|
|
},
|
|
-- static
|
|
showstatic = {
|
|
type = "toggle",
|
|
name = L["Show Static"],
|
|
desc = L["Show bars for static popup items such as rez and summon timers"],
|
|
order = 200,
|
|
width = "full",
|
|
},
|
|
CAMP = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Logout"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Logout"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
DEATH = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Release"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Release"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
QUIT = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Quit"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Quit"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
DUEL_OUTOFBOUNDS = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Forfeit Duel"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Forfeit Duel"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
INSTANCE_BOOT = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Instance Boot"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Instance Boot"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
CONFIRM_SUMMON = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Summon"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Summon"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
AREA_SPIRIT_HEAL = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["AOE Rez"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["AOE Rez"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
REZTIMER = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Resurrect Timer"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Resurrect Timer"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
RESURRECT_NO_SICKNESS = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Resurrect"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Resurrect"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
PARTY_INVITE = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Party Invite"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Party Invite"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
DUEL_REQUESTED = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Duel Request"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Duel Request"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getstatichidden,
|
|
order = 201,
|
|
},
|
|
--pvp
|
|
showpvp = {
|
|
type = "toggle",
|
|
name = L["Show PvP"],
|
|
desc = L["Show bar for start of arena and battleground games"],
|
|
order = 300,
|
|
width = "full",
|
|
},
|
|
GAMESTART = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(L["Game Start"]),
|
|
desc = L["Set the color of the bars for %s"]:format(L["Game Start"]),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getpvphidden,
|
|
order = 301,
|
|
},
|
|
--ready check
|
|
showreadycheck = {
|
|
type = "toggle",
|
|
name = L["Show Ready Check"],
|
|
desc = L["Show bar for Ready Checks"],
|
|
order = 500,
|
|
width = "full",
|
|
},
|
|
READYCHECK = {
|
|
type = "color",
|
|
name = L["%s Color"]:format(READY_CHECK),
|
|
desc = L["Set the color of the bars for %s"]:format(READY_CHECK),
|
|
get = getColor,
|
|
set = setColor,
|
|
disabled = getreadycheckhidden,
|
|
order = 501,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
end
|
|
return options
|
|
end
|
|
end
|