Add files via upload
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Auto Dismount"],
|
||||
description = T["Automatically dismounts whenever a spell is casted."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local dismount = CreateFrame("Frame")
|
||||
ShaguTweaks.dismount = dismount
|
||||
|
||||
-- mount tooltip texts
|
||||
dismount.strings = {
|
||||
-- deDE
|
||||
"^Erhöht Tempo um (.+)%%",
|
||||
-- enUS
|
||||
"^Increases speed by (.+)%%",
|
||||
-- esES
|
||||
"^Aumenta la velocidad en un (.+)%%",
|
||||
-- frFR
|
||||
"^Augmente la vitesse de (.+)%%",
|
||||
-- ruRU
|
||||
"^Скорость увеличена на (.+)%%",
|
||||
-- koKR
|
||||
"^이동 속도 (.+)%%만큼 증가",
|
||||
-- zhCN
|
||||
"^速度提高(.+)%%",
|
||||
-- turtle-wow
|
||||
"speed based on", "Slow and steady...", "Riding",
|
||||
"Lento y constante...", "Aumenta la velocidad según tu habilidad de Montar.",
|
||||
"根据您的骑行技能提高速度。", "根据骑术技能提高速度。", "又慢又稳......",
|
||||
}
|
||||
|
||||
-- shapeshift buff icons
|
||||
dismount.shapeshifts = {
|
||||
"ability_racial_bearform", "ability_druid_catform", "ability_druid_travelform",
|
||||
"spell_nature_forceofnature", "ability_druid_aquaticform", "spell_nature_spiritwolf"
|
||||
}
|
||||
|
||||
-- errors that indicate mount/shapeshift
|
||||
dismount.errors = { SPELL_FAILED_NOT_MOUNTED, ERR_ATTACK_MOUNTED, ERR_TAXIPLAYERALREADYMOUNTED,
|
||||
SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED, SPELL_NOT_SHAPESHIFTED,
|
||||
SPELL_NOT_SHAPESHIFTED_NOSPACE, ERR_CANT_INTERACT_SHAPESHIFTED, ERR_NOT_WHILE_SHAPESHIFTED,
|
||||
ERR_NO_ITEMS_WHILE_SHAPESHIFTED, ERR_TAXIPLAYERSHAPESHIFTED,ERR_MOUNT_SHAPESHIFTED }
|
||||
|
||||
dismount.scanner = ShaguTweaks.libtipscan:GetScanner("dismount")
|
||||
|
||||
dismount:RegisterEvent("UI_ERROR_MESSAGE")
|
||||
dismount:SetScript("OnEvent", function()
|
||||
-- stand up
|
||||
if arg1 == SPELL_FAILED_NOT_STANDING then
|
||||
SitOrStand()
|
||||
return
|
||||
end
|
||||
|
||||
-- scan through buffs and cancel shapeshift/mount
|
||||
for id, errorstring in pairs(dismount.errors) do
|
||||
if arg1 == errorstring then
|
||||
for i=0, 31 do
|
||||
-- detect mounts based on tooltip text
|
||||
dismount.scanner:SetPlayerBuff(i)
|
||||
for _, str in pairs(dismount.strings) do
|
||||
if dismount.scanner:Find(str) then
|
||||
CancelPlayerBuff(i)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- detect shapeshift based on texture
|
||||
local buff = GetPlayerBuffTexture(i)
|
||||
if buff then
|
||||
for id, bufftype in pairs(dismount.shapeshifts) do
|
||||
if string.find(string.lower(buff), bufftype) then
|
||||
CancelPlayerBuff(i)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local strsplit = ShaguTweaks.strsplit
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Auto Stance"],
|
||||
description = T["Automatically switch to the required warrior or druid stance on spell cast."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local stancedance = CreateFrame("Frame", "ShaguTweaksStancedance")
|
||||
stancedance.scanString = string.gsub(SPELL_FAILED_ONLY_SHAPESHIFT, "%%s", "(.+)")
|
||||
stancedance:RegisterEvent("UI_ERROR_MESSAGE")
|
||||
stancedance:SetScript("OnEvent", function()
|
||||
for stances in string.gfind(arg1, stancedance.scanString) do
|
||||
for _, stance in pairs({ strsplit(",", stances)}) do
|
||||
CastSpellByName(string.gsub(stance,"^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Blue Shaman Class Colors"],
|
||||
description = T["Changes the class color code of shamans to blue, as known from TBC+."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Social & Chat"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
-- update table to get unknown colors and blue shamans for vanilla
|
||||
RAID_CLASS_COLORS = {
|
||||
["WARRIOR"] = { r = 0.78, g = 0.61, b = 0.43, colorStr = "ffc79c6e" },
|
||||
["MAGE"] = { r = 0.41, g = 0.8, b = 0.94, colorStr = "ff69ccf0" },
|
||||
["ROGUE"] = { r = 1, g = 0.96, b = 0.41, colorStr = "fffff569" },
|
||||
["DRUID"] = { r = 1, g = 0.49, b = 0.04, colorStr = "ffff7d0a" },
|
||||
["HUNTER"] = { r = 0.67, g = 0.83, b = 0.45, colorStr = "ffabd473" },
|
||||
["SHAMAN"] = { r = 0.14, g = 0.35, b = 1.0, colorStr = "ff2459ff" },
|
||||
["PRIEST"] = { r = 1, g = 1, b = 1, colorStr = "ffffffff" },
|
||||
["WARLOCK"] = { r = 0.58, g = 0.51, b = 0.79, colorStr = "ff9482c9" },
|
||||
["PALADIN"] = { r = 0.96, g = 0.55, b = 0.73, colorStr = "fff58cba" },
|
||||
}
|
||||
|
||||
RAID_CLASS_COLORS = setmetatable(RAID_CLASS_COLORS, { __index = function(tab,key)
|
||||
return { r = 0.6, g = 0.6, b = 0.6, colorStr = "ff999999" }
|
||||
end})
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local gfind = string.gmatch or string.gfind
|
||||
local rgbhex = ShaguTweaks.rgbhex
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Chat Levels"],
|
||||
description = T["Shows player levels in chat."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Social & Chat"],
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local events = CreateFrame("Frame", nil, UIParent)
|
||||
events:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
events:SetScript("OnEvent", function()
|
||||
if this.loaded then return end
|
||||
this.loaded = true
|
||||
|
||||
local playerdb = ShaguTweaks_cache and ShaguTweaks_cache["players"]
|
||||
|
||||
for i=1, NUM_CHAT_WINDOWS do
|
||||
local frame = _G["ChatFrame"..i]
|
||||
if frame and not frame.HookAddMessageLevel and not Prat then
|
||||
frame.HookAddMessageLevel = frame.AddMessage
|
||||
frame.AddMessage = function(f, text, a1, a2, a3, a4, a5)
|
||||
if text and playerdb then
|
||||
for name in gfind(text, "|Hplayer:(.-)|h") do
|
||||
local data = playerdb[name]
|
||||
if data and data.level then
|
||||
local level = data.level
|
||||
local color = rgbhex(GetDifficultyColor(level))
|
||||
text = string.gsub(text,
|
||||
"|Hplayer:" .. name .. "|h%[" .. name .. "%]|h|r",
|
||||
"|Hplayer:" .. name .. "|h[" .. name .. "]|h|r " .. color .. level .. "|r")
|
||||
end
|
||||
end
|
||||
end
|
||||
frame.HookAddMessageLevel(f, text, a1, a2, a3, a4, a5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,517 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local L = ShaguTweaks.L
|
||||
local gfind = string.gmatch or string.gfind
|
||||
local GetUnitData = ShaguTweaks.GetUnitData
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
local hooksecurefunc = ShaguTweaks.hooksecurefunc
|
||||
local cmatch = ShaguTweaks.cmatch
|
||||
local rgbhex = ShaguTweaks.rgbhex
|
||||
local strsplit = ShaguTweaks.strsplit
|
||||
|
||||
local scrollspeed = 1
|
||||
local friendinfo = gsub(gsub(FRIENDS_LEVEL_TEMPLATE,"%%s","%%s %%s"),"%%d","%%s")
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Chat Tweaks"],
|
||||
description = T["Improves chat with mouse wheel scrolling, sticky channels, arrow-up repeat, shortened names, item link preview, Alt/Ctrl-click to invite/target, right-click ignore, chat history, and class colors."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Social & Chat"],
|
||||
enabled = true,
|
||||
order = 60,
|
||||
})
|
||||
|
||||
-- ============================================================
|
||||
-- URL pattern helpers (from chat-links)
|
||||
-- ============================================================
|
||||
local URLPattern = {
|
||||
WWW = { ["rx"]=" (www%d-)%.([_A-Za-z0-9-]+)%.(%S+)%s?", ["fm"]="%s.%s.%s" },
|
||||
PROTOCOL = { ["rx"]=" (%a+)://(%S+)%s?", ["fm"]="%s://%s" },
|
||||
EMAIL = { ["rx"]=" ([_A-Za-z0-9-%.:]+)@([_A-Za-z0-9-]+)(%.)([_A-Za-z0-9-]+%.?[_A-Za-z0-9-]*)%s?", ["fm"]="%s@%s%s%s" },
|
||||
PORTIP = { ["rx"]=" (%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?):(%d%d?%d?%d?%d?)%s?", ["fm"]="%s.%s.%s.%s:%s" },
|
||||
IP = { ["rx"]=" (%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%s?", ["fm"]="%s.%s.%s.%s" },
|
||||
SHORTURL = { ["rx"]=" (%a+)%.(%a+)/(%S+)%s?", ["fm"]="%s.%s/%s" },
|
||||
URLIP = { ["rx"]=" ([_A-Za-z0-9-]+)%.([_A-Za-z0-9-]+)%.(%S+)%:([_0-9-]+)%s?", ["fm"]="%s.%s.%s:%s" },
|
||||
URL = { ["rx"]=" ([_A-Za-z0-9-]+)%.([_A-Za-z0-9-]+)%.(%S+)%s?", ["fm"]="%s.%s.%s" },
|
||||
}
|
||||
|
||||
local function FormatLink(formatter,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||
if not (formatter and a1) then return end
|
||||
local newtext = string.format(formatter,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||
local invalidtld
|
||||
for _, arg in pairs({a10,a9,a8,a7,a6,a5,a4,a3,a2,a1}) do
|
||||
if arg then invalidtld = string.find(arg, "(%.%.)$") break end
|
||||
end
|
||||
if (invalidtld) then return newtext end
|
||||
if formatter == URLPattern.EMAIL.fm then
|
||||
local colon = string.find(a1,":")
|
||||
if (colon) and string.len(a1) > colon then
|
||||
if not (string.sub(a1,1,6) == "mailto") then
|
||||
local prefix,address = string.sub(newtext,1,colon),string.sub(newtext,colon+1)
|
||||
return string.format(" %s|cffccccff|Hurl:%s|h[%s]|h|r ",prefix,address,address)
|
||||
end
|
||||
end
|
||||
end
|
||||
return " |cffccccff|Hurl:" .. newtext .. "|h[" .. newtext .. "]|h|r "
|
||||
end
|
||||
|
||||
local URLFuncs = {
|
||||
["WWW"] = function(a1,a2,a3) return FormatLink(URLPattern.WWW.fm,a1,a2,a3) end,
|
||||
["PROTOCOL"] = function(a1,a2) return FormatLink(URLPattern.PROTOCOL.fm,a1,a2) end,
|
||||
["EMAIL"] = function(a1,a2,a3,a4) return FormatLink(URLPattern.EMAIL.fm,a1,a2,a3,a4) end,
|
||||
["PORTIP"] = function(a1,a2,a3,a4,a5) return FormatLink(URLPattern.PORTIP.fm,a1,a2,a3,a4,a5) end,
|
||||
["IP"] = function(a1,a2,a3,a4) return FormatLink(URLPattern.IP.fm,a1,a2,a3,a4) end,
|
||||
["SHORTURL"] = function(a1,a2,a3) return FormatLink(URLPattern.SHORTURL.fm,a1,a2,a3) end,
|
||||
["URLIP"] = function(a1,a2,a3,a4) return FormatLink(URLPattern.URLIP.fm,a1,a2,a3,a4) end,
|
||||
["URL"] = function(a1,a2,a3) return FormatLink(URLPattern.URL.fm,a1,a2,a3) end,
|
||||
}
|
||||
|
||||
local function HandleLink(text)
|
||||
text = string.gsub(text, URLPattern.WWW.rx, URLFuncs.WWW)
|
||||
text = string.gsub(text, URLPattern.PROTOCOL.rx, URLFuncs.PROTOCOL)
|
||||
text = string.gsub(text, URLPattern.EMAIL.rx, URLFuncs.EMAIL)
|
||||
text = string.gsub(text, URLPattern.PORTIP.rx, URLFuncs.PORTIP)
|
||||
text = string.gsub(text, URLPattern.IP.rx, URLFuncs.IP)
|
||||
text = string.gsub(text, URLPattern.SHORTURL.rx, URLFuncs.SHORTURL)
|
||||
text = string.gsub(text, URLPattern.URLIP.rx, URLFuncs.URLIP)
|
||||
text = string.gsub(text, URLPattern.URL.rx, URLFuncs.URL)
|
||||
return text
|
||||
end
|
||||
|
||||
-- URL copy dialog
|
||||
local CopyLinkDialog = CreateFrame("Frame", "ShaguTweaksURLCopy", UIParent)
|
||||
CopyLinkDialog:Hide()
|
||||
CopyLinkDialog:SetWidth(300)
|
||||
CopyLinkDialog:SetHeight(90)
|
||||
CopyLinkDialog:SetFrameStrata("FULLSCREEN")
|
||||
CopyLinkDialog:SetPoint("CENTER", 0, 0)
|
||||
CopyLinkDialog:SetBackdrop({
|
||||
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
||||
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
||||
tile = true, tileSize = 32, edgeSize = 32,
|
||||
insets = { left = 11, right = 12, top = 12, bottom = 11 }
|
||||
})
|
||||
CopyLinkDialog:SetScript("OnShow", function() this.text:HighlightText() end)
|
||||
|
||||
CopyLinkDialog.text = CreateFrame("EditBox", "ShaguTweaksURLCopyEditBox", CopyLinkDialog)
|
||||
CopyLinkDialog.text:SetTextColor(1,.8,0)
|
||||
CopyLinkDialog.text:SetJustifyH("CENTER")
|
||||
CopyLinkDialog.text:SetBackdrop({
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
})
|
||||
CopyLinkDialog.text:SetBackdropColor(0,0,0,.8)
|
||||
CopyLinkDialog.text:SetBackdropBorderColor(.8,.8,.8,1)
|
||||
CopyLinkDialog.text:SetWidth(260)
|
||||
CopyLinkDialog.text:SetHeight(25)
|
||||
CopyLinkDialog.text:SetPoint("TOP", CopyLinkDialog, "TOP", 0, -20)
|
||||
CopyLinkDialog.text:SetFontObject(GameFontNormal)
|
||||
CopyLinkDialog.text:SetScript("OnEscapePressed", function() CopyLinkDialog:Hide() end)
|
||||
CopyLinkDialog.text:SetScript("OnEditFocusLost", function() CopyLinkDialog:Hide() end)
|
||||
|
||||
CopyLinkDialog.close = CreateFrame("Button", "ShaguTweaksURLCopyClose", CopyLinkDialog, "UIPanelButtonTemplate")
|
||||
CopyLinkDialog.close:SetPoint("BOTTOMRIGHT", CopyLinkDialog, "BOTTOMRIGHT", -20, 20)
|
||||
CopyLinkDialog.close:SetWidth(70)
|
||||
CopyLinkDialog.close:SetHeight(18)
|
||||
CopyLinkDialog.close:SetText(CLOSE)
|
||||
CopyLinkDialog.close:SetScript("OnClick", function() CopyLinkDialog:Hide() end)
|
||||
CopyLinkDialog.CopyText = function(text)
|
||||
CopyLinkDialog.text:SetText(text)
|
||||
CopyLinkDialog:Show()
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Module enable
|
||||
-- ============================================================
|
||||
module.enable = function(self)
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Blue Shaman class colors (vanilla only)
|
||||
-- --------------------------------------------------------
|
||||
if GetExpansion() == "vanilla" then
|
||||
RAID_CLASS_COLORS = {
|
||||
["WARRIOR"] = { r = 0.78, g = 0.61, b = 0.43, colorStr = "ffc79c6e" },
|
||||
["MAGE"] = { r = 0.41, g = 0.8, b = 0.94, colorStr = "ff69ccf0" },
|
||||
["ROGUE"] = { r = 1, g = 0.96, b = 0.41, colorStr = "fffff569" },
|
||||
["DRUID"] = { r = 1, g = 0.49, b = 0.04, colorStr = "ffff7d0a" },
|
||||
["HUNTER"] = { r = 0.67, g = 0.83, b = 0.45, colorStr = "ffabd473" },
|
||||
["SHAMAN"] = { r = 0.14, g = 0.35, b = 1.0, colorStr = "ff2459ff" },
|
||||
["PRIEST"] = { r = 1, g = 1, b = 1, colorStr = "ffffffff" },
|
||||
["WARLOCK"] = { r = 0.58, g = 0.51, b = 0.79, colorStr = "ff9482c9" },
|
||||
["PALADIN"] = { r = 0.96, g = 0.55, b = 0.73, colorStr = "fff58cba" },
|
||||
}
|
||||
RAID_CLASS_COLORS = setmetatable(RAID_CLASS_COLORS, { __index = function(tab,key)
|
||||
return { r = 0.6, g = 0.6, b = 0.6, colorStr = "ff999999" }
|
||||
end})
|
||||
end
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Sticky channels & arrow-up repeat
|
||||
-- --------------------------------------------------------
|
||||
ChatTypeInfo.WHISPER.sticky = 1
|
||||
ChatTypeInfo.OFFICER.sticky = 1
|
||||
ChatTypeInfo.RAID_WARNING.sticky = 1
|
||||
ChatTypeInfo.CHANNEL.sticky = 1
|
||||
ChatFrameEditBox:SetAltArrowKeyMode(false)
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Mouse wheel scrolling
|
||||
-- --------------------------------------------------------
|
||||
local function ChatOnMouseWheel()
|
||||
if arg1 > 0 then
|
||||
if IsShiftKeyDown() then this:ScrollToTop()
|
||||
else for i=1,scrollspeed do this:ScrollUp() end end
|
||||
elseif arg1 < 0 then
|
||||
if IsShiftKeyDown() then this:ScrollToBottom()
|
||||
else for i=1,scrollspeed do this:ScrollDown() end end
|
||||
end
|
||||
if this:AtBottom() then
|
||||
_G[this:GetName().."BottomButton"]:Hide()
|
||||
this.scroll = nil
|
||||
else
|
||||
this.scroll = true
|
||||
_G[this:GetName().."BottomButton"]:Show()
|
||||
end
|
||||
end
|
||||
|
||||
for i=1, NUM_CHAT_WINDOWS do
|
||||
_G["ChatFrame"..i]:EnableMouseWheel(true)
|
||||
_G["ChatFrame"..i].scroll = nil
|
||||
_G["ChatFrame"..i]:SetScript("OnMouseWheel", ChatOnMouseWheel)
|
||||
end
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Chat history save/restore
|
||||
-- --------------------------------------------------------
|
||||
local realm = GetRealmName()
|
||||
local player = UnitName("player")
|
||||
|
||||
local function SaveChatHistory(id, msg, r, g, b)
|
||||
ShaguTweaks_cache = ShaguTweaks_cache or {}
|
||||
ShaguTweaks_cache["chathistory"] = ShaguTweaks_cache["chathistory"] or {}
|
||||
ShaguTweaks_cache["chathistory"][realm] = ShaguTweaks_cache["chathistory"][realm] or {}
|
||||
ShaguTweaks_cache["chathistory"][realm][player] = ShaguTweaks_cache["chathistory"][realm][player] or {}
|
||||
ShaguTweaks_cache["chathistory"][realm][player][id] = ShaguTweaks_cache["chathistory"][realm][player][id] or {}
|
||||
if r and g and b then
|
||||
local color = rgbhex(r*.5+.2, g*.5+.2, b*.5+.2)
|
||||
msg = string.gsub(msg, "^", color)
|
||||
msg = string.gsub(msg, "|r", "|r"..color)
|
||||
end
|
||||
local history = ShaguTweaks_cache["chathistory"][realm][player][id]
|
||||
table.insert(history, 1, msg)
|
||||
if history[30] then table.remove(history, 30) end
|
||||
end
|
||||
|
||||
local function GetChatHistory(id)
|
||||
ShaguTweaks_cache = ShaguTweaks_cache or {}
|
||||
ShaguTweaks_cache["chathistory"] = ShaguTweaks_cache["chathistory"] or {}
|
||||
ShaguTweaks_cache["chathistory"][realm] = ShaguTweaks_cache["chathistory"][realm] or {}
|
||||
ShaguTweaks_cache["chathistory"][realm][player] = ShaguTweaks_cache["chathistory"][realm][player] or {}
|
||||
ShaguTweaks_cache["chathistory"][realm][player][id] = ShaguTweaks_cache["chathistory"][realm][player][id] or {}
|
||||
return ShaguTweaks_cache["chathistory"][realm][player][id]
|
||||
end
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Per-frame hooks: history + CLINK cleanup + URLs + class colors
|
||||
-- --------------------------------------------------------
|
||||
for i=1, NUM_CHAT_WINDOWS do
|
||||
local isCombat = 0
|
||||
if _G["ChatFrame"..i] and _G["ChatFrame"..i].messageTypeList then
|
||||
for _, msg in pairs(_G["ChatFrame"..i].messageTypeList) do
|
||||
if strfind(msg,"SPELL",1) or strfind(msg,"COMBAT",1) then
|
||||
isCombat = isCombat + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isCombat <= 5 and _G["ChatFrame"..i] and not _G["ChatFrame"..i].ShaguTweaksChatTweaksHooked then
|
||||
_G["ChatFrame"..i].ShaguTweaksChatTweaksHooked = true
|
||||
|
||||
-- restore history
|
||||
local history = GetChatHistory(i)
|
||||
for j=30,0,-1 do
|
||||
if history[j] then _G["ChatFrame"..i]:AddMessage(history[j], .7,.7,.7) end
|
||||
end
|
||||
|
||||
_G["ChatFrame"..i].ShaguTweaksBaseAddMessage = _G["ChatFrame"..i].AddMessage
|
||||
_G["ChatFrame"..i].AddMessage = function(frame, text, a1, a2, a3, a4, a5)
|
||||
if not text then return end
|
||||
|
||||
-- Remove prat/chatter CLINKs
|
||||
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:enchant:(%x+):([%d-]-):([^}]-)}", "|c%1|Henchant:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:spell:(%x+):([%d-]-):([^}]-)}", "|c%1|Hspell:%2|h[%3]|h|r")
|
||||
text = gsub(text, "{CLINK:quest:(%x+):([%d-]-):([%d-]-):([^}]-)}", "|c%1|Hquest:%2:%3|h[%4]|h|r")
|
||||
|
||||
-- Reduce channel number (e.g. [1. General] -> [1])
|
||||
local channel = string.gsub(text, ".*%[(.-)%]%s+(.*|Hplayer).+", "%1")
|
||||
if string.find(channel, "%d+%. ") then
|
||||
channel = string.gsub(channel, "(%d+)%..*", "%1")
|
||||
text = string.gsub(text, "%[%d+%..-%]%s+(.*|Hplayer)", "[" .. channel .. "] %1")
|
||||
end
|
||||
|
||||
-- URL detection
|
||||
text = HandleLink(text)
|
||||
|
||||
-- Class colors on player links
|
||||
for name in gfind(text, "|Hplayer:(.-)|h") do
|
||||
local real, _ = strsplit(":", name)
|
||||
local color = "|cffaaaaaa"
|
||||
local class = GetUnitData(real)
|
||||
if class and class ~= UNKNOWN then
|
||||
color = rgbhex(RAID_CLASS_COLORS[class])
|
||||
end
|
||||
text = string.gsub(text, "|Hplayer:"..name.."|h%["..real.."%]|h(.-:-)",
|
||||
"|r["..color.."|Hplayer:"..name.."|h"..color..real.."|h|r".."]|r".."%1")
|
||||
end
|
||||
|
||||
SaveChatHistory(frame:GetID(), text, a1, a2, a3)
|
||||
frame:ShaguTweaksBaseAddMessage(text, a1, a2, a3, a4, a5)
|
||||
end
|
||||
|
||||
-- Item link tooltip on mouseover
|
||||
_G["ChatFrame"..i]:SetScript("OnHyperlinkEnter", function()
|
||||
local _, _, linktype = string.find(arg1, "^(.-):(.+)$")
|
||||
if linktype == "item" then
|
||||
GameTooltip:SetOwner(this, "ANCHOR_CURSOR")
|
||||
GameTooltip:SetHyperlink(arg1)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end)
|
||||
_G["ChatFrame"..i]:SetScript("OnHyperlinkLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
|
||||
-- Alt/Ctrl-click player names; URL copy
|
||||
_G["ChatFrame"..i]:SetScript("OnHyperlinkClick", function()
|
||||
local _, _, playerLink = string.find(arg1, "(player:.+)")
|
||||
if playerLink then
|
||||
local _, pname = strsplit(":", playerLink)
|
||||
if IsAltKeyDown() then
|
||||
InviteByName(pname)
|
||||
elseif IsControlKeyDown() then
|
||||
TargetByName(pname, true)
|
||||
else
|
||||
ChatFrame_OnHyperlinkShow(arg1, arg2, arg3)
|
||||
end
|
||||
elseif strsub(arg1,1,3) == "url" then
|
||||
if string.len(arg1) > 4 and string.sub(arg1,1,4) == "url:" then
|
||||
CopyLinkDialog.CopyText(string.sub(arg1, 5))
|
||||
end
|
||||
else
|
||||
ChatFrame_OnHyperlinkShow(arg1, arg2, arg3)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Shorten channel names
|
||||
-- --------------------------------------------------------
|
||||
local left, right = "[", "]"
|
||||
local default = " " .. "%s" .. "|r:" .. "\32"
|
||||
_G.CHAT_CHANNEL_GET = "%s" .. "|r:" .. "\32"
|
||||
_G.CHAT_GUILD_GET = left.."G"..right .. default
|
||||
_G.CHAT_OFFICER_GET = left.."O"..right .. default
|
||||
_G.CHAT_PARTY_GET = left.."P"..right .. default
|
||||
_G.CHAT_RAID_GET = left.."R"..right .. default
|
||||
_G.CHAT_RAID_LEADER_GET = left.."RL"..right .. default
|
||||
_G.CHAT_RAID_WARNING_GET = left.."RW"..right .. default
|
||||
_G.CHAT_BATTLEGROUND_GET = left.."BG"..right .. default
|
||||
_G.CHAT_BATTLEGROUND_LEADER_GET = left.."BL"..right .. default
|
||||
_G.CHAT_SAY_GET = left.."S"..right .. default
|
||||
_G.CHAT_YELL_GET = left.."Y"..right .. default
|
||||
_G.CHAT_WHISPER_GET = "[From]" .. default
|
||||
_G.CHAT_WHISPER_INFORM_GET = "[To]" .. default
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- SetItemRef hook for URL/quest/player links
|
||||
-- --------------------------------------------------------
|
||||
local HookSetItemRef = SetItemRef
|
||||
function _G.SetItemRef(link, text, button)
|
||||
if (strsub(link,1,3) == "url") then
|
||||
if string.len(link) > 4 and string.sub(link,1,4) == "url:" then
|
||||
CopyLinkDialog.CopyText(string.sub(link, 5))
|
||||
end
|
||||
return
|
||||
end
|
||||
local questlink, _, quest_id = string.find(link, "quest:(%d+):.*")
|
||||
local playerlink = strsub(link,1,6) == "player"
|
||||
if ShaguQuest or pfQuest or Questie then questlink = nil end
|
||||
if questlink then
|
||||
local _, _, quest_title = string.find(text, ".*|h%[(.*)%]|h.*")
|
||||
if quest_title then
|
||||
HideUIPanel(ItemRefTooltip)
|
||||
ShowUIPanel(ItemRefTooltip)
|
||||
ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE")
|
||||
ItemRefTooltip:AddLine(quest_title, 1,1,0)
|
||||
ItemRefTooltip:AddDoubleLine("Quest ID", quest_id, .6,.6,.6, 1,1,1)
|
||||
ItemRefTooltip:Show()
|
||||
end
|
||||
return
|
||||
elseif playerlink then
|
||||
local name = strsub(link, 8)
|
||||
if name and strlen(name) > 0 then
|
||||
local n, _ = strsplit(":", name)
|
||||
n = gsub(n, "([^%s]*)%s+([^%s]*)%s+([^%s]*)", "%3")
|
||||
n = gsub(n, "([^%s]*)%s+([^%s]*)", "%2")
|
||||
if IsShiftKeyDown() and ChatFrameEditBox:IsVisible() then
|
||||
ChatFrameEditBox:Insert("|cffffffff|Hplayer:"..n.."|h["..n.."]|h|r")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
HookSetItemRef(link, text, button)
|
||||
end
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Right-click ignore
|
||||
-- --------------------------------------------------------
|
||||
UnitPopupButtons["IGNORE_PLAYER"] = { text = "Ignore", dist = 0 }
|
||||
for index, value in ipairs(UnitPopupMenus["FRIEND"]) do
|
||||
if value == "GUILD_LEAVE" then
|
||||
table.insert(UnitPopupMenus["FRIEND"], index+1, "IGNORE_PLAYER")
|
||||
end
|
||||
end
|
||||
hooksecurefunc("UnitPopup_OnClick", function(self)
|
||||
if this.value == "IGNORE_PLAYER" then
|
||||
AddIgnore(_G[UIDROPDOWNMENU_INIT_MENU].name)
|
||||
end
|
||||
end)
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Social colors: guild, friends, who lists
|
||||
-- --------------------------------------------------------
|
||||
ShaguTweaks_cache = ShaguTweaks_cache or {}
|
||||
ShaguTweaks_cache["players"] = ShaguTweaks_cache["players"] or {}
|
||||
local playerdb = ShaguTweaks_cache["players"]
|
||||
|
||||
local socialmod = CreateFrame("Frame", "ShaguTweaksSocialMod", UIParent)
|
||||
socialmod:RegisterEvent("CHAT_MSG_SYSTEM")
|
||||
socialmod:SetScript("OnEvent", function()
|
||||
local name = cmatch(arg1, _G.ERR_FRIEND_ONLINE_SS)
|
||||
name = cmatch(arg1, _G.ERR_FRIEND_OFFLINE_S)
|
||||
if name and playerdb[name] and playerdb[name].cname then
|
||||
playerdb[name].lastseen = date("%a %d-%b-%Y")
|
||||
end
|
||||
end)
|
||||
|
||||
hooksecurefunc("GuildStatus_Update", function()
|
||||
local playerzone = GetRealZoneText()
|
||||
local off = FauxScrollFrame_GetOffset(GuildListScrollFrame)
|
||||
local _, _, playerrankindex = GetGuildInfo("player")
|
||||
for i=1, GUILDMEMBERS_TO_DISPLAY do
|
||||
local name, _, rankindex, level, class, zone, _, _, online = GetGuildRosterInfo(off + i)
|
||||
class = L["class"][class]
|
||||
if name then
|
||||
if class then
|
||||
local color = RAID_CLASS_COLORS[class]
|
||||
local alpha = online and 1 or .5
|
||||
_G["GuildFrameButton"..i.."Name"]:SetTextColor(color.r, color.g, color.b, alpha)
|
||||
_G["GuildFrameButton"..i.."Class"]:SetTextColor(color.r, color.g, color.b, alpha)
|
||||
_G["GuildFrameGuildStatusButton"..i.."Name"]:SetTextColor(color.r, color.g, color.b, alpha)
|
||||
end
|
||||
if level then
|
||||
local color = GetDifficultyColor(level)
|
||||
local alpha = online and 1 or .5
|
||||
_G["GuildFrameButton"..i.."Level"]:SetTextColor(color.r+.2, color.g+.2, color.b+.2, alpha)
|
||||
end
|
||||
if zone and zone == playerzone then
|
||||
local alpha = online and 1 or .5
|
||||
_G["GuildFrameButton"..i.."Zone"]:SetTextColor(.5, 1, 1, alpha)
|
||||
end
|
||||
if rankindex and rankindex == playerrankindex then
|
||||
local alpha = online and 1 or .5
|
||||
_G["GuildFrameGuildStatusButton"..i.."Rank"]:SetTextColor(.5, 1, 1, alpha)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local FRIENDS_NAME_LOCATION = GetExpansion() == "vanilla" and "ButtonTextNameLocation" or "ButtonTextLocation"
|
||||
hooksecurefunc("FriendsList_Update", function()
|
||||
if GetNumFriends() == 0 then return end
|
||||
local playerzone = GetRealZoneText()
|
||||
local off = FauxScrollFrame_GetOffset(FriendsFrameFriendsScrollFrame)
|
||||
for i=1, FRIENDS_TO_DISPLAY do
|
||||
local name, level, class, zone, connected, status = GetFriendInfo(off + i)
|
||||
if not name or name == _G.UNKNOWN then break end
|
||||
local friendName = _G["FriendsFrameFriendButton"..i.."ButtonTextName"]
|
||||
local friendLoc = _G["FriendsFrameFriendButton"..i..FRIENDS_NAME_LOCATION]
|
||||
local friendInfo = _G["FriendsFrameFriendButton"..i.."ButtonTextInfo"]
|
||||
local caption = friendName or friendLoc
|
||||
if connected then
|
||||
if not class or class == _G.UNKNOWN then break end
|
||||
local ccolor = RAID_CLASS_COLORS[L["class"][class]] or { 1,1,1 }
|
||||
local lcolor = GetDifficultyColor(tonumber(level)) or { 1,1,1 }
|
||||
zone = (zone == playerzone and "|cffffffff" or "|cffcccccc") .. zone .. "|r"
|
||||
local cname = rgbhex(ccolor) .. name .. "|r"
|
||||
local clevel = rgbhex(lcolor) .. level .. "|r"
|
||||
if playerdb[name] then
|
||||
playerdb[name].lastseen = date("%a %d-%b-%Y")
|
||||
playerdb[name].cname = cname
|
||||
playerdb[name].clevel = clevel
|
||||
playerdb[name].cclass = ccolor
|
||||
end
|
||||
if friendName then
|
||||
friendName:SetText(cname)
|
||||
friendLoc:SetText(format(TEXT(FRIENDS_LIST_TEMPLATE), zone, status))
|
||||
else
|
||||
friendLoc:SetText(format(TEXT(FRIENDS_LIST_TEMPLATE), cname, zone, status))
|
||||
end
|
||||
friendInfo:SetText(format(TEXT(friendinfo), clevel, class, ""))
|
||||
caption:SetVertexColor(1,1,1,.9)
|
||||
friendInfo:SetVertexColor(1,1,1,.9)
|
||||
else
|
||||
if playerdb[name] and playerdb[name].cname and playerdb[name].clevel and playerdb[name].lastseen then
|
||||
caption:SetText(format(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), playerdb[name].cname))
|
||||
friendInfo:SetText(format(TEXT(friendinfo), playerdb[name].clevel, playerdb[name].lastseen, ""))
|
||||
else
|
||||
caption:SetText(format(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), name.."|r"))
|
||||
friendInfo:SetText(TEXT(UNKNOWN))
|
||||
end
|
||||
caption:SetVertexColor(1,1,1,.4)
|
||||
friendInfo:SetVertexColor(1,1,1,.4)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hooksecurefunc("WhoList_Update", function()
|
||||
local num, max = GetNumWhoResults()
|
||||
local off = FauxScrollFrame_GetOffset(WhoListScrollFrame)
|
||||
local playerzone = GetRealZoneText()
|
||||
local playerrace = UnitRace("player")
|
||||
local playerguild = GetGuildInfo("player")
|
||||
for i=1, WHOS_TO_DISPLAY do
|
||||
local name, guild, level, race, class, zone = GetWhoInfo(off + i)
|
||||
local displayedText = ""
|
||||
if num + 1 >= MAX_WHOS_FROM_SERVER then
|
||||
displayedText = format(WHO_FRAME_SHOWN_TEMPLATE, MAX_WHOS_FROM_SERVER)
|
||||
WhoFrameTotals:SetText("|cffffffff"..format(GetText("WHO_FRAME_TOTAL_TEMPLATE",nil,num),max).." |cffaaaaaa"..displayedText)
|
||||
else
|
||||
displayedText = format(WHO_FRAME_SHOWN_TEMPLATE, num)
|
||||
WhoFrameTotals:SetText("|cffffffff"..format(GetText("WHO_FRAME_TOTAL_TEMPLATE",nil,num),num).." |cffaaaaaa"..displayedText)
|
||||
end
|
||||
class = L["class"][class]
|
||||
_G["WhoFrameButton"..i.."Name"]:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
||||
if UIDropDownMenu_GetSelectedID(WhoFrameDropDown) == 1 then
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(zone == playerzone and .5 or 1, 1, 1)
|
||||
elseif UIDropDownMenu_GetSelectedID(WhoFrameDropDown) == 2 then
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(guild == playerguild and .5 or 1, 1, 1)
|
||||
elseif UIDropDownMenu_GetSelectedID(WhoFrameDropDown) == 3 then
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(race == playerrace and .5 or 1, 1, 1)
|
||||
end
|
||||
if class then
|
||||
local color = RAID_CLASS_COLORS[class]
|
||||
_G["WhoFrameButton"..i.."Class"]:SetTextColor(color.r, color.g, color.b, 1)
|
||||
end
|
||||
local color = GetDifficultyColor(level)
|
||||
_G["WhoFrameButton"..i.."Level"]:SetTextColor(color.r, color.g, color.b)
|
||||
end
|
||||
end)
|
||||
|
||||
end
|
||||
@@ -0,0 +1,125 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local hooksecurefunc = hooksecurefunc or ShaguTweaks.hooksecurefunc
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
local AddBorder = ShaguTweaks.AddBorder
|
||||
local TimeConvert = ShaguTweaks.TimeConvert
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Cooldown Numbers"],
|
||||
description = T["Display the remaining duration as text on every cooldown."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
enabled = true,
|
||||
color = { r = .3, g = .3, b = .3, a = .9}
|
||||
})
|
||||
|
||||
local function CooldownOnUpdate()
|
||||
-- hide frames without parent
|
||||
local parent = this:GetParent()
|
||||
if not parent then this:Hide() end
|
||||
|
||||
if not this.tick then this.tick = GetTime() + .1 end
|
||||
if this.tick > GetTime() then return end
|
||||
this.tick = GetTime() + .1
|
||||
|
||||
-- fix own alpha value (should be inherited, but somehow isn't always)
|
||||
this:SetAlpha(parent:GetAlpha())
|
||||
|
||||
if this.start < GetTime() then
|
||||
-- calculating remaining time as it should be
|
||||
local remaining = this.duration - (GetTime() - this.start)
|
||||
if remaining > 0 then
|
||||
this.text:SetText(TimeConvert(remaining))
|
||||
else
|
||||
this:Hide()
|
||||
end
|
||||
else
|
||||
-- I have absolutely no idea, but it works:
|
||||
-- https://github.com/Stanzilla/WoWUIBugs/issues/47
|
||||
local time = time()
|
||||
local startupTime = time - GetTime()
|
||||
-- just a simplification of: ((2^32) - (start * 1000)) / 1000
|
||||
local cdTime = (2 ^ 32) / 1000 - this.start
|
||||
local cdStartTime = startupTime - cdTime
|
||||
local cdEndTime = cdStartTime + this.duration
|
||||
local remaining = cdEndTime - time
|
||||
|
||||
if remaining >= 0 then
|
||||
this.text:SetText(TimeConvert(remaining))
|
||||
else
|
||||
this:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function CreateCoolDown(cooldown, start, duration)
|
||||
local parent = cooldown:GetParent()
|
||||
if not parent then return end
|
||||
|
||||
-- skip already set debuff timers
|
||||
if cooldown.readable then return end
|
||||
|
||||
local parentname = parent and parent.GetName and parent:GetName()
|
||||
parentname = parentname or "UnknownCooldownFrame"
|
||||
|
||||
cooldown.cooldowntext = CreateFrame("Frame", parentname .. "CooldownText", cooldown)
|
||||
cooldown.cooldowntext:SetAllPoints(cooldown)
|
||||
cooldown.cooldowntext:SetFrameLevel(parent:GetFrameLevel() + 1)
|
||||
cooldown.cooldowntext.text = cooldown.cooldowntext:CreateFontString(parentname .. "CooldownTextFont", "OVERLAY")
|
||||
|
||||
-- detect dynamic font size
|
||||
local size = parent:GetHeight() or 0
|
||||
size = size > 0 and size * .64 or 12
|
||||
size = size > 14 and 14 or size
|
||||
|
||||
-- set fonts
|
||||
cooldown.cooldowntext.text:SetFont(STANDARD_TEXT_FONT, size, "OUTLINE")
|
||||
cooldown.cooldowntext.text:SetPoint("CENTER", cooldown.cooldowntext, "CENTER", 0, 0)
|
||||
cooldown.cooldowntext:SetScript("OnUpdate", CooldownOnUpdate)
|
||||
end
|
||||
|
||||
local function SetCooldown(this, start, duration, enable)
|
||||
-- add support for omnicc's disable flag
|
||||
if this.noCooldownCount then return end
|
||||
|
||||
-- skip ShaguPlates-owned frames (nameplates etc.)
|
||||
if this.pfCooldownType then return end
|
||||
|
||||
-- don't draw global cooldowns
|
||||
if not duration or duration < 2 then
|
||||
-- hide if already existing
|
||||
if this.cooldowntext then
|
||||
this.cooldowntext:Hide()
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not this.cooldowntext then
|
||||
CreateCoolDown(this, start, duration)
|
||||
end
|
||||
|
||||
if this.cooldowntext then
|
||||
if start > 0 and duration > 0 and (not enable or enable > 0) then
|
||||
this.cooldowntext:Show()
|
||||
else
|
||||
this.cooldowntext:Hide()
|
||||
end
|
||||
|
||||
this.cooldowntext.start = start
|
||||
this.cooldowntext.duration = duration
|
||||
end
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
if GetExpansion() == "vanilla" then
|
||||
-- vanilla does not have a cooldown frame type, so we hook the
|
||||
-- regular SetTimer function that each one is calling.
|
||||
hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
|
||||
else
|
||||
-- tbc and later expansion have a cooldown frametype, so we can
|
||||
-- hook directly into the frame creation and add our function there.
|
||||
local methods = getmetatable(CreateFrame('Cooldown', nil, nil, 'CooldownFrameTemplate')).__index
|
||||
hooksecurefunc(methods, 'SetCooldown', SetCooldown)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
-- This module can be used to add your own custom code.
|
||||
-- Make sure to read the comments carefully.
|
||||
|
||||
-- Remove the following line to activate the module:
|
||||
if true then return end
|
||||
|
||||
-- This table holds the meta-data of the module:
|
||||
local module = ShaguTweaks:register({
|
||||
title = "Custom Settings",
|
||||
description = "Custom code: Have a look at mods/custom.lua",
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = nil,
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
-- Global code:
|
||||
-- This is where you can put your most basic variable assignments.
|
||||
-- Code in this scope will *always* run, no matter if the module is enabled or not.
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
|
||||
module.enable = function(self)
|
||||
-- Module code:
|
||||
-- This is where you should put your changes.
|
||||
-- Code in this scope will *only* if the module is enabled.
|
||||
|
||||
-- Example:
|
||||
-- Hide actionbar textures:
|
||||
-- for i = 0, 4 do
|
||||
-- _G["MainMenuMaxLevelBar"..i]:Hide()
|
||||
-- _G["MainMenuBarTexture"..i]:Hide()
|
||||
-- end
|
||||
end
|
||||
@@ -0,0 +1,287 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local HookAddonOrVariable = ShaguTweaks.HookAddonOrVariable
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
local AddBorder = ShaguTweaks.AddBorder
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Darkened UI"],
|
||||
description = T["Turns the entire interface into darker colors."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
enabled = nil,
|
||||
config = {
|
||||
["darkmode.color"] = { r = .3, g = .3, b = .3, a = .9 }
|
||||
}
|
||||
})
|
||||
|
||||
local blacklist = {
|
||||
["Solid Texture"] = true,
|
||||
["WHITE8X8"] = true,
|
||||
["StatusBar"] = true,
|
||||
["BarFill"] = true,
|
||||
["Portrait"] = true,
|
||||
["Button"] = true,
|
||||
["Icon"] = true,
|
||||
["AddOns"] = true,
|
||||
["StationeryTest"] = true,
|
||||
["TargetDead"] = true, -- LootFrame Icon
|
||||
["^KeyRing"] = true, -- bag frame
|
||||
["GossipIcon"] = true,
|
||||
["WorldMap\\(.+)\\"] = true,
|
||||
["PetHappiness"] = true,
|
||||
["Elite"] = true,
|
||||
["Rare"] = true,
|
||||
["ColorPickerWheel"] = true,
|
||||
["ComboPoint"] = true,
|
||||
["Skull"] = true,
|
||||
|
||||
-- LFT:
|
||||
["battlenetworking0"] = true,
|
||||
["damage"] = true,
|
||||
["tank"] = true,
|
||||
["healer"] = true,
|
||||
}
|
||||
|
||||
local regionskips = {
|
||||
-- colorpicker gradient
|
||||
["ColorPickerFrame"] = { [15] = true },
|
||||
-- EQL3: background art tiles on the main frame - BookIcon(1), TopLeft(2), Top_Switch_Off(3), BottomLeft(4), Bottom_Switch_Off(5), Top_Switch_On(6), Bottom_Switch_On(7)
|
||||
["EQL3_QuestLogFrame"] = { [1]=true, [2]=true, [3]=true, [4]=true, [5]=true, [6]=true, [7]=true },
|
||||
-- EQL3: parchment tiles on the description panel - TopMiddle(1), TopRight(2), BottomMiddle(3), BottomRight(4)
|
||||
["EQL3_QuestLogFrame_Description"] = { [1]=true, [2]=true, [3]=true, [4]=true },
|
||||
}
|
||||
|
||||
local backgrounds = {
|
||||
["^SpellBookFrame$"] = { 325, 355, 17, -74 },
|
||||
["^ItemTextFrame$"] = { 300, 355, 24, -74 },
|
||||
["^QuestLogDetailScrollFrame$"] = { QuestLogDetailScrollChildFrame:GetWidth(), QuestLogDetailScrollChildFrame:GetHeight(), 0, 0 },
|
||||
["^QuestFrame(.+)Panel$"] = { 300, 330, 24, -82 },
|
||||
["^GossipFrameGreetingPanel$"] = { 300, 330, 24, -82 },
|
||||
}
|
||||
|
||||
local borders = {
|
||||
["ShapeshiftButton"] = 3,
|
||||
["BuffButton"] = 3,
|
||||
["TargetFrameBuff"] = 3,
|
||||
["TempEnchant"] = 3,
|
||||
["SpellButton"] = 3,
|
||||
["SpellBookSkillLineTab"] = 3,
|
||||
["ActionButton%d+$"] = 3,
|
||||
["MultiBar(.+)Button%d+$"] = 3,
|
||||
["KeyRingButton"] = 2,
|
||||
["ActionBarUpButton"] = -3,
|
||||
["ActionBarDownButton"] = -3,
|
||||
["MainMenuBarPerformanceBarFrameButton"] = { -12, -1, -8, 4 },
|
||||
["Character(.+)Slot$"] = 3,
|
||||
["Inspect(.+)Slot$"] = 3,
|
||||
["ContainerFrame(.+)Item"] = 3,
|
||||
["MainMenuBarBackpackButton$"] = 3,
|
||||
["CharacterBag(.+)Slot$"] = 3,
|
||||
["ChatFrame(.+)Button"] = -2,
|
||||
["PetFrameHappiness"] = 2,
|
||||
["MicroButton"] = { -21, 0, 0, 0 },
|
||||
}
|
||||
|
||||
local addonframes = {
|
||||
["Blizzard_TalentUI"] = { "TalentFrame" },
|
||||
["Blizzard_AuctionUI"] = { "AuctionFrame", "AuctionDressUpFrame" },
|
||||
["Blizzard_CraftUI"] = { "CraftFrame" },
|
||||
["Blizzard_InspectUI"] = { "InspectPaperDollFrame", "InspectHonorFrame", "InspectFrameTab1", "InspectFrameTab2" },
|
||||
["Blizzard_MacroUI"] = { "MacroFrame", "MacroPopupFrame" },
|
||||
["Blizzard_RaidUI"] = { "ReadyCheckFrame" },
|
||||
["Blizzard_TalentUI"] = { "TalentFrame" },
|
||||
["Blizzard_TradeSkillUI"] = { "TradeSkillFrame" },
|
||||
["Blizzard_TrainerUI"] = { "ClassTrainerFrame" },
|
||||
}
|
||||
|
||||
-- sizing is a bit different on tbc
|
||||
if GetExpansion() == "tbc" then
|
||||
borders["BuffButton"] = 2
|
||||
borders["TempEnchant"] = 2
|
||||
borders["MicroButton"] = { -21, 0, 0, 0 }
|
||||
end
|
||||
|
||||
local function IsBlacklisted(texture)
|
||||
local name = texture:GetName()
|
||||
local texture = texture:GetTexture()
|
||||
if not texture then return true end
|
||||
|
||||
if name then
|
||||
for entry in pairs(blacklist) do
|
||||
if string.find(name, entry, 1) then return true end
|
||||
end
|
||||
end
|
||||
|
||||
for entry in pairs(blacklist) do
|
||||
if string.find(texture, entry, 1) then return true end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function AddSpecialBackground(frame, w, h, x, y)
|
||||
frame.Material = frame.Material or frame:CreateTexture(nil, "OVERLAY")
|
||||
frame.Material:SetTexture("Interface\\Stationery\\StationeryTest1")
|
||||
frame.Material:SetWidth(w)
|
||||
frame.Material:SetHeight(h)
|
||||
frame.Material:SetPoint("TOPLEFT", frame, x, y)
|
||||
frame.Material:SetVertexColor(.8, .8, .8)
|
||||
end
|
||||
|
||||
local function DarkenFrame(frame, r, g, b, a)
|
||||
-- dont't do anything if disabled
|
||||
if not ShaguTweaks.DarkMode then return end
|
||||
|
||||
-- set defaults
|
||||
if not r and not g and not b then
|
||||
r, g, b, a = module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, module.config["darkmode.color"].a
|
||||
end
|
||||
|
||||
-- iterate through all subframes
|
||||
if frame and frame.GetChildren then
|
||||
for _, frame in pairs({frame:GetChildren()}) do
|
||||
DarkenFrame(frame, r, g, b, a)
|
||||
end
|
||||
end
|
||||
|
||||
-- set vertex on all regions
|
||||
if frame and frame.GetRegions then
|
||||
-- read name
|
||||
local name = frame.GetName and frame:GetName()
|
||||
|
||||
-- set a dark backdrop border color everywhere
|
||||
frame:SetBackdropBorderColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, module.config["darkmode.color"].a)
|
||||
|
||||
-- add special backgrounds to quests and such
|
||||
for pattern, inset in pairs(backgrounds) do
|
||||
if name and string.find(name, pattern) then AddSpecialBackground(frame, inset[1], inset[2], inset[3], inset[4]) end
|
||||
end
|
||||
|
||||
-- add black borders around specified buttons
|
||||
for pattern, inset in pairs(borders) do
|
||||
if name and string.find(name, pattern) then AddBorder(frame, inset, module.config["darkmode.color"]) end
|
||||
end
|
||||
|
||||
-- scan through all regions (textures)
|
||||
for id, region in pairs({frame:GetRegions()}) do
|
||||
if region.SetVertexColor and region:GetObjectType() == "Texture" then
|
||||
if region:GetTexture() and string.find(region:GetTexture(), "UI%-Panel%-Button%-Up") then
|
||||
-- monochrome buttons
|
||||
-- region:SetDesaturated(true)
|
||||
elseif name and id and regionskips[name] and regionskips[name][id] then
|
||||
-- skip special regions
|
||||
elseif region.GetBlendMode and region:GetBlendMode() == "ADD" then
|
||||
-- skip blend over textures
|
||||
elseif IsBlacklisted(region) then
|
||||
-- skip blacklisted texture names
|
||||
else
|
||||
region:SetVertexColor(r,g,b,a)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- register darken frame to global
|
||||
ShaguTweaks.DarkenFrame = DarkenFrame
|
||||
|
||||
module.enable = function(self)
|
||||
ShaguTweaks.DarkMode = true
|
||||
|
||||
local name, original, r, g, b
|
||||
local hookBuffButton_Update = BuffButton_Update
|
||||
function BuffButton_Update(buttonName, index, filter)
|
||||
hookBuffButton_Update(buttonName, index, filter)
|
||||
|
||||
-- tbc passes buttonName and index arguments, vanilla uses "this" context
|
||||
name = buttonName and index and buttonName .. index or this:GetName()
|
||||
original = _G[name.."Border"]
|
||||
|
||||
if original and this.ShaguTweaks_border then
|
||||
r, g, b = original:GetVertexColor()
|
||||
this.ShaguTweaks_border:SetBackdropBorderColor(r, g, b, 1)
|
||||
original:SetAlpha(0)
|
||||
elseif not original and _G[name] then
|
||||
-- tbc buff buttons don't have borders, so we
|
||||
-- need to manually add a dark one.
|
||||
AddBorder(_G[name], 2, module.config["darkmode.color"])
|
||||
end
|
||||
end
|
||||
|
||||
TOOLTIP_DEFAULT_COLOR.r = module.config["darkmode.color"].r
|
||||
TOOLTIP_DEFAULT_COLOR.g = module.config["darkmode.color"].g
|
||||
TOOLTIP_DEFAULT_COLOR.b = module.config["darkmode.color"].b
|
||||
|
||||
TOOLTIP_DEFAULT_BACKGROUND_COLOR.r = module.config["darkmode.color"].r
|
||||
TOOLTIP_DEFAULT_BACKGROUND_COLOR.g = module.config["darkmode.color"].g
|
||||
TOOLTIP_DEFAULT_BACKGROUND_COLOR.b = module.config["darkmode.color"].b
|
||||
|
||||
DarkenFrame(UIParent)
|
||||
DarkenFrame(WorldMapFrame)
|
||||
DarkenFrame(DropDownList1)
|
||||
DarkenFrame(DropDownList2)
|
||||
DarkenFrame(DropDownList3)
|
||||
|
||||
-- align all actionbutton textures
|
||||
local bars = { "Action", "BonusAction", "MultiBarBottomLeft", "MultiBarBottomRight", "MultiBarLeft", "MultiBarRight", "Shapeshift" }
|
||||
for _, prefix in pairs(bars) do
|
||||
for i = 1, NUM_ACTIONBAR_BUTTONS do
|
||||
local button = _G[prefix .. "Button" .. i]
|
||||
local texture = _G[prefix.."Button"..i.."NormalTexture"]
|
||||
|
||||
if button and texture then
|
||||
texture:SetWidth(60)
|
||||
texture:SetHeight(60)
|
||||
texture:SetPoint("CENTER", 0, 0)
|
||||
ShaguTweaks.AddBorder(button, 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, button in pairs({ MinimapZoomOut, MinimapZoomIn }) do
|
||||
for _, func in pairs({ "GetNormalTexture", "GetDisabledTexture", "GetPushedTexture" }) do
|
||||
if button[func] then
|
||||
local tex = button[func](button)
|
||||
if tex then
|
||||
tex:SetVertexColor(module.config["darkmode.color"].r+.2, module.config["darkmode.color"].g+.2, module.config["darkmode.color"].b+.2, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
HookAddonOrVariable("Blizzard_AuctionUI", function()
|
||||
for i = 1, 15 do
|
||||
local tex = _G["AuctionFilterButton"..i]:GetNormalTexture()
|
||||
tex:SetVertexColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, 1)
|
||||
end
|
||||
|
||||
for i = 1, 8 do
|
||||
_G["BrowseButton"..i.."Left"]:SetVertexColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, 1)
|
||||
_G["BrowseButton"..i.."Right"]:SetVertexColor(module.config["darkmode.color"].r, module.config["darkmode.color"].g, module.config["darkmode.color"].b, 1)
|
||||
end
|
||||
end)
|
||||
|
||||
for addon, data in pairs(addonframes) do
|
||||
for _, frame in pairs(data) do
|
||||
local frame = frame
|
||||
HookAddonOrVariable(frame, function()
|
||||
DarkenFrame(_G[frame])
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
HookAddonOrVariable("Blizzard_TimeManager", function()
|
||||
DarkenFrame(TimeManagerClockButton)
|
||||
end)
|
||||
|
||||
HookAddonOrVariable("GameTooltipStatusBarBackdrop", function()
|
||||
DarkenFrame(_G["GameTooltipStatusBarBackdrop"])
|
||||
end)
|
||||
|
||||
table.insert(ShaguTweaks.libnameplate.OnUpdate, function()
|
||||
if not this.darkened then
|
||||
this.darkened = true
|
||||
DarkenFrame(this)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,218 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Equip Compare"],
|
||||
description = T["Shows currently equipped items on tooltips while the shift key is pressed."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Tooltip & Items"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local sides = { "Left", "Right" }
|
||||
|
||||
local function AddHeader(tooltip)
|
||||
local name = tooltip:GetName()
|
||||
|
||||
-- shift all entries one line down
|
||||
for i=tooltip:NumLines(), 1, -1 do
|
||||
for _, side in pairs(sides) do
|
||||
local current = _G[name.."Text"..side..i]
|
||||
local below = _G[name.."Text"..side..i+1]
|
||||
|
||||
if current and current:IsShown() then
|
||||
local text = current:GetText()
|
||||
local r, g, b = current:GetTextColor()
|
||||
|
||||
if text and text ~= "" then
|
||||
if tooltip:NumLines() < i+1 then
|
||||
-- add new line if required
|
||||
tooltip:AddLine(text, r, g, b, true)
|
||||
else
|
||||
-- update existing lines
|
||||
below:SetText(text)
|
||||
below:SetTextColor(r, g, b)
|
||||
below:Show()
|
||||
|
||||
-- hide processed line
|
||||
current:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- add label to first line
|
||||
_G[name.."TextLeft1"]:SetTextColor(.5, .5, .5, 1)
|
||||
_G[name.."TextLeft1"]:SetText(CURRENTLY_EQUIPPED)
|
||||
_G[name.."TextLeft1"]:Show()
|
||||
|
||||
-- update tooltip sizes
|
||||
tooltip:Show()
|
||||
end
|
||||
|
||||
local itemtypes = {
|
||||
["deDE"] = {
|
||||
["INVTYPE_WAND"] = "Zauberstab",
|
||||
["INVTYPE_THROWN"] = "Wurfwaffe",
|
||||
["INVTYPE_GUN"] = "Schusswaffe",
|
||||
["INVTYPE_CROSSBOW"] = "Armbrust",
|
||||
["INVTYPE_PROJECTILE"] = "Projektil",
|
||||
},
|
||||
["enUS"] = {
|
||||
["INVTYPE_WAND"] = "Wand",
|
||||
["INVTYPE_THROWN"] = "Thrown",
|
||||
["INVTYPE_GUN"] = "Gun",
|
||||
["INVTYPE_CROSSBOW"] = "Crossbow",
|
||||
["INVTYPE_PROJECTILE"] = "Projectile",
|
||||
},
|
||||
["esES"] = {
|
||||
["INVTYPE_WAND"] = "Varita",
|
||||
["INVTYPE_THROWN"] = "Arma arrojadiza",
|
||||
["INVTYPE_GUN"] = "Arma de fuego",
|
||||
["INVTYPE_CROSSBOW"] = "Ballesta",
|
||||
["INVTYPE_PROJECTILE"] = "Proyectil",
|
||||
},
|
||||
["frFR"] = {
|
||||
["INVTYPE_WAND"] = "Baguette",
|
||||
["INVTYPE_THROWN"] = "Armes de jet",
|
||||
["INVTYPE_GUN"] = "Arme à feu",
|
||||
["INVTYPE_CROSSBOW"] = "Arbalète",
|
||||
["INVTYPE_PROJECTILE"] = "Projectile",
|
||||
},
|
||||
["koKR"] = {
|
||||
["INVTYPE_WAND"] = "마법봉",
|
||||
["INVTYPE_THROWN"] = "투척 무기",
|
||||
["INVTYPE_GUN"] = "총",
|
||||
["INVTYPE_CROSSBOW"] = "석궁",
|
||||
["INVTYPE_PROJECTILE"] = "투사체",
|
||||
},
|
||||
["ruRU"] = {
|
||||
["INVTYPE_WAND"] = "Жезл",
|
||||
["INVTYPE_THROWN"] = "Метательное",
|
||||
["INVTYPE_GUN"] = "Огнестрельное",
|
||||
["INVTYPE_CROSSBOW"] = "Арбалет",
|
||||
["INVTYPE_PROJECTILE"] = "Боеприпасы",
|
||||
},
|
||||
["zhCN"] = {
|
||||
["INVTYPE_WAND"] = "魔杖",
|
||||
["INVTYPE_THROWN"] = "投掷武器",
|
||||
["INVTYPE_GUN"] = "枪械",
|
||||
["INVTYPE_CROSSBOW"] = "弩",
|
||||
["INVTYPE_PROJECTILE"] = "弹药",
|
||||
}
|
||||
}
|
||||
|
||||
-- set globals for all inventory types
|
||||
for key, value in pairs(itemtypes[GetLocale()]) do setglobal(key, value) end
|
||||
INVTYPE_WEAPON_OTHER = INVTYPE_WEAPON.."_other"
|
||||
INVTYPE_FINGER_OTHER = INVTYPE_FINGER.."_other"
|
||||
INVTYPE_TRINKET_OTHER = INVTYPE_TRINKET.."_other"
|
||||
|
||||
local slots = {
|
||||
[INVTYPE_2HWEAPON] = "MainHandSlot",
|
||||
[INVTYPE_BODY] = "ShirtSlot",
|
||||
[INVTYPE_CHEST] = "ChestSlot",
|
||||
[INVTYPE_CLOAK] = "BackSlot",
|
||||
[INVTYPE_FEET] = "FeetSlot",
|
||||
[INVTYPE_FINGER] = "Finger0Slot",
|
||||
[INVTYPE_FINGER_OTHER] = "Finger1Slot",
|
||||
[INVTYPE_HAND] = "HandsSlot",
|
||||
[INVTYPE_HEAD] = "HeadSlot",
|
||||
[INVTYPE_HOLDABLE] = "SecondaryHandSlot",
|
||||
[INVTYPE_LEGS] = "LegsSlot",
|
||||
[INVTYPE_NECK] = "NeckSlot",
|
||||
[INVTYPE_RANGED] = "RangedSlot",
|
||||
[INVTYPE_RELIC] = "RangedSlot",
|
||||
[INVTYPE_ROBE] = "ChestSlot",
|
||||
[INVTYPE_SHIELD] = "SecondaryHandSlot",
|
||||
[INVTYPE_SHOULDER] = "ShoulderSlot",
|
||||
[INVTYPE_TABARD] = "TabardSlot",
|
||||
[INVTYPE_TRINKET] = "Trinket0Slot",
|
||||
[INVTYPE_TRINKET_OTHER] = "Trinket1Slot",
|
||||
[INVTYPE_WAIST] = "WaistSlot",
|
||||
[INVTYPE_WEAPON] = "MainHandSlot",
|
||||
[INVTYPE_WEAPON_OTHER] = "SecondaryHandSlot",
|
||||
[INVTYPE_WEAPONMAINHAND] = "MainHandSlot",
|
||||
[INVTYPE_WEAPONOFFHAND] = "SecondaryHandSlot",
|
||||
[INVTYPE_WRIST] = "WristSlot",
|
||||
[INVTYPE_WAND] = "RangedSlot",
|
||||
[INVTYPE_GUN] = "RangedSlot",
|
||||
[INVTYPE_PROJECTILE] = "AmmoSlot",
|
||||
[INVTYPE_CROSSBOW] = "RangedSlot",
|
||||
[INVTYPE_THROWN] = "RangedSlot",
|
||||
}
|
||||
|
||||
ShoppingTooltip1:SetClampedToScreen(true)
|
||||
ShoppingTooltip2:SetClampedToScreen(true)
|
||||
|
||||
local function ShowCompare(tooltip)
|
||||
-- abort if shift is not pressed
|
||||
if not IsShiftKeyDown() then
|
||||
ShoppingTooltip1:Hide()
|
||||
ShoppingTooltip2:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
for i=1,tooltip:NumLines() do
|
||||
local tmpText = _G[tooltip:GetName() .. "TextLeft"..i]
|
||||
|
||||
for slotType, slotName in pairs(slots) do
|
||||
if tmpText:GetText() == slotType then
|
||||
local slotID = GetInventorySlotInfo(slotName)
|
||||
|
||||
-- determine screen part
|
||||
local x = GetCursorPosition() / UIParent:GetEffectiveScale()
|
||||
local anchor = x < GetScreenWidth() / 2 and "TOPLEFT" or "TOPRIGHT"
|
||||
local relative = x < GetScreenWidth() / 2 and "TOPRIGHT" or "TOPLEFT"
|
||||
|
||||
-- overwrite position for tooltips without owner
|
||||
local pos, parent = tooltip:GetPoint()
|
||||
if parent and parent == UIParent and pos == "TOPRIGHT" then
|
||||
anchor = "TOPRIGHT"
|
||||
relative = "TOPLEFT"
|
||||
end
|
||||
|
||||
-- first tooltip
|
||||
ShoppingTooltip1:SetOwner(tooltip, "ANCHOR_NONE")
|
||||
ShoppingTooltip1:ClearAllPoints()
|
||||
ShoppingTooltip1:SetPoint(anchor, tooltip, relative, 0, 0)
|
||||
ShoppingTooltip1:SetInventoryItem("player", slotID)
|
||||
ShoppingTooltip1:Show()
|
||||
AddHeader(ShoppingTooltip1)
|
||||
|
||||
-- second tooltip
|
||||
if slots[slotType .. "_other"] then
|
||||
local slotID_other = GetInventorySlotInfo(slots[slotType .. "_other"])
|
||||
ShoppingTooltip2:SetOwner(tooltip, "ANCHOR_NONE")
|
||||
ShoppingTooltip2:ClearAllPoints()
|
||||
if ShoppingTooltip1:IsShown() then
|
||||
ShoppingTooltip2:SetPoint(anchor, ShoppingTooltip1, relative, 0, 0)
|
||||
else
|
||||
ShoppingTooltip2:SetPoint(anchor, tooltip, relative, 0, 0)
|
||||
end
|
||||
ShoppingTooltip2:SetInventoryItem("player", slotID_other)
|
||||
ShoppingTooltip2:Show()
|
||||
AddHeader(ShoppingTooltip2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- show item compare on default tooltips
|
||||
local default = CreateFrame("Frame", nil, GameTooltip)
|
||||
default:SetScript("OnUpdate", function()
|
||||
ShowCompare(GameTooltip)
|
||||
end)
|
||||
|
||||
-- show compare on atlas tooltips
|
||||
ShaguTweaks.HookAddonOrVariable("AtlasLoot", function()
|
||||
local atlas = CreateFrame("Frame", nil, AtlasLootTooltip)
|
||||
atlas:SetScript("OnUpdate", function()
|
||||
ShowCompare(AtlasLootTooltip)
|
||||
ShowCompare(AtlasLootTooltip2)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,107 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local L, T = ShaguTweaks.L, ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Free Slot Count"],
|
||||
description = T["Shows free slot counts on the backpack button: class bag slots (top right), reagent bag slots (bottom left), and total free slots (bottom right)."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["General"],
|
||||
enabled = true,
|
||||
order = 31,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local button = MainMenuBarBackpackButton
|
||||
|
||||
button.class = button:CreateFontString("Status", "LOW", "GameFontNormal")
|
||||
button.class:SetFont(STANDARD_TEXT_FONT, 14, "OUTLINE")
|
||||
button.class:SetPoint("TOPRIGHT", button, "TOPRIGHT", -2, -4)
|
||||
button.class:SetJustifyH("RIGHT")
|
||||
button.class:SetFontObject(GameFontWhite)
|
||||
local _, playerclass = UnitClass("player")
|
||||
local classcolor = RAID_CLASS_COLORS[playerclass] or { r = .5, g = .5, b = .5, a = 1 }
|
||||
button.class:SetTextColor(classcolor.r, classcolor.g, classcolor.b)
|
||||
|
||||
button.reagent = button:CreateFontString("Status", "LOW", "GameFontNormal")
|
||||
button.reagent:SetFont(STANDARD_TEXT_FONT, 14, "OUTLINE")
|
||||
button.reagent:SetPoint("BOTTOMLEFT", button, "BOTTOMLEFT", 2, 4)
|
||||
button.reagent:SetJustifyH("LEFT")
|
||||
button.reagent:SetFontObject(GameFontWhite)
|
||||
button.reagent:SetTextColor(.25, .78, .92)
|
||||
|
||||
button.count = button:CreateFontString("Status", "LOW", "GameFontNormal")
|
||||
button.count:SetFont(STANDARD_TEXT_FONT, 14, "OUTLINE")
|
||||
button.count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 4)
|
||||
button.count:SetJustifyH("RIGHT")
|
||||
button.count:SetFontObject(GameFontWhite)
|
||||
|
||||
-- class-specific bags
|
||||
local soul = { "Core Felcloth Bag", "D'Sak's Small bag", "Felcloth Bag", "Box of Souls", "Small Soul Pouch", "Soul Pouch" }
|
||||
local quiver = { "Ancient Sinew Wrapped Lamina", "Harpy Hide Quiver", "Heavy Quiver", "Quickdraw Quiver", "Quiver of the Night Watch", "Ribbly's Quiver", "Hunting Quiver", "Light Leather Quiver", "Light Quiver", "Medium Quiver", "Small Quiver" }
|
||||
local pouch = { "Gnoll Skin Bandolier", "Bandolier of the Night Watch", "Heavy Leather Ammo Pouch", "Ribbly's Bandolier", "Thick Leather Ammo Pouch", "Hunting Ammo Sack", "Medium Shot Pouch", "Small Ammo Pouch", "Small Leather Ammo Pouch", "Small Shot Pouch" }
|
||||
-- reagent bags
|
||||
local herb = { "Cenarion Herb Bag", "Herb Pouch", "Satchel of Cenarius" }
|
||||
local ench = { "Big Bag of Enchantment", "Enchanted Mageweave Pouch", "Enchanted Runecloth Bag" }
|
||||
|
||||
local freeClass = 0
|
||||
local freeReagent = 0
|
||||
|
||||
local function findName(name, names)
|
||||
for _, bagName in ipairs(names) do
|
||||
if string.find(name, bagName) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function classSlots()
|
||||
local found, free = false, 0
|
||||
for i = 0, 4 do
|
||||
local name = GetBagName(i)
|
||||
if name and (findName(name, soul) or findName(name, quiver) or findName(name, pouch)) then
|
||||
found = true
|
||||
for slot = 1, GetContainerNumSlots(i) do
|
||||
if not GetContainerItemLink(i, slot) then free = free + 1 end
|
||||
end
|
||||
end
|
||||
end
|
||||
freeClass = free
|
||||
button.class:SetText(found and free or "")
|
||||
end
|
||||
|
||||
local function reagentSlots()
|
||||
local found, free = false, 0
|
||||
for i = 0, 4 do
|
||||
local name = GetBagName(i)
|
||||
if name and (findName(name, herb) or findName(name, ench)) then
|
||||
found = true
|
||||
for slot = 1, GetContainerNumSlots(i) do
|
||||
if not GetContainerItemLink(i, slot) then free = free + 1 end
|
||||
end
|
||||
end
|
||||
end
|
||||
freeReagent = free
|
||||
button.reagent:SetText(found and free or "")
|
||||
end
|
||||
|
||||
local function freeSlots()
|
||||
local free = 0
|
||||
for i = 0, 4 do
|
||||
for slot = 1, GetContainerNumSlots(i) do
|
||||
if not GetContainerItemLink(i, slot) then free = free + 1 end
|
||||
end
|
||||
end
|
||||
button.count:SetText(free - freeClass - freeReagent)
|
||||
end
|
||||
|
||||
classSlots()
|
||||
reagentSlots()
|
||||
freeSlots()
|
||||
|
||||
local events = CreateFrame("Frame")
|
||||
events:RegisterEvent("BAG_UPDATE")
|
||||
events:SetScript("OnEvent", function()
|
||||
classSlots()
|
||||
reagentSlots()
|
||||
freeSlots()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local Abbreviate = ShaguTweaks.Abbreviate
|
||||
local GetColorGradient = ShaguTweaks.GetColorGradient
|
||||
local vanilla = ShaguTweaks.GetExpansion() == "vanilla" or nil
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Unit Frame Health Colors"],
|
||||
description = T["Change health text color based on its value."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Unit Frames"],
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local HookUnitFrame_UpdateManaType = UnitFrame_UpdateManaType
|
||||
function UnitFrame_UpdateManaType(uf)
|
||||
HookUnitFrame_UpdateManaType(uf)
|
||||
if not uf then uf = this end
|
||||
local string = uf.manabar and uf.manabar.TextString
|
||||
if not string then return end
|
||||
|
||||
if not strfind(uf.manabar:GetName(), "Health") then
|
||||
local r, g, b = uf.manabar:GetStatusBarColor()
|
||||
string:SetTextColor((r + 2) / 3, (g + 2) / 3, (b + 2) / 3, 1)
|
||||
end
|
||||
end
|
||||
|
||||
local HookTextStatusBar_UpdateTextString = TextStatusBar_UpdateTextString
|
||||
function TextStatusBar_UpdateTextString(sb)
|
||||
if not sb then sb = this end
|
||||
|
||||
HookTextStatusBar_UpdateTextString(sb)
|
||||
local string = sb.TextString
|
||||
|
||||
if string and sb.unit then
|
||||
local min, max = sb:GetMinMaxValues()
|
||||
local cur = sb:GetValue()
|
||||
local percent = max > 0 and floor(cur/max*100) or 0
|
||||
|
||||
if strfind(sb:GetName(), "Health") then
|
||||
local r, g, b = GetColorGradient(percent/100)
|
||||
string:SetTextColor((r + 1) / 2, (g + 1) / 2, (b + 1) / 2, .75)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local Abbreviate = ShaguTweaks.Abbreviate
|
||||
local GetColorGradient = ShaguTweaks.GetColorGradient
|
||||
local vanilla = ShaguTweaks.GetExpansion() == "vanilla" or nil
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Real Health Numbers"],
|
||||
description = T["Estimates health numbers, and shows numbers on player, pet and target unit frames."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Unit Frames"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
TargetFrame.StatusTexts = CreateFrame("Frame", nil, TargetFrame)
|
||||
TargetFrame.StatusTexts:SetAllPoints(TargetFrame)
|
||||
|
||||
TargetFrameHealthBar.TextString = TargetFrame.StatusTexts:CreateFontString("TargetFrameHealthBarText", "OVERLAY")
|
||||
TargetFrameHealthBar.TextString:SetPoint("TOP", TargetFrameHealthBar, "BOTTOM", -2, 23)
|
||||
|
||||
TargetFrameManaBar.TextString = TargetFrame.StatusTexts:CreateFontString("TargetFrameManaBarText", "OVERLAY")
|
||||
TargetFrameManaBar.TextString:SetPoint("TOP", TargetFrameManaBar, "BOTTOM", -2, 22)
|
||||
|
||||
PetFrameHealthBar.TextString:SetPoint("CENTER", PetFrameHealthBar, "CENTER", -2, 0)
|
||||
PetFrameManaBar.TextString:SetPoint("CENTER", PetFrameManaBar, "CENTER", -2, -2)
|
||||
|
||||
for _, frame in pairs( { TargetFrameHealthBar, TargetFrameManaBar, PlayerFrameHealthBar, PlayerFrameManaBar }) do
|
||||
frame.TextString:SetFontObject("GameFontWhite")
|
||||
frame.TextString:SetFont(STANDARD_TEXT_FONT, 10, "OUTLINE")
|
||||
frame.TextString:SetHeight(32)
|
||||
end
|
||||
|
||||
for _, frame in pairs( { PetFrameHealthBar, PetFrameManaBar }) do
|
||||
frame.TextString:SetFontObject("GameFontWhite")
|
||||
frame.TextString:SetFont(STANDARD_TEXT_FONT, 9, "OUTLINE")
|
||||
frame.TextString:SetHeight(32)
|
||||
frame.TextString:SetJustifyH("LEFT")
|
||||
end
|
||||
|
||||
local HookTextStatusBar_UpdateTextString = TextStatusBar_UpdateTextString
|
||||
function TextStatusBar_UpdateTextString(sb)
|
||||
if not sb then sb = this end
|
||||
|
||||
HookTextStatusBar_UpdateTextString(sb)
|
||||
local string = sb.TextString
|
||||
|
||||
if string and sb.unit then
|
||||
-- hide tbc text string element
|
||||
if not vanilla then
|
||||
TargetFrameHealthBarText:Hide()
|
||||
end
|
||||
|
||||
sb.lockShow = 42
|
||||
sb:Show()
|
||||
|
||||
local min, max = sb:GetMinMaxValues()
|
||||
local cur = sb:GetValue()
|
||||
local percent = max > 0 and floor(cur/max*100) or 0
|
||||
|
||||
if sb:GetName() == "TargetFrameHealthBar" then
|
||||
cur, max = ShaguTweaks.libhealth:GetUnitHealth(sb.unit)
|
||||
end
|
||||
|
||||
if cur == percent and strfind(sb:GetName(), "Health") then
|
||||
string:SetText(percent .. "/" .. percent)
|
||||
elseif sb:GetName() == "TargetFrameHealthBar" and cur < max then
|
||||
string:SetText(Abbreviate(cur) .. "/" .. Abbreviate(max) .. " - " .. percent .. "%")
|
||||
else
|
||||
string:SetText(Abbreviate(cur) .. "/" .. Abbreviate(max))
|
||||
end
|
||||
|
||||
if max == 0 then
|
||||
string:Hide()
|
||||
string:SetText("")
|
||||
elseif sb.unit == "target" and UnitIsDead("target") then
|
||||
string:Hide()
|
||||
string:SetText("")
|
||||
elseif sb.unit == "target" and UnitIsGhost("target") then
|
||||
string:Hide()
|
||||
string:SetText("")
|
||||
else
|
||||
string:Show()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Hide Errors"],
|
||||
description = T["Hides and ignores all Lua errors produced by broken addons."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
error = function() return end
|
||||
seterrorhandler(error)
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Hide Gryphons"],
|
||||
description = T["Hides the gryphons left and right of the action bar."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
MainMenuBarLeftEndCap:Hide()
|
||||
MainMenuBarRightEndCap:Hide()
|
||||
end
|
||||
@@ -0,0 +1,222 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
local AddBorder = ShaguTweaks.AddBorder
|
||||
local HookAddonOrVariable = ShaguTweaks.HookAddonOrVariable
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Item Rarity Borders"],
|
||||
description = T["Show item rarity as the border color on bags, bank, character and inspect frames."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Tooltip & Items"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
local defcolor = {}
|
||||
|
||||
local paperdoll_slots = {
|
||||
[0] = "AmmoSlot", "HeadSlot",
|
||||
"NeckSlot", "ShoulderSlot",
|
||||
"ShirtSlot", "ChestSlot",
|
||||
"WaistSlot", "LegsSlot",
|
||||
"FeetSlot", "WristSlot",
|
||||
"HandsSlot", "Finger0Slot",
|
||||
"Finger1Slot", "Trinket0Slot",
|
||||
"Trinket1Slot", "BackSlot",
|
||||
"MainHandSlot", "SecondaryHandSlot",
|
||||
"RangedSlot", "TabardSlot",
|
||||
}
|
||||
|
||||
local inspect_slots = {
|
||||
"HeadSlot", "NeckSlot",
|
||||
"ShoulderSlot", "ShirtSlot",
|
||||
"ChestSlot", "WaistSlot",
|
||||
"LegsSlot", "FeetSlot",
|
||||
"WristSlot", "HandsSlot",
|
||||
"Finger0Slot", "Finger1Slot",
|
||||
"Trinket0Slot", "Trinket1Slot",
|
||||
"BackSlot", "MainHandSlot",
|
||||
"SecondaryHandSlot", "RangedSlot",
|
||||
"TabardSlot"
|
||||
}
|
||||
|
||||
module.enable = function(self)
|
||||
do -- paperdoll
|
||||
local refresh_paperdoll = function()
|
||||
for i, slot in pairs(paperdoll_slots) do
|
||||
local button = _G["Character"..slot]
|
||||
if button then
|
||||
local border = button.ShaguTweaks_border
|
||||
|
||||
if not border then
|
||||
border = AddBorder(button, 3, { r = .5, g = .5, b = .5 })
|
||||
end
|
||||
|
||||
if not defcolor["paperdoll"] then
|
||||
defcolor["paperdoll"] = { border:GetBackdropBorderColor() }
|
||||
end
|
||||
|
||||
local quality = GetInventoryItemQuality("player", i)
|
||||
if quality then
|
||||
local r, g, b = GetItemQualityColor(quality)
|
||||
border:SetBackdropBorderColor(r, g, b, 1)
|
||||
else
|
||||
border:SetBackdropBorderColor(defcolor["paperdoll"][1], defcolor["paperdoll"][2], defcolor["paperdoll"][3], 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local paperdoll = CreateFrame("Frame", nil, CharacterFrame)
|
||||
paperdoll:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
paperdoll:SetScript("OnEvent", refresh_paperdoll)
|
||||
paperdoll:SetScript("OnShow", refresh_paperdoll)
|
||||
end
|
||||
|
||||
do -- inspect
|
||||
local refresh_inspect = function()
|
||||
for i, v in pairs(inspect_slots) do
|
||||
local button = _G["Inspect"..v]
|
||||
local link = GetInventoryItemLink("target", i)
|
||||
local border = button.ShaguTweaks_border
|
||||
|
||||
if not border then
|
||||
border = AddBorder(button, 3, { r = .5, g = .5, b = .5 })
|
||||
end
|
||||
|
||||
if not defcolor["inspect"] then
|
||||
defcolor["inspect"] = { border:GetBackdropBorderColor() }
|
||||
end
|
||||
|
||||
border:SetBackdropBorderColor(defcolor["inspect"][1], defcolor["inspect"][2], defcolor["inspect"][3], 1)
|
||||
if link then
|
||||
local _, _, istring = string.find(link, "|H(.+)|h")
|
||||
local _, _, quality = GetItemInfo(istring)
|
||||
if quality then
|
||||
local r, g, b = GetItemQualityColor(quality)
|
||||
border:SetBackdropBorderColor(r, g, b, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
HookAddonOrVariable("Blizzard_InspectUI", function()
|
||||
local HookInspectPaperDollItemSlotButton_Update = InspectPaperDollItemSlotButton_Update
|
||||
InspectPaperDollItemSlotButton_Update = function(arg)
|
||||
HookInspectPaperDollItemSlotButton_Update(arg)
|
||||
refresh_inspect()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
do -- bags
|
||||
local color = { r = .5, g = .5, b = .46 }
|
||||
|
||||
for i = 0, 3 do
|
||||
AddBorder(_G["CharacterBag"..i.."Slot"], 3, color)
|
||||
end
|
||||
|
||||
for i = 1, 12 do
|
||||
for k = 1, MAX_CONTAINER_ITEMS do
|
||||
AddBorder(_G["ContainerFrame"..i.."Item"..k], 3, color)
|
||||
end
|
||||
end
|
||||
|
||||
local refresh_bags = function()
|
||||
for i = 1, 12 do
|
||||
local frame = _G["ContainerFrame"..i]
|
||||
if frame then
|
||||
local name = frame:GetName()
|
||||
local id = frame:GetID()
|
||||
for i = 1, MAX_CONTAINER_ITEMS do
|
||||
local button = _G[name.."Item"..i]
|
||||
|
||||
if not defcolor["bag"] then
|
||||
defcolor["bag"] = { button.ShaguTweaks_border:GetBackdropBorderColor() }
|
||||
end
|
||||
|
||||
button.ShaguTweaks_border:SetBackdropBorderColor(defcolor["bag"][1], defcolor["bag"][2], defcolor["bag"][3], 1)
|
||||
|
||||
local link = GetContainerItemLink(id, button:GetID())
|
||||
if button and button:IsShown() and link then
|
||||
local _, _, istring = string.find(link, "|H(.+)|h")
|
||||
local _, _, quality = GetItemInfo(istring)
|
||||
if quality then
|
||||
local r, g, b = GetItemQualityColor(quality)
|
||||
button.ShaguTweaks_border:SetBackdropBorderColor(r,g,b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local bags = CreateFrame("Frame", nil, ContainerFrame1)
|
||||
bags:RegisterEvent("BAG_UPDATE")
|
||||
bags:SetScript("OnEvent", refresh_bags)
|
||||
|
||||
local HookContainerFrame_OnShow = ContainerFrame_OnShow
|
||||
function ContainerFrame_OnShow() refresh_bags() HookContainerFrame_OnShow() end
|
||||
|
||||
local HookContainerFrame_OnHide = ContainerFrame_OnHide
|
||||
function ContainerFrame_OnHide() refresh_bags() HookContainerFrame_OnHide() end
|
||||
end
|
||||
|
||||
do -- bank
|
||||
for i = 1, 28 do
|
||||
AddBorder(_G["BankFrameItem"..i], 3, color)
|
||||
end
|
||||
|
||||
local refresh_bank = function()
|
||||
for i = 1, 28 do
|
||||
local button = _G["BankFrameItem"..i]
|
||||
local link = GetContainerItemLink(-1, i)
|
||||
if button then
|
||||
if not defcolor["bank"] then
|
||||
defcolor["bank"] = { button.ShaguTweaks_border:GetBackdropBorderColor() }
|
||||
end
|
||||
|
||||
button.ShaguTweaks_border:SetBackdropBorderColor(defcolor["bank"][1], defcolor["bank"][2], defcolor["bank"][3], 1)
|
||||
|
||||
if link then
|
||||
local _, _, istring = string.find(link, "|H(.+)|h")
|
||||
local _, _, q = GetItemInfo(istring)
|
||||
if q and q > 1 then
|
||||
local r, g, b = GetItemQualityColor(q)
|
||||
button.ShaguTweaks_border:SetBackdropBorderColor(r,g,b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local bank = CreateFrame("Frame", nil, BankFrame)
|
||||
bank:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
|
||||
bank:SetScript("OnEvent", refresh_bank)
|
||||
bank:SetScript("OnShow", refresh_bank)
|
||||
end
|
||||
|
||||
do -- weapon buff
|
||||
AddBorder(TempEnchant1, 3, {.2,.2,.2})
|
||||
AddBorder(TempEnchant2, 3, {.2,.2,.2})
|
||||
|
||||
local hookBuffFrame_Enchant_OnUpdate = BuffFrame_Enchant_OnUpdate
|
||||
function BuffFrame_Enchant_OnUpdate(elapsed)
|
||||
hookBuffFrame_Enchant_OnUpdate(elapsed)
|
||||
|
||||
-- return early without any weapon enchants
|
||||
local mh, _, _, oh = GetWeaponEnchantInfo()
|
||||
if not mh and not oh then return end
|
||||
|
||||
-- update weapon enchant 1
|
||||
local r, g, b = GetItemQualityColor(GetInventoryItemQuality("player", TempEnchant1:GetID()) or 1)
|
||||
TempEnchant1.ShaguTweaks_border:SetBackdropBorderColor(r,g,b,1)
|
||||
TempEnchant1Border:SetAlpha(0)
|
||||
|
||||
-- update weapon enchant 2
|
||||
local r, g, b = GetItemQualityColor(GetInventoryItemQuality("player", TempEnchant2:GetID()) or 1)
|
||||
TempEnchant2.ShaguTweaks_border:SetBackdropBorderColor(r,g,b,1)
|
||||
TempEnchant2Border:SetAlpha(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Loot Cursor"],
|
||||
description = T["Positions the loot window directly under your cursor so you can loot without moving your mouse."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["General"],
|
||||
enabled = true,
|
||||
order = 44,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local loot = CreateFrame("Frame", "ShaguTweaksLoot", LootFrame)
|
||||
|
||||
loot:SetScript("OnUpdate", function()
|
||||
if GetNumLootItems() == 0 then HideUIPanel(LootFrame) return end
|
||||
local x, y = GetCursorPosition()
|
||||
local s = LootFrame:GetEffectiveScale()
|
||||
x, y = x / s, y / s
|
||||
for i = 1, LOOTFRAME_NUMBUTTONS do
|
||||
local button = getglobal("LootButton"..i)
|
||||
if button:IsVisible() then
|
||||
if loot.last_button ~= button then
|
||||
local button_offset = (i-1) * button:GetHeight()
|
||||
LootFrame:ClearAllPoints()
|
||||
LootFrame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x - 40, y + 100 + button_offset)
|
||||
loot.last_button = button
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
loot:SetScript("OnShow", function()
|
||||
loot.last_button = nil
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,144 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Minimap Clean"],
|
||||
description = T["Hides minimap addon buttons automatically when the cursor leaves the minimap area."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
-- 🛡️ Liste noire : tout ce qu'on ne veut PAS toucher (trackers, blips, boutons systeme...)
|
||||
local ignoreList = {
|
||||
"MiniMapTrackingFrame",
|
||||
"MiniMapMeetingStoneFrame",
|
||||
"MiniMapMailFrame",
|
||||
"MiniMapPing",
|
||||
"MinimapBackdrop",
|
||||
"MinimapZoomIn",
|
||||
"MinimapZoomOut",
|
||||
"BookOfTracksFrame",
|
||||
"GatherNote",
|
||||
"FishingExtravaganzaMini",
|
||||
"MiniNotePOI",
|
||||
"RecipeRadarMinimapIcon",
|
||||
"FWGMinimapPOI",
|
||||
"MBB_MinimapButtonFrame",
|
||||
"MinimapButtonFrame", -- MBB peut nommer sa frame sans le prefixe MBB_ selon les versions
|
||||
"QuestieNote",
|
||||
"MetaMap",
|
||||
"LootLinkMinimapButton",
|
||||
"TimeManagerClockButton",
|
||||
"pfMiniMapPin",
|
||||
"Clock",
|
||||
"Timer",
|
||||
"GameTimeFrame",
|
||||
"MinimapToggleButton",
|
||||
"TWMinimapShopFrame",
|
||||
"LFT_Minimap"
|
||||
}
|
||||
|
||||
local function ShouldIgnore(name)
|
||||
if not name then return true end
|
||||
for _, needle in ipairs(ignoreList) do
|
||||
if string.find(name, needle, 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function IsAddonButton(child)
|
||||
local name = child:GetName()
|
||||
|
||||
if ShouldIgnore(name) then return false end
|
||||
|
||||
local hasClick = child:HasScript("OnClick") and child:GetScript("OnClick")
|
||||
local hasMouseUp = child:HasScript("OnMouseUp") and child:GetScript("OnMouseUp")
|
||||
local hasMouseDown = child:HasScript("OnMouseDown") and child:GetScript("OnMouseDown")
|
||||
|
||||
-- Parfois, le bouton cliquable est cache dans un enfant de la frame principale
|
||||
if not (hasClick or hasMouseUp or hasMouseDown) then
|
||||
for _, subchild in ipairs({child:GetChildren()}) do
|
||||
if subchild:HasScript("OnClick") and subchild:GetScript("OnClick") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return hasClick or hasMouseUp or hasMouseDown
|
||||
end
|
||||
|
||||
local function SetButtonsAlpha(alpha)
|
||||
local children = {Minimap:GetChildren()}
|
||||
for _, child in ipairs(children) do
|
||||
-- pcall ici : si un autre addon (MBB, etc.) est en train de detruire/
|
||||
-- reparenter sa frame au meme moment, un appel direct sur un objet
|
||||
-- dans un etat incoherent peut planter le client. On isole l'appel
|
||||
-- pour qu'une frame problematique ne fasse pas tomber tout le module.
|
||||
local ok, isButton = pcall(IsAddonButton, child)
|
||||
if ok and isButton then
|
||||
pcall(child.SetAlpha, child, alpha)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
-- Etat interne stocke sur le module -> propre a chaque enable
|
||||
self.isShown = true
|
||||
self.leaveTime = nil
|
||||
self.elapsed = 0
|
||||
|
||||
local HIDE_DELAY = 3
|
||||
local THROTTLE = 0.1
|
||||
local MARGIN = 30
|
||||
|
||||
self.frame = self.frame or CreateFrame("Frame")
|
||||
|
||||
self.frame:SetScript("OnUpdate", function()
|
||||
-- ⚠️ En vanilla 1.12, OnUpdate ne passe pas "elapsed" en parametre de fonction,
|
||||
-- il faut utiliser la variable globale arg1 !
|
||||
self.elapsed = self.elapsed + arg1
|
||||
if self.elapsed < THROTTLE then return end
|
||||
self.elapsed = 0
|
||||
|
||||
local x, y = GetCursorPosition()
|
||||
local scale = Minimap:GetEffectiveScale()
|
||||
local mx, my = x / scale, y / scale
|
||||
|
||||
local left = Minimap:GetLeft()
|
||||
local right = Minimap:GetRight()
|
||||
local bottom = Minimap:GetBottom()
|
||||
local top = Minimap:GetTop()
|
||||
|
||||
local isOver = left and mx >= (left - MARGIN) and mx <= (right + MARGIN)
|
||||
and my >= (bottom - MARGIN) and my <= (top + MARGIN)
|
||||
|
||||
if isOver then
|
||||
self.leaveTime = nil
|
||||
if not self.isShown then
|
||||
SetButtonsAlpha(1)
|
||||
self.isShown = true
|
||||
end
|
||||
else
|
||||
if self.isShown then
|
||||
if not self.leaveTime then
|
||||
self.leaveTime = GetTime()
|
||||
elseif GetTime() - self.leaveTime >= HIDE_DELAY then
|
||||
SetButtonsAlpha(0)
|
||||
self.isShown = false
|
||||
self.leaveTime = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
module.disable = function(self)
|
||||
if self.frame then
|
||||
self.frame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
-- On remet tous les boutons visibles quand on desactive le module
|
||||
SetButtonsAlpha(1)
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["MiniMap Clock"],
|
||||
description = T["Adds a small 24h clock to the mini map."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
MinimapClock = CreateFrame("Frame", "Clock", Minimap)
|
||||
MinimapClock:Hide()
|
||||
MinimapClock:SetFrameLevel(64)
|
||||
MinimapClock:SetPoint("BOTTOM", MinimapCluster, "BOTTOM", 8, 18)
|
||||
MinimapClock:SetWidth(50)
|
||||
MinimapClock:SetHeight(23)
|
||||
MinimapClock:SetBackdrop({
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
})
|
||||
MinimapClock:SetBackdropBorderColor(.9,.8,.5,1)
|
||||
MinimapClock:SetBackdropColor(.4,.4,.4,1)
|
||||
|
||||
module.enable = function(self)
|
||||
MinimapClock:Show()
|
||||
MinimapClock:EnableMouse(true)
|
||||
|
||||
MinimapClock.text = MinimapClock:CreateFontString("Status", "LOW", "GameFontNormal")
|
||||
MinimapClock.text:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE")
|
||||
MinimapClock.text:SetAllPoints(MinimapClock)
|
||||
MinimapClock.text:SetFontObject(GameFontWhite)
|
||||
MinimapClock:SetScript("OnUpdate", function()
|
||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + 1 end
|
||||
this.text:SetText(date("%H:%M"))
|
||||
end)
|
||||
|
||||
MinimapClock:SetScript("OnEnter", function()
|
||||
local h, m = GetGameTime()
|
||||
local servertime = string.format("%.2d:%.2d", h, m)
|
||||
local time = date("%H:%M")
|
||||
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:SetOwner(this, ANCHOR_BOTTOMLEFT)
|
||||
|
||||
GameTooltip:AddLine(T["Clock"])
|
||||
GameTooltip:AddDoubleLine(T["Localtime"], time, 1,1,1,1,1,1)
|
||||
GameTooltip:AddDoubleLine(T["Servertime"], servertime, 1,1,1,1,1,1)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
|
||||
MinimapClock:SetScript("OnLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["MiniMap Square"],
|
||||
description = T["Draw the mini map in a squared shape instead of a round one."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = nil,
|
||||
config = {
|
||||
["minimap.size"] = 144,
|
||||
},
|
||||
})
|
||||
module.enable = function(self)
|
||||
local size = module.config["minimap.size"]
|
||||
MinimapBorder:SetTexture(nil)
|
||||
Minimap:SetWidth(size)
|
||||
Minimap:SetHeight(size)
|
||||
Minimap:SetPoint("CENTER", MinimapCluster, "TOP", 9, -98)
|
||||
Minimap:SetMaskTexture("Interface\\BUTTONS\\WHITE8X8")
|
||||
Minimap.border = CreateFrame("Frame", nil, Minimap)
|
||||
Minimap.border:SetFrameStrata("BACKGROUND")
|
||||
Minimap.border:SetFrameLevel(1)
|
||||
Minimap.border:SetPoint("TOPLEFT", Minimap, "TOPLEFT", -3, 3)
|
||||
Minimap.border:SetPoint("BOTTOMRIGHT", Minimap, "BOTTOMRIGHT", 3, -3)
|
||||
Minimap.border:SetBackdrop({
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }})
|
||||
Minimap.border:SetBackdropBorderColor(.9,.8,.5,1)
|
||||
Minimap.border:SetBackdropColor(.4,.4,.4,1)
|
||||
|
||||
if _G.MinimapClock then
|
||||
if not self.clockOriginalPoint then
|
||||
local point, relativeTo, relativePoint, x, y = MinimapClock:GetPoint()
|
||||
self.clockOriginalPoint = { point, relativeTo, relativePoint, x, y }
|
||||
end
|
||||
|
||||
MinimapClock:ClearAllPoints()
|
||||
MinimapClock:SetPoint("TOP", Minimap, "BOTTOM", 0, -2)
|
||||
end
|
||||
end
|
||||
|
||||
module.disable = function(self)
|
||||
if _G.MinimapClock and self.clockOriginalPoint then
|
||||
MinimapClock:ClearAllPoints()
|
||||
MinimapClock:SetPoint(unpack(self.clockOriginalPoint))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["MiniMap Tweaks"],
|
||||
description = T["Hides unnecessary mini map buttons and allows to zoom using the mouse wheel."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
|
||||
-- hide daytime circle
|
||||
GameTimeFrame:Hide()
|
||||
GameTimeFrame:SetScript("OnShow", function() this:Hide() end)
|
||||
|
||||
-- hide minimap zone background
|
||||
MinimapBorderTop:Hide()
|
||||
MinimapToggleButton:Hide()
|
||||
MinimapZoneTextButton:SetPoint("CENTER", 7, 85)
|
||||
|
||||
-- hide zoom buttons and enable mousewheel
|
||||
MinimapZoomIn:Hide()
|
||||
MinimapZoomOut:Hide()
|
||||
Minimap:EnableMouseWheel(true)
|
||||
Minimap:SetScript("OnMouseWheel", function()
|
||||
if(arg1 > 0) then Minimap_ZoomIn() else Minimap_ZoomOut() end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,103 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Enlarged Minimap"],
|
||||
description = T["Increases the minimap size and shifts buff icons left to prevent overlap."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = nil,
|
||||
order = 73,
|
||||
config = {
|
||||
["minimap.scale"] = 1.2,
|
||||
}
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local scale = module.config["minimap.scale"]
|
||||
if scale < 1.0 then scale = 1.0 end
|
||||
if scale > 2.0 then scale = 2.0 end
|
||||
|
||||
MinimapCluster:SetScale(scale)
|
||||
|
||||
-- BuffFrame is anchored to UIParent TOPRIGHT/TOPRIGHT x=-205 y=-13 by vanilla.
|
||||
-- The C engine resets this after every PLAYER_AURAS_CHANGED event, overwriting
|
||||
-- any Lua SetPoint. The only reliable fix is to enforce on every frame via
|
||||
-- OnUpdate, which always runs after the C layout pass for that frame.
|
||||
-- We skip the call when the position is already correct to minimise overhead.
|
||||
|
||||
local extra = MinimapCluster:GetWidth() * (scale - 1.0)
|
||||
local targetX = -205 - extra
|
||||
local targetY = -13
|
||||
|
||||
-- BuffButton16 is the anchor for the player debuff row in vanilla 1.12.
|
||||
-- It sits just to the left of the minimap independently of BuffFrame.
|
||||
-- We calculate its target position to match the same leftward shift.
|
||||
local debuffX = -205 - extra
|
||||
local debuffY = -13 - 70 -- tuned value: one row below buffs without overlap
|
||||
|
||||
-- BuffButton8 ends the top buff row; it is not reanchored by the C engine
|
||||
-- so it can overlap the minimap when scaled up. Pin it one icon height
|
||||
-- above BuffButton16 to keep both rows aligned with the leftward shift.
|
||||
local buffRowX = -205 - extra
|
||||
local buffRowY = debuffY + 26 -- one icon height above the debuff row
|
||||
|
||||
-- TempEnchant1 sits to the right of BuffFrame, TempEnchant2 just below it.
|
||||
-- Both are re-anchored every frame to prevent the C engine from resetting them.
|
||||
|
||||
-- IMPORTANT: enable() can be called multiple times (reload UI, toggling the
|
||||
-- module in ShaguTweaks settings, expansion switch, etc). Without reusing a
|
||||
-- single persistent frame, every call created a brand new anonymous
|
||||
-- CreateFrame("Frame") with its own OnUpdate, and the old ones were never
|
||||
-- released -- they kept running forever in the background, stacking up and
|
||||
-- fighting each other over the same anchors every frame. That's the source
|
||||
-- of the micro-stutter. We now store the enforcer on the module and just
|
||||
-- refresh its OnUpdate closure (with the new target values) if it already
|
||||
-- exists, instead of creating a new frame.
|
||||
if not self.enforcer then
|
||||
self.enforcer = CreateFrame("Frame")
|
||||
end
|
||||
local enforcer = self.enforcer
|
||||
|
||||
enforcer:SetScript("OnUpdate", function()
|
||||
local _, _, _, x, y = BuffFrame:GetPoint(1)
|
||||
if x ~= targetX or y ~= targetY then
|
||||
BuffFrame:ClearAllPoints()
|
||||
BuffFrame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", targetX, targetY)
|
||||
end
|
||||
|
||||
if BuffButton16 then
|
||||
local _, _, _, dx, dy = BuffButton16:GetPoint(1)
|
||||
if dx ~= debuffX or dy ~= debuffY then
|
||||
BuffButton16:ClearAllPoints()
|
||||
BuffButton16:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", debuffX, debuffY)
|
||||
end
|
||||
end
|
||||
|
||||
-- BuffButton8 ends the top buff row; force it leftward to clear the minimap.
|
||||
if BuffButton8 then
|
||||
local _, _, _, bx, by = BuffButton8:GetPoint(1)
|
||||
if bx ~= buffRowX or by ~= buffRowY then
|
||||
BuffButton8:ClearAllPoints()
|
||||
BuffButton8:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", buffRowX, buffRowY)
|
||||
end
|
||||
end
|
||||
|
||||
-- TempEnchant1 to the right of BuffFrame, TempEnchant2 just below it.
|
||||
if TempEnchant1 then
|
||||
TempEnchant1:ClearAllPoints()
|
||||
TempEnchant1:SetPoint("TOPLEFT", BuffFrame, "TOPRIGHT", 5, 0)
|
||||
end
|
||||
|
||||
if TempEnchant2 and TempEnchant1 then
|
||||
TempEnchant2:ClearAllPoints()
|
||||
TempEnchant2:SetPoint("TOP", TempEnchant1, "BOTTOM", 0, -2)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
module.disable = function(self)
|
||||
if self.enforcer then
|
||||
self.enforcer:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,92 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Movable Unit Frames"],
|
||||
description = T["Player and Target unit frames can be moved while <Shift> and <Ctrl> are pressed together."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Unit Frames"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
local movables = { "PlayerFrame", "TargetFrame" }
|
||||
|
||||
module.enable = function(self)
|
||||
local unlocker = CreateFrame("Frame", nil, UIParent)
|
||||
unlocker:SetAllPoints(UIParent)
|
||||
|
||||
for _, frame in pairs(movables) do
|
||||
_G[frame]:SetClampedToScreen(true)
|
||||
end
|
||||
|
||||
unlocker.movable = nil
|
||||
unlocker:SetScript("OnUpdate", function()
|
||||
if IsShiftKeyDown() and IsControlKeyDown() then
|
||||
if not unlocker.movable then
|
||||
for _, frame in pairs(movables) do
|
||||
_G[frame]:SetUserPlaced(true)
|
||||
_G[frame]:SetMovable(true)
|
||||
_G[frame]:EnableMouse(true)
|
||||
_G[frame]:RegisterForDrag("LeftButton")
|
||||
_G[frame]:SetScript("OnDragStart", function() this:StartMoving() end)
|
||||
_G[frame]:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
|
||||
end
|
||||
|
||||
unlocker.movable = true
|
||||
unlocker.grid:Show()
|
||||
end
|
||||
elseif unlocker.movable then
|
||||
for _, frame in pairs(movables) do
|
||||
_G[frame]:SetScript("OnDragStart", function() end)
|
||||
_G[frame]:SetScript("OnDragStop", function() end)
|
||||
_G[frame]:StopMovingOrSizing()
|
||||
end
|
||||
|
||||
unlocker.movable = nil
|
||||
unlocker.grid:Hide()
|
||||
end
|
||||
end)
|
||||
|
||||
unlocker.grid = CreateFrame("Frame", nil, WorldFrame)
|
||||
unlocker.grid:SetAllPoints(WorldFrame)
|
||||
unlocker.grid:Hide()
|
||||
|
||||
local size = 1
|
||||
local line = {}
|
||||
|
||||
local width = GetScreenWidth()
|
||||
local height = GetScreenHeight()
|
||||
|
||||
local ratio = width / GetScreenHeight()
|
||||
local rheight = GetScreenHeight() * ratio
|
||||
|
||||
local wStep = width / 64
|
||||
local hStep = rheight / 64
|
||||
|
||||
-- vertical lines
|
||||
for i = 0, 64 do
|
||||
if i == 64 / 2 then
|
||||
line = unlocker.grid:CreateTexture(nil, 'BORDER')
|
||||
line:SetTexture(.8, .6, 0)
|
||||
else
|
||||
line = unlocker.grid:CreateTexture(nil, 'BACKGROUND')
|
||||
line:SetTexture(0, 0, 0, .2)
|
||||
end
|
||||
line:SetPoint("TOPLEFT", unlocker.grid, "TOPLEFT", i*wStep - (size/2), 0)
|
||||
line:SetPoint('BOTTOMRIGHT', unlocker.grid, 'BOTTOMLEFT', i*wStep + (size/2), 0)
|
||||
end
|
||||
|
||||
-- horizontal lines
|
||||
for i = 1, floor(height/hStep) do
|
||||
if i == floor(height/hStep / 2) then
|
||||
line = unlocker.grid:CreateTexture(nil, 'BORDER')
|
||||
line:SetTexture(.8, .6, 0)
|
||||
else
|
||||
line = unlocker.grid:CreateTexture(nil, 'BACKGROUND')
|
||||
line:SetTexture(0, 0, 0, .2)
|
||||
end
|
||||
|
||||
line:SetPoint("TOPLEFT", unlocker.grid, "TOPLEFT", 0, -(i*hStep) + (size/2))
|
||||
line:SetPoint('BOTTOMRIGHT', unlocker.grid, 'TOPRIGHT', 0, -(i*hStep + size/2))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,118 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local UnitCastingInfo = ShaguTweaks.UnitCastingInfo
|
||||
local UnitChannelInfo = ShaguTweaks.UnitChannelInfo
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Nameplate Castbar"],
|
||||
description = T["Adds a castbar to the nameplate based on combat log estimations."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = false },
|
||||
category = T["Nameplates"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
if ShaguPlates then return end
|
||||
|
||||
local backdrop = {
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 12,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
}
|
||||
|
||||
local function create_castbar(plate)
|
||||
-- create the castbar
|
||||
plate.castbar = CreateFrame("StatusBar", nil, plate)
|
||||
plate.castbar:SetPoint("BOTTOM", plate, "BOTTOM", 8, -11)
|
||||
plate.castbar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
|
||||
plate.castbar:SetStatusBarColor(1, .8, 0, 1)
|
||||
plate.castbar:SetWidth(plate:GetWidth() - 22)
|
||||
plate.castbar:SetHeight(10)
|
||||
|
||||
-- create the spell icon
|
||||
plate.castbar.texture = CreateFrame("Frame", nil, plate.castbar)
|
||||
plate.castbar.texture:SetPoint("RIGHT", plate.castbar, "LEFT", 0, 0)
|
||||
plate.castbar.texture:SetHeight(18)
|
||||
plate.castbar.texture:SetWidth(18)
|
||||
plate.castbar.texture.icon = plate.castbar.texture:CreateTexture(nil, "BACKGROUND")
|
||||
plate.castbar.texture.icon:SetPoint("CENTER", 0, 0)
|
||||
plate.castbar.texture.icon:SetWidth(12)
|
||||
plate.castbar.texture.icon:SetHeight(12)
|
||||
plate.castbar.texture:SetBackdrop(backdrop)
|
||||
plate.castbar.texture:SetBackdropBorderColor(1,.8,0)
|
||||
|
||||
-- castbar background
|
||||
plate.castbar.bg = plate.castbar:CreateTexture(nil, "BACKGROUND")
|
||||
plate.castbar.bg:SetTexture("Interface\\TARGETINGFRAME\\UI-StatusBar")
|
||||
plate.castbar.bg:SetVertexColor(.1, .1, 0, .8)
|
||||
plate.castbar.bg:SetAllPoints(true)
|
||||
|
||||
-- castbar spark
|
||||
plate.castbar.spark = plate.castbar:CreateTexture(nil, "OVERLAY")
|
||||
plate.castbar.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||
plate.castbar.spark:SetWidth(20)
|
||||
plate.castbar.spark:SetHeight(20)
|
||||
plate.castbar.spark:SetBlendMode("ADD")
|
||||
|
||||
-- castbar border
|
||||
plate.castbar.backdrop = CreateFrame("Frame", nil, plate.castbar)
|
||||
plate.castbar.backdrop:SetFrameLevel(plate.castbar:GetFrameLevel())
|
||||
plate.castbar.backdrop:SetPoint("TOPLEFT", plate.castbar, "TOPLEFT", -3, 3)
|
||||
plate.castbar.backdrop:SetPoint("BOTTOMRIGHT", plate.castbar, "BOTTOMRIGHT", 3, -3)
|
||||
plate.castbar.backdrop:SetBackdrop(backdrop)
|
||||
plate.castbar.backdrop:SetBackdropBorderColor(1,.8,0)
|
||||
|
||||
-- castbar spellname
|
||||
plate.castbar.text = plate.castbar:CreateFontString(nil, "HIGH", "GameFontWhite")
|
||||
plate.castbar.text:SetPoint("CENTER", plate.castbar, "CENTER", 0, 0)
|
||||
local font, size, opts = plate.castbar.text:GetFont()
|
||||
plate.castbar.text:SetFont(font, size - 3, "THINOUTLINE")
|
||||
|
||||
-- hide castbar by default
|
||||
plate.castbar:Hide()
|
||||
end
|
||||
|
||||
-- scan for casts and show castbar
|
||||
table.insert(ShaguTweaks.libnameplate.OnUpdate, function()
|
||||
-- create castbar if not existing
|
||||
if not this.castbar then create_castbar(this) end
|
||||
|
||||
local name = this.name:GetText()
|
||||
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(name)
|
||||
|
||||
-- read enemy casts from SuperWoW if enabled
|
||||
if ShaguTweaks.superwow_active then
|
||||
cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(this:GetName(1))
|
||||
end
|
||||
|
||||
if cast then
|
||||
local duration = endTime - startTime
|
||||
local max = duration / 1000
|
||||
local cur = GetTime() - startTime / 1000
|
||||
|
||||
cur = cur > max and max or cur
|
||||
cur = cur < 0 and 0 or cur
|
||||
|
||||
this.castbar:Show()
|
||||
this.castbar:SetMinMaxValues(0, duration / 1000)
|
||||
this.castbar:SetValue(cur)
|
||||
|
||||
local percent = cur / max
|
||||
local x = this.castbar:GetWidth()*percent
|
||||
this.castbar.spark:SetPoint("CENTER", this.castbar, "LEFT", x, 0)
|
||||
|
||||
this.castbar.text:SetText(cast)
|
||||
|
||||
if texture then
|
||||
this.castbar.texture.icon:SetTexture(texture)
|
||||
this.castbar.texture.icon:Show()
|
||||
else
|
||||
this.castbar.texture.icon:Hide()
|
||||
end
|
||||
|
||||
this.castbar:SetAlpha(this:GetAlpha())
|
||||
else
|
||||
this.castbar:Hide()
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local GetUnitData = ShaguTweaks.GetUnitData
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Nameplate Class Colors"],
|
||||
description = T["Changes the nameplate health bar color to the class color."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Nameplates"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
if ShaguPlates then return end
|
||||
|
||||
table.insert(ShaguTweaks.libnameplate.OnUpdate, function()
|
||||
local name = this.name:GetText()
|
||||
local class, _, elite, player = GetUnitData(name, true)
|
||||
if class and player then
|
||||
local color = RAID_CLASS_COLORS[class] or { r = .5, g = .5, b = .5, a = 1 }
|
||||
this.healthbar:SetStatusBarColor(color.r, color.g, color.b, 1)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Nameplate Scale"],
|
||||
description = T["Makes all nameplates honor the UI-Scale setting."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Nameplates"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
if ShaguPlates then return end
|
||||
|
||||
table.insert(ShaguTweaks.libnameplate.OnInit, function(plate)
|
||||
local owidth = plate:GetWidth()
|
||||
local oheight = plate:GetHeight()
|
||||
|
||||
-- create new plate
|
||||
local new = CreateFrame("Frame", nil, plate)
|
||||
plate.new = new
|
||||
|
||||
new:SetScale(UIParent:GetScale())
|
||||
new:SetAllPoints(plate)
|
||||
new.plate = plate
|
||||
|
||||
plate.healthbar:SetParent(new)
|
||||
plate.healthbar:SetFrameLevel(1)
|
||||
|
||||
plate:SetWidth(owidth*UIParent:GetScale())
|
||||
plate:SetHeight(oheight*UIParent:GetScale())
|
||||
|
||||
for i, object in pairs({plate:GetRegions()}) do
|
||||
object:SetParent(new)
|
||||
|
||||
-- adjust level icon position
|
||||
if ShaguTweaks:GetExpansion() == "vanilla" and i == 5 or i == 7 then
|
||||
object:SetPoint("BOTTOMRIGHT", -6, 3)
|
||||
end
|
||||
end
|
||||
|
||||
new:SetScript("OnShow", function()
|
||||
-- adjust sizes
|
||||
this:SetScale(UIParent:GetScale())
|
||||
this.plate:SetWidth(owidth*UIParent:GetScale())
|
||||
this.plate:SetHeight(oheight*UIParent:GetScale())
|
||||
end)
|
||||
end)
|
||||
|
||||
table.insert(ShaguTweaks.libnameplate.OnUpdate, function()
|
||||
this.new:SetAlpha(this:GetAlpha())
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,62 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["No Toggle Auto-Attack"],
|
||||
description = T["Keeps Auto Attack, Auto Shot, and Shoot active when re-pressed, preventing accidental cancellation."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["General"],
|
||||
enabled = true,
|
||||
order = 12,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local attacking, shooting
|
||||
|
||||
local combatFrame = CreateFrame("Frame")
|
||||
combatFrame:RegisterEvent("PLAYER_ENTER_COMBAT")
|
||||
combatFrame:RegisterEvent("PLAYER_LEAVE_COMBAT")
|
||||
combatFrame:SetScript("OnEvent", function()
|
||||
attacking = event == "PLAYER_ENTER_COMBAT"
|
||||
end)
|
||||
|
||||
local shootFrame = CreateFrame("Frame")
|
||||
shootFrame:RegisterEvent("START_AUTOREPEAT_SPELL")
|
||||
shootFrame:RegisterEvent("STOP_AUTOREPEAT_SPELL")
|
||||
shootFrame:SetScript("OnEvent", function()
|
||||
shooting = event == "START_AUTOREPEAT_SPELL"
|
||||
end)
|
||||
|
||||
local function active(name)
|
||||
if not name then return false end
|
||||
name = strlower(name)
|
||||
return (name == "attack" and attacking) or
|
||||
((name == "auto shot" or name == "shoot") and shooting)
|
||||
end
|
||||
|
||||
local origCastSpell = CastSpell
|
||||
function _G.CastSpell(index, booktype)
|
||||
if active(GetSpellName(index, booktype)) then return end
|
||||
return origCastSpell(index, booktype)
|
||||
end
|
||||
|
||||
local origCastSpellByName = CastSpellByName
|
||||
function _G.CastSpellByName(text, onself)
|
||||
if active(text) then return end
|
||||
return origCastSpellByName(text, onself)
|
||||
end
|
||||
|
||||
local tt = CreateFrame("GameTooltip", "ShaguTweaksNoToggleTT", nil, "GameTooltipTemplate")
|
||||
tt:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
|
||||
local origUseAction = UseAction
|
||||
function _G.UseAction(slot, clicked, onself)
|
||||
if HasAction(slot) and not GetActionText(slot) then
|
||||
tt:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
tt:SetAction(slot)
|
||||
local label = _G["ShaguTweaksNoToggleTTTextLeft1"]
|
||||
if label and active(label:GetText()) then return end
|
||||
end
|
||||
return origUseAction(slot, clicked, onself)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,172 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local hooksecurefunc = hooksecurefunc or ShaguTweaks.hooksecurefunc
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Reduced Actionbar Size"],
|
||||
description = T["Reduces the actionbar size by removing several items such as the bag panel and microbar"],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
local function ReplaceBag()
|
||||
local id = this:GetID()
|
||||
if id ~= 0 then
|
||||
id = ContainerIDToInventoryID(id)
|
||||
if CursorHasItem() then
|
||||
PutItemInBag(id)
|
||||
else
|
||||
PickupBagFromSlot(id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
-- general function to hide textures and frames
|
||||
local function hide(frame, texture)
|
||||
if not frame then return end
|
||||
|
||||
if texture and texture == 1 and frame.SetTexture then
|
||||
frame:SetTexture("")
|
||||
elseif texture and texture == 2 and frame.SetNormalTexture then
|
||||
frame:SetNormalTexture("")
|
||||
else
|
||||
frame:ClearAllPoints()
|
||||
frame.Show = function() return end
|
||||
frame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- frames that shall be hidden
|
||||
local frames = {
|
||||
-- actionbar paging
|
||||
MainMenuBarPageNumber, ActionBarUpButton, ActionBarDownButton,
|
||||
-- xp and reputation bar
|
||||
MainMenuXPBarTexture2, MainMenuXPBarTexture3,
|
||||
ReputationWatchBarTexture2, ReputationWatchBarTexture3,
|
||||
-- actionbar backgrounds
|
||||
MainMenuBarTexture2, MainMenuBarTexture3,
|
||||
MainMenuMaxLevelBar2, MainMenuMaxLevelBar3,
|
||||
-- micro button panel
|
||||
CharacterMicroButton, SpellbookMicroButton, TalentMicroButton,
|
||||
QuestLogMicroButton, MainMenuMicroButton, SocialsMicroButton,
|
||||
WorldMapMicroButton, MainMenuBarPerformanceBarFrame, HelpMicroButton,
|
||||
-- bag panel
|
||||
CharacterBag3Slot, CharacterBag2Slot, CharacterBag1Slot,
|
||||
CharacterBag0Slot, MainMenuBarBackpackButton, KeyRingButton,
|
||||
-- shapeshift backgrounds
|
||||
ShapeshiftBarLeft, ShapeshiftBarMiddle, ShapeshiftBarRight,
|
||||
}
|
||||
|
||||
-- textures that shall be set empty
|
||||
local textures = {
|
||||
ReputationWatchBarTexture2, ReputationWatchBarTexture3,
|
||||
ReputationXPBarTexture2, ReputationXPBarTexture3,
|
||||
SlidingActionBarTexture0, SlidingActionBarTexture1,
|
||||
}
|
||||
|
||||
-- button textures that shall be set empty
|
||||
local normtextures = {
|
||||
ShapeshiftButton1, ShapeshiftButton2,
|
||||
ShapeshiftButton3, ShapeshiftButton4,
|
||||
ShapeshiftButton5, ShapeshiftButton6,
|
||||
ShapeshiftButton7, ShapeshiftButton8,
|
||||
ShapeshiftButton9, ShapeshiftButton10,
|
||||
ShapeshiftButton11, ShapeshiftButton12,
|
||||
}
|
||||
|
||||
-- elements that shall be resized to 511px
|
||||
local resizes = {
|
||||
MainMenuBar, MainMenuExpBar, MainMenuBarMaxLevelBar,
|
||||
ReputationWatchBar, ReputationWatchStatusBar,
|
||||
}
|
||||
|
||||
-- hide frames
|
||||
for id, frame in pairs(frames) do hide(frame) end
|
||||
|
||||
-- clear textures
|
||||
for id, frame in pairs(textures) do hide(frame, 1) end
|
||||
for id, frame in pairs(normtextures) do hide(frame, 2) end
|
||||
|
||||
-- resize actionbar
|
||||
for id, frame in pairs(resizes) do frame:SetWidth(511) end
|
||||
|
||||
-- experience bar
|
||||
MainMenuXPBarTexture0:SetPoint("LEFT", MainMenuExpBar, "LEFT")
|
||||
MainMenuXPBarTexture1:SetPoint("RIGHT", MainMenuExpBar, "RIGHT")
|
||||
|
||||
-- reputation bar
|
||||
ReputationWatchBar:SetPoint("BOTTOM", MainMenuExpBar, "TOP", 0, 0)
|
||||
ReputationWatchBarTexture0:SetPoint("LEFT", ReputationWatchBar, "LEFT")
|
||||
ReputationWatchBarTexture1:SetPoint("RIGHT", ReputationWatchBar, "RIGHT")
|
||||
|
||||
-- move menubar texture background
|
||||
MainMenuMaxLevelBar0:SetPoint("LEFT", MainMenuBarArtFrame, "LEFT")
|
||||
MainMenuBarTexture0:SetPoint("LEFT", MainMenuBarArtFrame, "LEFT")
|
||||
MainMenuBarTexture1:SetPoint("RIGHT", MainMenuBarArtFrame, "RIGHT")
|
||||
|
||||
-- move gryphon textures
|
||||
MainMenuBarLeftEndCap:SetPoint("RIGHT", MainMenuBarArtFrame, "LEFT", 29.5, 0)
|
||||
MainMenuBarRightEndCap:SetPoint("LEFT", MainMenuBarArtFrame, "RIGHT", -31.5, 0)
|
||||
|
||||
-- move MultiBarBottomRight ontop of MultiBarBottomLeft
|
||||
MultiBarBottomRight:ClearAllPoints()
|
||||
MultiBarBottomRight:SetPoint("BOTTOM", MultiBarBottomLeft, "TOP", 0, 5)
|
||||
|
||||
-- reload custom frame positions after original frame manage runs
|
||||
local hookUIParent_ManageFramePositions = UIParent_ManageFramePositions
|
||||
UIParent_ManageFramePositions = function(a1, a2, a3)
|
||||
-- run original function
|
||||
hookUIParent_ManageFramePositions(a1, a2, a3)
|
||||
|
||||
-- move top actionbar if xp or reputation is tracked
|
||||
MultiBarBottomLeft:ClearAllPoints()
|
||||
if MainMenuExpBar:IsVisible() or ReputationWatchBar:IsVisible() then
|
||||
local anchor = GetWatchedFactionInfo() and ReputationWatchBar or MainMenuExpBar
|
||||
MultiBarBottomLeft:SetPoint("BOTTOM", anchor, "TOP", 2, 3)
|
||||
else
|
||||
MultiBarBottomLeft:SetPoint("BOTTOM", MainMenuBar, "TOP", 2, -3)
|
||||
end
|
||||
|
||||
-- move pet actionbar above other actionbars
|
||||
PetActionBarFrame:ClearAllPoints()
|
||||
local anchor = MainMenuBarArtFrame
|
||||
anchor = MultiBarBottomLeft:IsVisible() and MultiBarBottomLeft or anchor
|
||||
anchor = MultiBarBottomRight:IsVisible() and MultiBarBottomRight or anchor
|
||||
anchor = ShapeshiftBarFrame:IsVisible() and ShapeshiftBarFrame or anchor
|
||||
PetActionBarFrame:SetPoint("BOTTOMLEFT", anchor, "TOPLEFT", 20, 4)
|
||||
|
||||
-- ShapeshiftBarFrame
|
||||
ShapeshiftBarFrame:ClearAllPoints()
|
||||
local offset = 0
|
||||
local anchor = ActionButton1
|
||||
anchor = MultiBarBottomLeft:IsVisible() and MultiBarBottomLeft or anchor
|
||||
anchor = MultiBarBottomRight:IsVisible() and MultiBarBottomRight or anchor
|
||||
|
||||
offset = anchor == ActionButton1 and ( MainMenuExpBar:IsVisible() or ReputationWatchBar:IsVisible() ) and 6 or 0
|
||||
offset = anchor == ActionButton1 and offset + 4 or offset
|
||||
ShapeshiftBarFrame:SetPoint("BOTTOMLEFT", anchor, "TOPLEFT", 8, 4 + offset)
|
||||
|
||||
-- move castbar ontop of other bars
|
||||
local anchor = MainMenuBarArtFrame
|
||||
anchor = MultiBarBottomLeft:IsVisible() and MultiBarBottomLeft or anchor
|
||||
anchor = MultiBarBottomRight:IsVisible() and MultiBarBottomRight or anchor
|
||||
local pet_offset = PetActionBarFrame:IsVisible() and 40 or 0
|
||||
local stance_offset = ShapeshiftBarFrame:IsVisible() and 40 or 0
|
||||
CastingBarFrame:SetPoint("BOTTOM", anchor, "TOP", 0, 10 + pet_offset + stance_offset)
|
||||
end
|
||||
|
||||
-- restore frame positions when UIParent becomes visible
|
||||
local restore = CreateFrame("Frame", nil, UIParent)
|
||||
restore:SetScript("OnShow", UIParent_ManageFramePositions)
|
||||
|
||||
-- enforce pet actionbar offset after pet actionbar becomes visible
|
||||
hooksecurefunc("ShowPetActionBar", function()
|
||||
PETACTIONBAR_XPOS = 36
|
||||
end)
|
||||
|
||||
-- enable picking up/replacing bags by clicking on the container frame portrait
|
||||
for i = 1, 5 do
|
||||
_G["ContainerFrame" .. i .. "PortraitButton"]:SetScript("OnClick", ReplaceBag)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,175 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local GetItemIDFromLink = ShaguTweaks.GetItemIDFromLink
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Sell Junk"],
|
||||
description = T["Adds a “Sell Junk” button to every merchant window, that sells all grey items."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Tooltip & Items"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
local processed = {}
|
||||
|
||||
local function CreateGoldString(money)
|
||||
if type(money) ~= "number" then return "-" end
|
||||
|
||||
local gold = floor(money/ 100 / 100)
|
||||
local silver = floor(mod((money/100),100))
|
||||
local copper = floor(mod(money,100))
|
||||
|
||||
local string = ""
|
||||
if gold > 0 then string = string .. "|cffffffff" .. gold .. "|cffffd700g" end
|
||||
if silver > 0 or gold > 0 then string = string .. "|cffffffff " .. silver .. "|cffc7c7cfs" end
|
||||
string = string .. "|cffffffff " .. copper .. "|cffeda55fc"
|
||||
|
||||
return string
|
||||
end
|
||||
|
||||
local function HasGreyItems()
|
||||
for bag = 0, 4, 1 do
|
||||
for slot = 1, GetContainerNumSlots(bag), 1 do
|
||||
local name = GetContainerItemLink(bag,slot)
|
||||
if name and string.find(name,"ff9d9d9d") then return true end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function GetNextGreyItem()
|
||||
for bag = 0, 4, 1 do
|
||||
for slot = 1, GetContainerNumSlots(bag), 1 do
|
||||
local name = GetContainerItemLink(bag,slot)
|
||||
if name and string.find(name,"ff9d9d9d") and not processed[bag.."x"..slot] then
|
||||
processed[bag.."x"..slot] = true
|
||||
return bag, slot
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
local autovendor = CreateFrame("Frame", nil, nil)
|
||||
autovendor:Hide()
|
||||
|
||||
autovendor:SetScript("OnShow", function()
|
||||
processed = {}
|
||||
this.price = 0
|
||||
this.count = 0
|
||||
end)
|
||||
|
||||
autovendor:SetScript("OnHide", function()
|
||||
if this.count > 0 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(T["Your vendor trash has been sold and you earned"] .. " " .. CreateGoldString(this.price))
|
||||
end
|
||||
end)
|
||||
|
||||
autovendor:SetScript("OnUpdate", function()
|
||||
-- throttle to to one item per .1 second
|
||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
|
||||
|
||||
-- scan for the next grey item
|
||||
local bag, slot = GetNextGreyItem()
|
||||
if not bag or not slot then
|
||||
this:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
-- double check to only sell grey
|
||||
local name = GetContainerItemLink(bag,slot)
|
||||
if not name or not string.find(name,"ff9d9d9d") then
|
||||
return
|
||||
end
|
||||
|
||||
-- get value
|
||||
local _, icount = GetContainerItemInfo(bag, slot)
|
||||
local itemID = GetItemIDFromLink(GetContainerItemLink(bag, slot))
|
||||
local price = ShaguTweaks.SellValueDB[itemID] or 0
|
||||
if this.price then
|
||||
this.price = this.price + ( price * ( icount or 1 ) )
|
||||
this.count = this.count + 1
|
||||
end
|
||||
|
||||
-- abort if the merchant window disappeared
|
||||
if not this.merchant then return end
|
||||
|
||||
-- clear cursor and sell the item
|
||||
ClearCursor()
|
||||
UseContainerItem(bag, slot)
|
||||
end)
|
||||
|
||||
autovendor:RegisterEvent("MERCHANT_SHOW")
|
||||
autovendor:RegisterEvent("MERCHANT_CLOSED")
|
||||
autovendor:RegisterEvent("MERCHANT_UPDATE")
|
||||
autovendor:SetScript("OnEvent", function()
|
||||
autovendor.button:Update()
|
||||
|
||||
if event == "MERCHANT_CLOSED" then
|
||||
autovendor.merchant = nil
|
||||
autovendor:Hide()
|
||||
elseif event == "MERCHANT_SHOW" then
|
||||
autovendor.merchant = true
|
||||
autovendor.button:Show()
|
||||
end
|
||||
|
||||
MerchantRepairText:SetText("")
|
||||
if MerchantRepairItemButton:IsShown() then
|
||||
autovendor.button:ClearAllPoints()
|
||||
autovendor.button:SetPoint("RIGHT", MerchantRepairItemButton, "LEFT", -4, 0)
|
||||
else
|
||||
autovendor.button:ClearAllPoints()
|
||||
autovendor.button:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -14, 0)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Setup Autosell button
|
||||
autovendor.button = CreateFrame("Button", nil, MerchantFrame)
|
||||
autovendor.button:SetWidth(36)
|
||||
autovendor.button:SetHeight(36)
|
||||
autovendor.button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
|
||||
autovendor.button:SetNormalTexture("Interface\\Icons\\Spell_Shadow_SacrificialShield")
|
||||
autovendor.button:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetText(T["Sell Grey Items"])
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
|
||||
autovendor.button:SetScript("OnLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
|
||||
autovendor.button:SetScript("OnClick", function()
|
||||
autovendor:Show()
|
||||
end)
|
||||
|
||||
autovendor.button.Update = function()
|
||||
if not autovendor:IsVisible() then
|
||||
if HasGreyItems() then
|
||||
autovendor.button:Enable()
|
||||
autovendor.button:GetNormalTexture():SetDesaturated(false)
|
||||
else
|
||||
autovendor.button:Disable()
|
||||
autovendor.button:GetNormalTexture():SetDesaturated(true)
|
||||
end
|
||||
else
|
||||
autovendor.button:Disable()
|
||||
autovendor.button:GetNormalTexture():SetDesaturated(true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Hook MerchantFrame_Update
|
||||
if not HookMerchantFrame_Update then
|
||||
local HookMerchantFrame_Update = MerchantFrame_Update
|
||||
function _G.MerchantFrame_Update()
|
||||
if MerchantFrame.selectedTab == 1 then
|
||||
autovendor.button:Show()
|
||||
else
|
||||
autovendor.button:Hide()
|
||||
end
|
||||
HookMerchantFrame_Update()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,228 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local L = ShaguTweaks.L
|
||||
local gfind = string.gmatch or string.gfind
|
||||
local GetUnitData = ShaguTweaks.GetUnitData
|
||||
local hooksecurefunc = ShaguTweaks.hooksecurefunc
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
local cmatch = ShaguTweaks.cmatch
|
||||
local rgbhex = ShaguTweaks.rgbhex
|
||||
local strsplit = ShaguTweaks.strsplit
|
||||
local friendinfo = gsub(gsub(FRIENDS_LEVEL_TEMPLATE,"%%s","%%s %%s"),"%%d","%%s")
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Social Colors"],
|
||||
description = T["Show class colors in Who, Guild, Friends and Chat."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Social & Chat"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
do -- add class colors to chat
|
||||
for i=1,NUM_CHAT_WINDOWS do
|
||||
if _G["ChatFrame"..i] and not _G["ChatFrame"..i].HookAddMessageColor and not Prat then
|
||||
_G["ChatFrame"..i].HookAddMessageColor = _G["ChatFrame"..i].AddMessage
|
||||
_G["ChatFrame"..i].AddMessage = function(frame, text, a1, a2, a3, a4, a5)
|
||||
if text then
|
||||
for name in gfind(text, "|Hplayer:(.-)|h") do
|
||||
local real = strsplit(":", name)
|
||||
local class = GetUnitData(real)
|
||||
if class and class ~= UNKNOWN then
|
||||
local color = rgbhex(RAID_CLASS_COLORS[class])
|
||||
text = string.gsub(text,
|
||||
"|Hplayer:"..name.."|h%["..real.."%]|h(.-:-)",
|
||||
"|r["..color.."|Hplayer:"..name.."|h"..color..real.."|h|r]|r%1")
|
||||
end
|
||||
end
|
||||
end
|
||||
_G["ChatFrame"..i].HookAddMessageColor(frame, text, a1, a2, a3, a4, a5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ShaguTweaks_cache = ShaguTweaks_cache or {}
|
||||
ShaguTweaks_cache["players"] = ShaguTweaks_cache["players"] or {}
|
||||
|
||||
local playerdb = ShaguTweaks_cache["players"]
|
||||
local socialmod = CreateFrame("Frame", "ShaguTweaksSocialMod", UIParent)
|
||||
socialmod:RegisterEvent("CHAT_MSG_SYSTEM")
|
||||
socialmod:SetScript("OnEvent", function()
|
||||
local name = cmatch(arg1, _G.ERR_FRIEND_ONLINE_SS)
|
||||
name = cmatch(arg1, _G.ERR_FRIEND_OFFLINE_S)
|
||||
if name and playerdb[name] and playerdb[name].cname then
|
||||
playerdb[name].lastseen = date("%a %d-%b-%Y")
|
||||
end
|
||||
end)
|
||||
|
||||
do -- add colors to guild list
|
||||
hooksecurefunc("GuildStatus_Update", function()
|
||||
local playerzone = GetRealZoneText()
|
||||
local off = FauxScrollFrame_GetOffset(GuildListScrollFrame)
|
||||
local _, _, playerrankindex = GetGuildInfo("player")
|
||||
|
||||
for i=1, GUILDMEMBERS_TO_DISPLAY, 1 do
|
||||
local name, _, rankindex, level, class, zone, _, _, online = GetGuildRosterInfo(off + i)
|
||||
|
||||
class = L["class"][class]
|
||||
|
||||
if name then
|
||||
if class then
|
||||
local color = RAID_CLASS_COLORS[class]
|
||||
if online then
|
||||
_G["GuildFrameButton"..i.."Name"]:SetTextColor(color.r,color.g,color.b,1)
|
||||
_G["GuildFrameButton"..i.."Class"]:SetTextColor(color.r,color.g,color.b,1)
|
||||
_G["GuildFrameGuildStatusButton"..i.."Name"]:SetTextColor(color.r,color.g,color.b,1)
|
||||
else
|
||||
_G["GuildFrameButton"..i.."Name"]:SetTextColor(color.r,color.g,color.b,.5)
|
||||
_G["GuildFrameButton"..i.."Class"]:SetTextColor(color.r,color.g,color.b,.5)
|
||||
_G["GuildFrameGuildStatusButton"..i.."Name"]:SetTextColor(color.r,color.g,color.b,.5)
|
||||
end
|
||||
end
|
||||
|
||||
if level then
|
||||
local color = GetDifficultyColor(level)
|
||||
if online then
|
||||
_G["GuildFrameButton"..i.."Level"]:SetTextColor(color.r + .2, color.g + .2, color.b + .2, 1)
|
||||
else
|
||||
_G["GuildFrameButton"..i.."Level"]:SetTextColor(color.r + .2, color.g + .2, color.b + .2, .5)
|
||||
end
|
||||
end
|
||||
|
||||
if zone and zone == playerzone then
|
||||
if online then
|
||||
_G["GuildFrameButton"..i.."Zone"]:SetTextColor(.5, 1, 1, 1)
|
||||
else
|
||||
_G["GuildFrameButton"..i.."Zone"]:SetTextColor(.5, 1, 1, .5)
|
||||
end
|
||||
end
|
||||
|
||||
if rankindex and rankindex == playerrankindex then
|
||||
if online then
|
||||
_G["GuildFrameGuildStatusButton"..i.."Rank"]:SetTextColor(.5, 1, 1, 1)
|
||||
else
|
||||
_G["GuildFrameGuildStatusButton"..i.."Rank"]:SetTextColor(.5, 1, 1, .5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
do -- add colors to friend list
|
||||
local FRIENDS_NAME_LOCATION = GetExpansion() == "vanilla" and "ButtonTextNameLocation" or "ButtonTextLocation"
|
||||
hooksecurefunc("FriendsList_Update", function()
|
||||
if GetNumFriends() == 0 then return end
|
||||
|
||||
local playerzone = GetRealZoneText()
|
||||
local off = FauxScrollFrame_GetOffset(FriendsFrameFriendsScrollFrame)
|
||||
|
||||
for i=1, FRIENDS_TO_DISPLAY do
|
||||
local name, level, class, zone, connected, status = GetFriendInfo(off + i)
|
||||
if not name or name == _G.UNKNOWN then break end
|
||||
local friendName = _G["FriendsFrameFriendButton"..i.."ButtonTextName"]
|
||||
local friendLoc = _G["FriendsFrameFriendButton"..i..FRIENDS_NAME_LOCATION]
|
||||
local friendInfo = _G["FriendsFrameFriendButton"..i.."ButtonTextInfo"]
|
||||
local caption = friendName or friendLoc
|
||||
|
||||
if connected then
|
||||
if not class or class == _G.UNKNOWN then break end
|
||||
local ccolor = RAID_CLASS_COLORS[L["class"][class]] or { 1, 1, 1 }
|
||||
local lcolor = GetDifficultyColor(tonumber(level)) or { 1, 1, 1 }
|
||||
|
||||
zone = ( zone == playerzone and "|cffffffff" or "|cffcccccc" ) .. zone .. "|r"
|
||||
local cname = rgbhex(ccolor) .. name .. "|r"
|
||||
local clevel = rgbhex(lcolor) .. level .. "|r"
|
||||
|
||||
if playerdb[name] then
|
||||
playerdb[name].lastseen = date("%a %d-%b-%Y")
|
||||
playerdb[name].cname = cname
|
||||
playerdb[name].clevel = clevel
|
||||
playerdb[name].cclass = ccolor
|
||||
end
|
||||
|
||||
if friendName then
|
||||
friendName:SetText(cname)
|
||||
friendLoc:SetText(format(TEXT(FRIENDS_LIST_TEMPLATE), zone, status))
|
||||
else
|
||||
friendLoc:SetText(format(TEXT(FRIENDS_LIST_TEMPLATE), cname, zone, status))
|
||||
end
|
||||
|
||||
friendInfo:SetText(format(TEXT(friendinfo), clevel, class, ""))
|
||||
caption:SetVertexColor(1,1,1,.9)
|
||||
friendInfo:SetVertexColor(1,1,1,.9)
|
||||
else
|
||||
if playerdb[name] and playerdb[name].cname and playerdb[name].clevel and playerdb[name].lastseen then
|
||||
caption:SetText(format(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), playerdb[name].cname))
|
||||
friendInfo:SetText(format(TEXT(friendinfo), playerdb[name].clevel, playerdb[name].lastseen, ""))
|
||||
else
|
||||
caption:SetText(format(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), name.."|r"))
|
||||
friendInfo:SetText(TEXT(UNKNOWN))
|
||||
end
|
||||
|
||||
caption:SetVertexColor(1,1,1,.4)
|
||||
friendInfo:SetVertexColor(1,1,1,.4)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
do -- add colors to who list
|
||||
hooksecurefunc("WhoList_Update", function()
|
||||
local num, max = GetNumWhoResults()
|
||||
local off = FauxScrollFrame_GetOffset(WhoListScrollFrame)
|
||||
|
||||
local playerzone = GetRealZoneText()
|
||||
local playerrace = UnitRace("player")
|
||||
local playerguild = GetGuildInfo("player")
|
||||
|
||||
for i=1, WHOS_TO_DISPLAY do
|
||||
local name, guild, level, race, class, zone = GetWhoInfo(off + i)
|
||||
local displayedText = ""
|
||||
|
||||
if num + 1 >= MAX_WHOS_FROM_SERVER then
|
||||
displayedText = format(WHO_FRAME_SHOWN_TEMPLATE, MAX_WHOS_FROM_SERVER)
|
||||
WhoFrameTotals:SetText("|cffffffff" .. format(GetText("WHO_FRAME_TOTAL_TEMPLATE", nil, num), max).." |cffaaaaaa"..displayedText)
|
||||
else
|
||||
displayedText = format(WHO_FRAME_SHOWN_TEMPLATE, num)
|
||||
WhoFrameTotals:SetText("|cffffffff" .. format(GetText("WHO_FRAME_TOTAL_TEMPLATE", nil, num), num).." |cffaaaaaa"..displayedText)
|
||||
end
|
||||
|
||||
class = L["class"][class]
|
||||
|
||||
_G["WhoFrameButton"..i.."Name"]:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
||||
|
||||
if (UIDropDownMenu_GetSelectedID(WhoFrameDropDown) == 1) then
|
||||
if (zone == playerzone) then
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(.5, 1, 1)
|
||||
else
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(1, 1, 1)
|
||||
end
|
||||
|
||||
elseif (UIDropDownMenu_GetSelectedID(WhoFrameDropDown) == 2) then
|
||||
if (guild == playerguild) then
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(.5, 1, 1)
|
||||
else
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(1, 1, 1)
|
||||
end
|
||||
|
||||
elseif (UIDropDownMenu_GetSelectedID(WhoFrameDropDown) == 3) then
|
||||
if (race == playerrace) then
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(.5, 1, 1)
|
||||
else
|
||||
_G["WhoFrameButton"..i.."Variable"]:SetTextColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
|
||||
if class then
|
||||
local color = RAID_CLASS_COLORS[class]
|
||||
_G["WhoFrameButton"..i.."Class"]:SetTextColor(color.r,color.g,color.b,1)
|
||||
end
|
||||
|
||||
local color = GetDifficultyColor(level)
|
||||
_G["WhoFrameButton"..i.."Level"]:SetTextColor(color.r, color.g, color.b)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
-- SuperWoW compatibility
|
||||
--
|
||||
-- https://github.com/balakethelock/SuperWoW
|
||||
--
|
||||
-- This module adds GUID based cast and channel data to the
|
||||
-- libcast library that is used to query enemy casting infos.
|
||||
|
||||
-- Skip module initialization if SuperWoW is not running.
|
||||
if not GetPlayerBuffID or not CombatLogAdd or not SpellInfo then return end
|
||||
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Super WoW Compatibility"],
|
||||
description = T["Adds compatibility for the SuperWoW client mod."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = false },
|
||||
category = T["General"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local libcast = ShaguTweaks.libcast
|
||||
|
||||
local unitcast = CreateFrame("Frame")
|
||||
unitcast:RegisterEvent("UNIT_CASTEVENT")
|
||||
unitcast:SetScript("OnEvent", function()
|
||||
if arg3 == "START" or arg3 == "CAST" or arg3 == "CHANNEL" then
|
||||
-- human readable argument list
|
||||
local guid = arg1
|
||||
local target = arg2
|
||||
local event_type = arg3
|
||||
local spell_id = arg4
|
||||
local timer = arg5
|
||||
local start = GetTime()
|
||||
|
||||
-- get spell info from spell id
|
||||
local spell, icon, _
|
||||
if SpellInfo and SpellInfo(spell_id) then
|
||||
spell, _, icon = SpellInfo(spell_id)
|
||||
end
|
||||
|
||||
-- set fallback values
|
||||
spell = spell or UNKNOWN
|
||||
icon = icon or "Interface\\Icons\\INV_Misc_QuestionMark"
|
||||
|
||||
-- add cast action to the database
|
||||
if not libcast.db[guid] then libcast.db[guid] = {} end
|
||||
libcast.db[guid].cast = spell
|
||||
libcast.db[guid].rank = nil
|
||||
libcast.db[guid].start = GetTime()
|
||||
libcast.db[guid].casttime = timer
|
||||
libcast.db[guid].icon = icon
|
||||
libcast.db[guid].channel = event_type == "CHANNEL" or false
|
||||
|
||||
-- write state variable
|
||||
ShaguTweaks.superwow_active = true
|
||||
elseif arg3 == "FAIL" then
|
||||
local guid = arg1
|
||||
|
||||
-- delete all cast entries of guid
|
||||
if libcast.db[guid] then
|
||||
libcast.db[guid].cast = nil
|
||||
libcast.db[guid].rank = nil
|
||||
libcast.db[guid].start = nil
|
||||
libcast.db[guid].casttime = nil
|
||||
libcast.db[guid].icon = nil
|
||||
libcast.db[guid].channel = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,144 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local GetExpansion = ShaguTweaks.GetExpansion
|
||||
local UnitCastingInfo = ShaguTweaks.UnitCastingInfo
|
||||
local UnitChannelInfo = ShaguTweaks.UnitChannelInfo
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Enemy Castbars"],
|
||||
description = T["Shows an enemy castbar on target unit frame."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Unit Frames"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
local castbar = CreateFrame("StatusBar", "ShaguTargetCastbar", TargetFrame)
|
||||
castbar:SetPoint("BOTTOM", TargetFrame, "BOTTOM", -12, -4)
|
||||
castbar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
|
||||
castbar:SetStatusBarColor(1, .8, 0, 1)
|
||||
castbar:SetWidth(140)
|
||||
castbar:SetHeight(10)
|
||||
castbar:Hide()
|
||||
|
||||
castbar.texture = CreateFrame("Frame", nil, castbar)
|
||||
castbar.texture:SetPoint("RIGHT", castbar, "LEFT", -2, 0)
|
||||
castbar.texture:SetHeight(20)
|
||||
castbar.texture:SetWidth(20)
|
||||
|
||||
castbar.texture.icon = castbar.texture:CreateTexture(nil, "BACKGROUND")
|
||||
castbar.texture.icon:SetPoint("CENTER", 0, 0)
|
||||
castbar.texture.icon:SetWidth(16)
|
||||
castbar.texture.icon:SetHeight(16)
|
||||
castbar.texture:SetBackdrop({
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 12,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
})
|
||||
|
||||
castbar.bg = castbar:CreateTexture(nil, "BACKGROUND")
|
||||
castbar.bg:SetTexture("Interface\\TARGETINGFRAME\\UI-StatusBar")
|
||||
castbar.bg:SetVertexColor(.1, .1, 0, .8)
|
||||
castbar.bg:SetAllPoints(true)
|
||||
|
||||
castbar.spark = castbar:CreateTexture(nil, "OVERLAY")
|
||||
castbar.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||
castbar.spark:SetWidth(20)
|
||||
castbar.spark:SetHeight(20)
|
||||
castbar.spark:SetBlendMode("ADD")
|
||||
|
||||
castbar.backdrop = CreateFrame("Frame", nil, castbar)
|
||||
castbar.backdrop:SetFrameStrata("BACKGROUND")
|
||||
castbar.backdrop:SetPoint("TOPLEFT", castbar, "TOPLEFT", -3, 3)
|
||||
castbar.backdrop:SetPoint("BOTTOMRIGHT", castbar, "BOTTOMRIGHT", 3, -3)
|
||||
castbar.backdrop:SetBackdrop({
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 12,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
})
|
||||
|
||||
castbar.text = castbar:CreateFontString(nil, "HIGH", "GameFontWhite")
|
||||
castbar.text:SetPoint("CENTER", castbar, "CENTER", 0, 0)
|
||||
local font, size, opts = castbar.text:GetFont()
|
||||
castbar.text:SetFont(font, size - 2, "THINOUTLINE")
|
||||
|
||||
module.enable = function(self)
|
||||
local oldUpdate = TargetFrame:GetScript("OnUpdate")
|
||||
TargetFrame:SetScript("OnUpdate", function(arg)
|
||||
if oldUpdate then oldUpdate(arg) end
|
||||
|
||||
local query = this.unit
|
||||
local channel = false
|
||||
|
||||
-- try to read cast and guid from SuperWoW (except for self casts)
|
||||
if ShaguTweaks.superwow_active and this.unit and not UnitIsUnit(this.unit, 'player') then
|
||||
local _, guid = UnitExists(this.unit)
|
||||
query = guid or query
|
||||
end
|
||||
|
||||
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(query)
|
||||
if not cast then
|
||||
-- scan for channel spells if no cast was found
|
||||
channel, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(query)
|
||||
cast = channel
|
||||
end
|
||||
|
||||
if cast then
|
||||
local channel = UnitChannelInfo(this.unit)
|
||||
local duration = endTime - startTime
|
||||
local max = duration / 1000
|
||||
local cur = GetTime() - startTime / 1000
|
||||
|
||||
if channel then
|
||||
cur = max + startTime/1000 - GetTime()
|
||||
end
|
||||
|
||||
cur = cur > max and max or cur
|
||||
cur = cur < 0 and 0 or cur
|
||||
|
||||
castbar:Show()
|
||||
castbar:SetMinMaxValues(0, duration / 1000)
|
||||
castbar:SetValue(cur)
|
||||
|
||||
local percent = cur / max
|
||||
local x = castbar:GetWidth()*percent
|
||||
castbar.spark:SetPoint("CENTER", castbar, "LEFT", x, 0)
|
||||
|
||||
castbar.text:SetText(cast)
|
||||
|
||||
if texture then
|
||||
castbar.texture.icon:SetTexture(texture)
|
||||
castbar.texture.icon:Show()
|
||||
else
|
||||
castbar.texture.icon:Hide()
|
||||
end
|
||||
|
||||
castbar:ClearAllPoints()
|
||||
castbar:SetPoint("BOTTOM", TargetFrame, "BOTTOM", -12, -4)
|
||||
|
||||
local targetOfTarget = TargetofTargetFrame and TargetofTargetFrame:IsShown()
|
||||
local debuff11 = TargetFrameDebuff11 and TargetFrameDebuff11:IsShown()
|
||||
local debuff7 = TargetFrameDebuff7 and TargetFrameDebuff7:IsShown()
|
||||
local buff1 = TargetFrameBuff1 and TargetFrameBuff1:IsShown()
|
||||
|
||||
if targetOfTarget then
|
||||
castbar:ClearAllPoints()
|
||||
castbar:SetPoint("BOTTOM", TargetFrame, "BOTTOM", -12, -24)
|
||||
if debuff11 then
|
||||
castbar:ClearAllPoints()
|
||||
castbar:SetPoint("BOTTOM", TargetFrame, "BOTTOM", -12, -45)
|
||||
if buff1 then
|
||||
castbar:ClearAllPoints()
|
||||
castbar:SetPoint("BOTTOM", TargetFrame, "BOTTOM", -12, -65)
|
||||
end
|
||||
end
|
||||
else
|
||||
if debuff7 then
|
||||
castbar:ClearAllPoints()
|
||||
castbar:SetPoint("BOTTOM", TargetFrame, "BOTTOM", -12, -24)
|
||||
end
|
||||
end
|
||||
else
|
||||
castbar:Hide()
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Debuff Timer"],
|
||||
description = T["Show debuff durations on the target unit frame."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Unit Frames"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
local libdebuff = ShaguTweaks.libdebuff
|
||||
local UnitDebuff = libdebuff and libdebuff.UnitDebuff
|
||||
local TimeConvert = ShaguTweaks.TimeConvert
|
||||
|
||||
local function CreateTextCooldown(cooldown)
|
||||
if cooldown.readable then return end
|
||||
|
||||
cooldown.readable = CreateFrame("Frame", "pfCooldownFrame", cooldown:GetParent())
|
||||
cooldown.readable:SetAllPoints(cooldown)
|
||||
cooldown.readable:SetFrameLevel(cooldown:GetParent():GetFrameLevel() + 1)
|
||||
cooldown.readable.text = cooldown.readable:CreateFontString("pfCooldownFrameText", "OVERLAY")
|
||||
|
||||
cooldown.readable.text:SetFont(STANDARD_TEXT_FONT, 10, "OUTLINE")
|
||||
cooldown.readable.text:SetPoint("CENTER", cooldown.readable, "CENTER", 0, 0)
|
||||
cooldown.readable:SetScript("OnUpdate", function()
|
||||
parent = this:GetParent()
|
||||
if not parent then this:Hide() end
|
||||
|
||||
if not this.next then this.next = GetTime() + .1 end
|
||||
if this.next > GetTime() then return end
|
||||
this.next = GetTime() + .1
|
||||
|
||||
-- fix own alpha value (should be inherited, but somehow isn't always)
|
||||
this:SetAlpha(parent:GetAlpha())
|
||||
|
||||
local remaining = this.duration - (GetTime() - this.start)
|
||||
if remaining >= 0 then
|
||||
this.text:SetText(TimeConvert(remaining))
|
||||
else
|
||||
this:Hide()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
local HookTargetDebuffButton_Update = TargetDebuffButton_Update
|
||||
TargetDebuffButton_Update = function()
|
||||
HookTargetDebuffButton_Update()
|
||||
|
||||
for i=1, MAX_TARGET_DEBUFFS do
|
||||
local effect, rank, texture, stacks, dtype, duration, timeleft = libdebuff:UnitDebuff("target", i)
|
||||
local button = _G["TargetFrameDebuff"..i]
|
||||
|
||||
if button and not button.cd then
|
||||
button.cd = CreateFrame("Model", "TargetFrameDebuff"..i.."Cooldown", button, "CooldownFrameTemplate")
|
||||
button.cd.noCooldownCount = true
|
||||
button.cd:SetAllPoints()
|
||||
button.cd:SetScale(.6)
|
||||
button.cd:SetAlpha(.8)
|
||||
end
|
||||
|
||||
local dCount = _G["TargetFrameDebuff" .. i .. "Count"]
|
||||
if button and dCount then
|
||||
if not dCount.fixup then
|
||||
dCount.fixup = true
|
||||
dCount:SetPoint("BOTTOMRIGHT", "TargetFrameDebuff" .. i, "BOTTOMRIGHT", 6, -3)
|
||||
end
|
||||
if stacks and stacks > 1 then
|
||||
dCount:SetText("|c0000ff3b" .. stacks)
|
||||
dCount:Show()
|
||||
else
|
||||
dCount:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local dBorder = _G["TargetFrameDebuff" .. i .. "Border"]
|
||||
if button and dBorder then
|
||||
local color = dtype and DebuffTypeColor[dtype] or DebuffTypeColor["none"]
|
||||
dBorder:SetVertexColor(color.r, color.g, color.b)
|
||||
end
|
||||
|
||||
if button and effect and duration and timeleft then
|
||||
local start = GetTime() + timeleft - duration
|
||||
CreateTextCooldown(button.cd)
|
||||
CooldownFrame_SetTimer(button.cd, start, duration, 1)
|
||||
button.cd.readable.start = start
|
||||
button.cd.readable.duration = duration
|
||||
button.cd.readable:Show()
|
||||
button.cd:Show()
|
||||
elseif button then
|
||||
CooldownFrame_SetTimer(button.cd,0,0,0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,199 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local L = ShaguTweaks.L
|
||||
local round = ShaguTweaks.round
|
||||
local rgbhex = ShaguTweaks.rgbhex
|
||||
local Abbreviate = ShaguTweaks.Abbreviate
|
||||
|
||||
local units = { "mouseover", "player", "pet", "target", "party", "partypet", "raid", "raidpet" }
|
||||
local current_unit = "none"
|
||||
|
||||
local function GetUnit()
|
||||
current_unit = "none"
|
||||
for i, unit in pairs(units) do
|
||||
if unit == "party" or unit == "partypet" then
|
||||
for i=1,4 do
|
||||
if UnitExists(unit .. i) and ( UnitName(unit .. i) == GameTooltipTextLeft1:GetText() or UnitPVPName(unit .. i) == GameTooltipTextLeft1:GetText() ) then
|
||||
current_unit = unit .. i
|
||||
return current_unit
|
||||
end
|
||||
end
|
||||
elseif unit == "raid" or unit == "raidpet" then
|
||||
for i=1,40 do
|
||||
if UnitExists(unit .. i) and ( UnitName(unit .. i) == GameTooltipTextLeft1:GetText() or UnitPVPName(unit .. i) == GameTooltipTextLeft1:GetText() ) then
|
||||
current_unit = unit .. i
|
||||
return current_unit
|
||||
end
|
||||
end
|
||||
else
|
||||
if UnitExists(unit) and ( UnitName(unit) == GameTooltipTextLeft1:GetText() or UnitPVPName(unit) == GameTooltipTextLeft1:GetText() ) then
|
||||
current_unit = unit
|
||||
return current_unit
|
||||
end
|
||||
end
|
||||
end
|
||||
return current_unit
|
||||
end
|
||||
|
||||
local updating = false
|
||||
|
||||
local function UpdateTooltip()
|
||||
if updating then return end
|
||||
updating = true
|
||||
|
||||
local unit = GetUnit()
|
||||
if unit == "none" then
|
||||
updating = false
|
||||
return
|
||||
end
|
||||
|
||||
local pvpname = UnitPVPName(unit)
|
||||
local name = UnitName(unit)
|
||||
local target = UnitName(unit .. "target")
|
||||
local _, targetClass = UnitClass(unit .. "target")
|
||||
local targetReaction = UnitReaction("player", unit .. "target")
|
||||
local _, class = UnitClass(unit)
|
||||
local guild = GetGuildInfo(unit)
|
||||
local reaction = UnitReaction(unit, "player")
|
||||
local pvptitle = gsub(pvpname or name, " " .. name, "", 1)
|
||||
|
||||
if name then
|
||||
if UnitIsPlayer(unit) and class then
|
||||
local color = RAID_CLASS_COLORS[class]
|
||||
GameTooltipStatusBar:SetStatusBarColor_orig(color.r, color.g, color.b)
|
||||
GameTooltipStatusBar.bg:SetVertexColor(color.r * 0.15, color.g * 0.15, color.b * 0.15, 0.8)
|
||||
if color and color.r then
|
||||
GameTooltipTextLeft1:SetText(rgbhex(color.r, color.g, color.b, color.a) .. name)
|
||||
else
|
||||
GameTooltipTextLeft1:SetText("|cff999999" .. name)
|
||||
end
|
||||
elseif reaction then
|
||||
local color = UnitReactionColor[reaction]
|
||||
GameTooltipStatusBar:SetStatusBarColor_orig(color.r, color.g, color.b)
|
||||
GameTooltipStatusBar.bg:SetVertexColor(color.r * 0.15, color.g * 0.15, color.b * 0.15, 0.8)
|
||||
end
|
||||
|
||||
if pvptitle ~= name then
|
||||
GameTooltip:AppendText(" |cff666666[" .. pvptitle .. "]|r")
|
||||
end
|
||||
end
|
||||
|
||||
-- Guild name only (no rank)
|
||||
if guild then
|
||||
local guildAlready = false
|
||||
for i = 2, GameTooltip:NumLines() do
|
||||
local left = _G["GameTooltipTextLeft" .. i]
|
||||
if left and left:GetText() == "<" .. guild .. ">" then
|
||||
guildAlready = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not guildAlready then
|
||||
GameTooltip:AddLine("<" .. guild .. ">", 0.3, 1, 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
-- Current target, colored by class or reaction
|
||||
-- Check tooltip lines to avoid duplicating the target line
|
||||
local alreadyAdded = false
|
||||
for i = 2, GameTooltip:NumLines() do
|
||||
local left = _G["GameTooltipTextLeft" .. i]
|
||||
if left and left:GetText() == target then
|
||||
alreadyAdded = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if target and not alreadyAdded then
|
||||
if UnitIsPlayer(unit .. "target") and targetClass then
|
||||
local color = RAID_CLASS_COLORS[targetClass]
|
||||
GameTooltip:AddLine(target, color.r, color.g, color.b)
|
||||
elseif targetReaction then
|
||||
local color = UnitReactionColor[targetReaction]
|
||||
if color then
|
||||
GameTooltip:AddLine(target, color.r, color.g, color.b)
|
||||
else
|
||||
GameTooltip:AddLine(target, .5, .5, .5)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
GameTooltip:Show()
|
||||
updating = false
|
||||
end
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Tooltip Details"],
|
||||
description = T["Enriches unit tooltips with health, class color, guild name, rank, and current target."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["General"],
|
||||
enabled = true,
|
||||
order = 50,
|
||||
})
|
||||
|
||||
local backdrop = {
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 12,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
}
|
||||
|
||||
module.enable = function(self)
|
||||
GameTooltipStatusBar:SetHeight(10)
|
||||
GameTooltipStatusBar:ClearAllPoints()
|
||||
GameTooltipStatusBar:SetPoint("BOTTOMLEFT", GameTooltip, "TOPLEFT", 4, 2)
|
||||
GameTooltipStatusBar:SetPoint("BOTTOMRIGHT", GameTooltip, "TOPRIGHT", -4, 2)
|
||||
|
||||
GameTooltipStatusBar.bg = GameTooltipStatusBar:CreateTexture(nil, "BACKGROUND")
|
||||
GameTooltipStatusBar.bg:SetTexture("Interface\\TARGETINGFRAME\\UI-StatusBar")
|
||||
GameTooltipStatusBar.bg:SetVertexColor(.1, .1, 0, .8)
|
||||
GameTooltipStatusBar.bg:SetAllPoints(true)
|
||||
|
||||
GameTooltipStatusBar.backdrop = CreateFrame("Frame", "GameTooltipStatusBarBackdrop", GameTooltipStatusBar)
|
||||
GameTooltipStatusBar.backdrop:SetPoint("TOPLEFT", GameTooltipStatusBar, "TOPLEFT", -3, 3)
|
||||
GameTooltipStatusBar.backdrop:SetPoint("BOTTOMRIGHT", GameTooltipStatusBar, "BOTTOMRIGHT", 3, -3)
|
||||
GameTooltipStatusBar.backdrop:SetBackdrop(backdrop)
|
||||
GameTooltipStatusBar.backdrop:SetBackdropBorderColor(.8,.8,.8,1)
|
||||
|
||||
GameTooltipStatusBar.backdrop.health = GameTooltipStatusBar.backdrop:CreateFontString("Status", "DIALOG", "GameFontWhite")
|
||||
GameTooltipStatusBar.backdrop.health:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE")
|
||||
GameTooltipStatusBar.backdrop.health:SetPoint("TOP", 0, 4)
|
||||
GameTooltipStatusBar.backdrop.health:SetNonSpaceWrap(false)
|
||||
|
||||
GameTooltipStatusBar.SetStatusBarColor_orig = GameTooltipStatusBar.SetStatusBarColor
|
||||
GameTooltipStatusBar.SetStatusBarColor = function() return end
|
||||
|
||||
-- update tooltip whenever it gets shown
|
||||
local details = CreateFrame("Frame", nil, GameTooltip)
|
||||
details:SetScript("OnShow", UpdateTooltip)
|
||||
|
||||
-- refresh current name and level
|
||||
local statusbar = CreateFrame('Frame', nil, GameTooltipStatusBar)
|
||||
statusbar:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
||||
statusbar:SetScript("OnEvent", function()
|
||||
this.name = UnitName("mouseover")
|
||||
this.level = UnitLevel("mouseover")
|
||||
UpdateTooltip()
|
||||
end)
|
||||
|
||||
-- update health text
|
||||
statusbar:SetScript("OnUpdate", function()
|
||||
local hp = GameTooltipStatusBar:GetValue()
|
||||
local _, hpmax = GameTooltipStatusBar:GetMinMaxValues()
|
||||
local rhp, rhpmax, estimated
|
||||
|
||||
if hpmax > 100 or (round(hpmax/100*hp) ~= hp) then
|
||||
rhp, rhpmax = hp, hpmax
|
||||
else
|
||||
rhp, rhpmax, estimated = ShaguTweaks.libhealth:GetUnitHealthByName(this.name, this.level, tonumber(hp), tonumber(hpmax))
|
||||
end
|
||||
|
||||
if ( estimated or hpmax > 100 or round(hpmax/100*hp) ~= hp ) then
|
||||
GameTooltipStatusBar.backdrop.health:SetText(string.format("%s / %s", Abbreviate(rhp, true), Abbreviate(rhpmax, true)))
|
||||
elseif hpmax > 0 then
|
||||
GameTooltipStatusBar.backdrop.health:SetText(string.format("%s%%", ceil(hp/hpmax*100)))
|
||||
else
|
||||
GameTooltipStatusBar.backdrop.health:SetText("")
|
||||
end
|
||||
end)
|
||||
|
||||
end
|
||||
+3092
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,113 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Unit Frame Big Health"],
|
||||
description = T["Increases the healthbar of the player and target unitframe."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Unit Frames"],
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
|
||||
local addonpath
|
||||
local tocs = { "", "-master", "-tbc", "-wotlk" }
|
||||
for _, name in pairs(tocs) do
|
||||
local current = string.format("ShaguTweaks%s", name)
|
||||
local _, title = GetAddOnInfo(current)
|
||||
if title then
|
||||
addonpath = "Interface\\AddOns\\" .. current
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
PlayerFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame")
|
||||
PlayerFrameHealthBar:SetPoint("TOPLEFT", 106, -22)
|
||||
PlayerFrameHealthBar:SetHeight(30)
|
||||
|
||||
PlayerStatusTexture:SetTexture(addonpath .. "\\img\\UI-Player-Status")
|
||||
|
||||
TargetFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame")
|
||||
TargetFrameHealthBar:SetPoint("TOPRIGHT", -106, -22)
|
||||
TargetFrameHealthBar:SetHeight(30)
|
||||
|
||||
|
||||
local original = TargetFrame_CheckClassification
|
||||
function TargetFrame_CheckClassification()
|
||||
local classification = UnitClassification("target")
|
||||
if ( classification == "worldboss" ) then
|
||||
TargetFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame-Elite")
|
||||
elseif ( classification == "rareelite" ) then
|
||||
TargetFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame-Elite")
|
||||
elseif ( classification == "elite" ) then
|
||||
TargetFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame-Elite")
|
||||
elseif ( classification == "rare" ) then
|
||||
TargetFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame-Rare")
|
||||
else
|
||||
TargetFrameTexture:SetTexture(addonpath .. "\\img\\UI-TargetingFrame")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local wait = CreateFrame("Frame")
|
||||
wait:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
wait:SetScript("OnEvent", function()
|
||||
-- apply darkmode if required
|
||||
ShaguTweaks.DarkenFrame(PlayerFrameTexture)
|
||||
ShaguTweaks.DarkenFrame(TargetFrameTexture)
|
||||
|
||||
-- adjust healthbar colors to frame colors
|
||||
local original = TargetFrame_CheckFaction
|
||||
function TargetFrame_CheckFaction(self)
|
||||
original(self)
|
||||
|
||||
if TargetFrameHealthBar._SetStatusBarColor then
|
||||
local r, g, b, a = TargetFrameNameBackground:GetVertexColor()
|
||||
TargetFrameHealthBar:_SetStatusBarColor(r, g, b, a)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- delay to first draw
|
||||
wait:SetScript("OnUpdate", function()
|
||||
-- move text strings a bit higher
|
||||
if PlayerFrameHealthBar.TextString then
|
||||
PlayerFrameHealthBar.TextString:SetPoint("TOP", PlayerFrameHealthBar, "BOTTOM", 0, 23)
|
||||
end
|
||||
|
||||
if TargetFrameHealthBar.TextString then
|
||||
TargetFrameHealthBar.TextString:SetPoint("TOP", TargetFrameHealthBar, "BOTTOM", -2, 23)
|
||||
end
|
||||
|
||||
-- use class color for player (if enabled)
|
||||
if PlayerFrameNameBackground then
|
||||
-- disable vanilla ui color restore functions
|
||||
PlayerFrameHealthBar._SetStatusBarColor = PlayerFrameHealthBar.SetStatusBarColor
|
||||
PlayerFrameHealthBar.SetStatusBarColor = function() return end
|
||||
|
||||
-- set player healthbar to class color
|
||||
local r, g, b, a = PlayerFrameNameBackground:GetVertexColor()
|
||||
PlayerFrameHealthBar:_SetStatusBarColor(r, g, b, a)
|
||||
|
||||
-- hide status textures
|
||||
PlayerFrameNameBackground:Hide()
|
||||
PlayerFrameNameBackground.Show = function() return end
|
||||
end
|
||||
|
||||
-- use frame color for target frame
|
||||
if TargetFrameNameBackground then
|
||||
-- disable vanilla ui color restore functions
|
||||
TargetFrameHealthBar._SetStatusBarColor = TargetFrameHealthBar.SetStatusBarColor
|
||||
TargetFrameHealthBar.SetStatusBarColor = function() return end
|
||||
|
||||
-- hide status textures
|
||||
TargetFrameNameBackground.Show = function() return end
|
||||
TargetFrameNameBackground:Hide()
|
||||
end
|
||||
|
||||
TargetFrame_CheckFaction(PlayerFrame)
|
||||
wait:UnregisterAllEvents()
|
||||
wait:Hide()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Unit Frame Class Colors"],
|
||||
description = T["Adds class colors to the player, target and party unit frames."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Unit Frames"],
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
local partycolors = function()
|
||||
for id = 1, MAX_PARTY_MEMBERS do
|
||||
local name = _G['PartyMemberFrame'..id..'Name']
|
||||
local _, class = UnitClass("party" .. id)
|
||||
local class = RAID_CLASS_COLORS[class] or { r = .5, g = .5, b = .5, a = 1 }
|
||||
if name then name:SetTextColor(class.r, class.g, class.b, 1) end
|
||||
end
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
-- enable class color backgrounds
|
||||
local original = TargetFrame_CheckFaction
|
||||
function TargetFrame_CheckFaction(self)
|
||||
original(self)
|
||||
|
||||
local reaction = UnitReaction("target", "player")
|
||||
|
||||
if UnitIsPlayer("target") then
|
||||
local _, class = UnitClass("target")
|
||||
local class = RAID_CLASS_COLORS[class] or { r = .5, g = .5, b = .5, a = 1 }
|
||||
TargetFrameNameBackground:SetVertexColor(class.r, class.g, class.b, 1)
|
||||
TargetFrameNameBackground:Show()
|
||||
elseif reaction and reaction > 4 then
|
||||
TargetFrameNameBackground:Hide()
|
||||
else
|
||||
TargetFrameNameBackground:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local _, class = UnitClass("player")
|
||||
local class = RAID_CLASS_COLORS[class] or { r = .5, g = .5, b = .5, a = 1 }
|
||||
|
||||
-- add name background to player frame
|
||||
PlayerFrameNameBackground = PlayerFrame:CreateTexture(nil, "BACKGROUND")
|
||||
PlayerFrameNameBackground:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-LevelBackground")
|
||||
PlayerFrameNameBackground:SetWidth(119)
|
||||
PlayerFrameNameBackground:SetHeight(19)
|
||||
PlayerFrameNameBackground:SetPoint("TOPLEFT", 106, -22)
|
||||
PlayerFrameNameBackground:SetVertexColor(class.r, class.g, class.b, 1)
|
||||
|
||||
local wait = CreateFrame("Frame")
|
||||
wait:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
wait:SetScript("OnEvent", function()
|
||||
local _, class = UnitClass("player")
|
||||
local class = RAID_CLASS_COLORS[class] or { r = .5, g = .5, b = .5, a = 1 }
|
||||
PlayerFrameNameBackground:SetVertexColor(class.r, class.g, class.b, 1)
|
||||
this:UnregisterAllEvents()
|
||||
|
||||
-- make sure to keep name background above frame shadow
|
||||
PlayerFrameNameBackground:SetDrawLayer("BORDER")
|
||||
TargetFrameNameBackground:SetDrawLayer("BORDER")
|
||||
end)
|
||||
|
||||
-- add font outline
|
||||
local font, size = PlayerFrame.name:GetFont()
|
||||
PlayerFrame.name:SetFont(font, size, "NONE")
|
||||
TargetFrame.name:SetFont(font, size, "NONE")
|
||||
|
||||
-- add party frame class colors
|
||||
local HookPartyMemberFrame_UpdateMember = PartyMemberFrame_UpdateMember
|
||||
PartyMemberFrame_UpdateMember = function(self)
|
||||
HookPartyMemberFrame_UpdateMember(self)
|
||||
partycolors()
|
||||
end
|
||||
|
||||
partycolors()
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local addonpath
|
||||
local tocs = { "", "-master", "-tbc", "-wotlk" }
|
||||
for _, name in pairs(tocs) do
|
||||
local current = string.format("ShaguTweaks%s", name)
|
||||
local _, title = GetAddOnInfo(current)
|
||||
if title then
|
||||
addonpath = "Interface\\AddOns\\" .. current
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local CLASS_ICON_TCOORDS = {
|
||||
["WARRIOR"] = { 0, 0.25, 0, 0.25 },
|
||||
["MAGE"] = { 0.25, 0.49609375, 0, 0.25 },
|
||||
["ROGUE"] = { 0.49609375, 0.7421875, 0, 0.25 },
|
||||
["DRUID"] = { 0.7421875, 0.98828125, 0, 0.25 },
|
||||
["HUNTER"] = { 0, 0.25, 0.25, 0.5 },
|
||||
["SHAMAN"] = { 0.25, 0.49609375, 0.25, 0.5 },
|
||||
["PRIEST"] = { 0.49609375, 0.7421875, 0.25, 0.5 },
|
||||
["WARLOCK"] = { 0.7421875, 0.98828125, 0.25, 0.5 },
|
||||
["PALADIN"] = { 0, 0.25, 0.5, 0.75 },
|
||||
["DEATHKNIGHT"] = { 0.25, .5, 0.5, .75 },
|
||||
}
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Unit Frame Class Portraits"],
|
||||
description = T["Replace unitframe portraits with class icons."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["Unit Frames"],
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
local function UpdatePortraits(frame)
|
||||
-- detect unit class or remove for non-player units
|
||||
local _, class = UnitClass(frame.unit)
|
||||
class = UnitIsPlayer(frame.unit) and class or nil
|
||||
|
||||
-- update class icon if possible
|
||||
if class and frame.portrait then
|
||||
local iconCoords = CLASS_ICON_TCOORDS[class]
|
||||
frame.portrait:SetTexture(addonpath .. "\\img\\UI-Classes-Circles")
|
||||
frame.portrait:SetTexCoord(unpack(iconCoords))
|
||||
elseif not class and frame.portrait then
|
||||
frame.portrait:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
module.enable = function(self)
|
||||
-- overwrite portraits set by the game
|
||||
local original = UnitFrame_Update
|
||||
UnitFrame_Update = function(arg1, arg2, arg3)
|
||||
original(arg1, arg2, arg3)
|
||||
UpdatePortraits(this)
|
||||
end
|
||||
|
||||
-- handle portrait update events
|
||||
local events = CreateFrame("Frame")
|
||||
events:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
events:RegisterEvent("UNIT_PORTRAIT_UPDATE")
|
||||
events:SetScript("OnEvent", function()
|
||||
-- reload player portrait
|
||||
UpdatePortraits(PlayerFrame)
|
||||
UpdatePortraits(TargetFrame)
|
||||
|
||||
-- reload party portraits
|
||||
UpdatePortraits(PartyMemberFrame1)
|
||||
UpdatePortraits(PartyMemberFrame2)
|
||||
UpdatePortraits(PartyMemberFrame3)
|
||||
UpdatePortraits(PartyMemberFrame4)
|
||||
end)
|
||||
|
||||
-- update target of target
|
||||
local tot = CreateFrame("Frame", nil, TargetFrame)
|
||||
tot:SetScript("OnUpdate", function()
|
||||
UpdatePortraits(TargetofTargetFrame)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["Unit Frame Energy & Mana Tick"],
|
||||
description = T["Adds an energy & mana tick to the player frame."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = nil },
|
||||
category = T["Unit Frames"],
|
||||
enabled = nil,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local energytick = CreateFrame("Frame", nil, PlayerFrameManaBar)
|
||||
energytick:SetAllPoints(PlayerFrameManaBar)
|
||||
energytick:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
energytick:RegisterEvent("UNIT_DISPLAYPOWER")
|
||||
energytick:RegisterEvent("UNIT_ENERGY")
|
||||
energytick:RegisterEvent("UNIT_MANA")
|
||||
energytick:SetScript("OnEvent", function()
|
||||
if UnitPowerType("player") == 0 then
|
||||
this.mode = "MANA"
|
||||
-- hide if full mana and not in combat
|
||||
if (UnitMana("player") == UnitManaMax("player")) and (not UnitAffectingCombat("player")) then
|
||||
this:Hide()
|
||||
else
|
||||
this:Show()
|
||||
end
|
||||
elseif UnitPowerType("player") == 3 then
|
||||
this.mode = "ENERGY"
|
||||
this:Show()
|
||||
else
|
||||
this:Hide()
|
||||
end
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
this.lastMana = UnitMana("player")
|
||||
end
|
||||
|
||||
if (this.mode == "ENERGY") or ((event == "UNIT_MANA" or event == "UNIT_ENERGY") and arg1 == "player") then
|
||||
this.currentMana = UnitMana("player")
|
||||
local diff = 0
|
||||
if this.lastMana then
|
||||
diff = this.currentMana - this.lastMana
|
||||
end
|
||||
|
||||
if this.mode == "MANA" and diff < 0 then
|
||||
this.target = 5
|
||||
elseif this.mode == "MANA" and diff > 0 then
|
||||
if this.max ~= 5 and diff > (this.badtick and this.badtick*1.2 or 5) then
|
||||
this.target = 2
|
||||
else
|
||||
this.badtick = diff
|
||||
end
|
||||
elseif this.mode == "ENERGY" and diff >= 0 then
|
||||
this.target = 2
|
||||
end
|
||||
this.lastMana = this.currentMana
|
||||
end
|
||||
end)
|
||||
|
||||
local pheight, pwidth = PlayerFrameManaBar:GetHeight(), PlayerFrameManaBar:GetWidth()
|
||||
energytick:SetScript("OnUpdate", function()
|
||||
if this.target then
|
||||
this.start, this.max = GetTime(), this.target
|
||||
this.target = nil
|
||||
end
|
||||
|
||||
if not this.start then return end
|
||||
|
||||
this.current = GetTime() - this.start
|
||||
|
||||
if this.current > this.max then
|
||||
this.start, this.max, this.current = GetTime(), 2, 0
|
||||
end
|
||||
|
||||
local pos = (pwidth ~= "-1" and pwidth or width) * (this.current / this.max)
|
||||
if not pheight then return end
|
||||
this.spark:SetPoint("LEFT", pos-((pheight+5)/2), 0)
|
||||
end)
|
||||
|
||||
energytick.spark = energytick:CreateTexture(nil, 'OVERLAY')
|
||||
energytick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||
energytick.spark:SetHeight(pheight + 10)
|
||||
energytick.spark:SetWidth(pheight + 4)
|
||||
energytick.spark:SetBlendMode('ADD')
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["WorldMap Class Colors"],
|
||||
description = T["Show class colored circles on world and battlefield map."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
local addonpath
|
||||
local tocs = { "", "-master", "-tbc", "-wotlk" }
|
||||
for _, name in pairs(tocs) do
|
||||
local current = string.format("ShaguTweaks%s", name)
|
||||
local _, title = GetAddOnInfo(current)
|
||||
if title then
|
||||
addonpath = "Interface\\AddOns\\" .. current
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local function SetAllPointsOffset(frame, parent, offset)
|
||||
frame:SetPoint("TOPLEFT", parent, "TOPLEFT", offset, -offset)
|
||||
frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -offset, offset)
|
||||
end
|
||||
|
||||
local function UpdateWorldMapColors()
|
||||
-- throttle to to one item per .1 second
|
||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
|
||||
|
||||
local frame, icon
|
||||
|
||||
-- initialize all button names
|
||||
if not this.buttons then
|
||||
this.buttons = {}
|
||||
|
||||
for i = 1, 4 do
|
||||
icon = string.format("WorldMapParty%d", i)
|
||||
this.buttons[icon] = string.format("party%d", i)
|
||||
end
|
||||
|
||||
for i = 1, 4 do
|
||||
icon = string.format("BattlefieldMinimapParty%d", i)
|
||||
this.buttons[icon] = string.format("party%d", i)
|
||||
end
|
||||
|
||||
for i = 1, 40 do
|
||||
icon = string.format("BattlefieldMinimapRaid%d", i)
|
||||
this.buttons[icon] = string.format("raid%d", i)
|
||||
end
|
||||
|
||||
for i = 1, 40 do
|
||||
icon = string.format("WorldMapRaid%d", i)
|
||||
this.buttons[icon] = string.format("raid%d", i)
|
||||
end
|
||||
end
|
||||
|
||||
-- update all available buttons
|
||||
local ingroup
|
||||
for name, unitstr in pairs(this.buttons) do
|
||||
frame = _G[name]
|
||||
|
||||
if frame and UnitExists(unitstr) then
|
||||
icon = _G[name.."Icon"]
|
||||
icon:SetTexture()
|
||||
|
||||
-- create icon if not yet existing
|
||||
if not frame.texture then
|
||||
frame.texture = frame:CreateTexture(nil, "OVERLAY")
|
||||
SetAllPointsOffset(frame.texture, frame, 12, 12)
|
||||
end
|
||||
|
||||
-- check if unit is in same group
|
||||
ingroup = nil
|
||||
for i=1,5 do -- check if unit is in group
|
||||
if UnitName(string.format("party%d", i)) == UnitName(unitstr) then
|
||||
ingroup = true
|
||||
end
|
||||
end
|
||||
|
||||
-- update texture according to raid/group state
|
||||
if ingroup and frame.texture.ingroup ~= "PARTY" then
|
||||
frame.texture:SetTexture(addonpath .. "\\img\\circleparty")
|
||||
frame.texture.ingroup = "PARTY"
|
||||
elseif not ingroup and frame.texture.ingroup ~= "RAID" then
|
||||
frame.texture:SetTexture(addonpath .. "\\img\\circleraid")
|
||||
frame.texture.ingroup = "RAID"
|
||||
end
|
||||
|
||||
-- detect unit class and set color
|
||||
local _, class = UnitClass(unitstr)
|
||||
local color = RAID_CLASS_COLORS[class]
|
||||
if color then
|
||||
frame.texture:SetVertexColor(color.r, color.g, color.b)
|
||||
else
|
||||
frame.texture:SetVertexColor(.5,1,.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mapcolors = CreateFrame("Frame", nil, UIParent)
|
||||
|
||||
module.enable = function(self)
|
||||
mapcolors:SetScript("OnUpdate", UpdateWorldMapColors)
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["WorldMap Coordinates"],
|
||||
description = T["Adds coordinates to the bottom of the World Map."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
local delay = CreateFrame("Frame")
|
||||
delay:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
delay:SetScript("OnEvent", function()
|
||||
-- do not load if other map addon is loaded
|
||||
if Cartographer then return end
|
||||
if METAMAP_TITLE then return end
|
||||
|
||||
-- coordinates
|
||||
if not WorldMapButton.coords then
|
||||
WorldMapButton.coords = CreateFrame("Frame", "pfWorldMapButtonCoords", WorldMapButton)
|
||||
WorldMapButton.coords.text = WorldMapButton.coords:CreateFontString(nil, "OVERLAY")
|
||||
WorldMapButton.coords.text:SetPoint("BOTTOMLEFT", WorldMapButton, "BOTTOMLEFT", 3, -21)
|
||||
WorldMapButton.coords.text:SetFontObject(GameFontWhite)
|
||||
WorldMapButton.coords.text:SetTextColor(1, 1, 1)
|
||||
WorldMapButton.coords.text:SetJustifyH("RIGHT")
|
||||
|
||||
-- move coordinates in case of other addons already taking the space
|
||||
if Gatherer_WorldMapDisplay then
|
||||
WorldMapButton.coords.text:SetPoint("LEFT", Gatherer_WorldMapDisplay, "RIGHT", 3, -21)
|
||||
end
|
||||
|
||||
WorldMapButton.player = CreateFrame("Frame", "pfWorldMapButtonCoords", WorldMapButton)
|
||||
WorldMapButton.player.text = WorldMapButton.player:CreateFontString(nil, "OVERLAY")
|
||||
WorldMapButton.player.text:SetPoint("BOTTOMRIGHT", WorldMapButton, "BOTTOMRIGHT", -3, -21)
|
||||
WorldMapButton.player.text:SetFontObject(GameFontWhite)
|
||||
WorldMapButton.player.text:SetTextColor(1, 1, 1)
|
||||
WorldMapButton.player.text:SetJustifyH("RIGHT")
|
||||
|
||||
WorldMapButton.coords:SetScript("OnUpdate", function()
|
||||
local width = WorldMapButton:GetWidth()
|
||||
local height = WorldMapButton:GetHeight()
|
||||
local mx, my = WorldMapButton:GetCenter()
|
||||
local scale = WorldMapButton:GetEffectiveScale()
|
||||
local x, y = GetCursorPosition()
|
||||
|
||||
if mx and my then
|
||||
mx = (( x / scale ) - ( mx - width / 2)) / width * 100
|
||||
my = (( my + height / 2 ) - ( y / scale )) / height * 100
|
||||
end
|
||||
|
||||
local px, py = GetPlayerMapPosition("player")
|
||||
if px > 0 and py > 0 then
|
||||
WorldMapButton.player.text:SetText(string.format("|cffffcc00" .. T["Player"] .. ": |r%.1f / %.1f", px*100, py*100))
|
||||
else
|
||||
WorldMapButton.player.text:SetText(string.format("|cffffcc00" .. T["Player"] .. ": |r" .. T["N/A"]))
|
||||
end
|
||||
|
||||
if mx and my and MouseIsOver(WorldMapButton) then
|
||||
WorldMapButton.coords.text:SetText(string.format("|cffffcc00" .. T["Cursor"] .. ": |r%.1f / %.1f", mx, my))
|
||||
else
|
||||
WorldMapButton.coords.text:SetText(string.format("|cffffcc00" .. T["Cursor"] .. ": |r" .. T["N/A"]))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
local HookScript = ShaguTweaks.HookScript
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["WorldMap Window"],
|
||||
description = T["Turns the world map into a movable window. The map can be scaled with <Ctrl> + Mousewheel."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["World & MiniMap"],
|
||||
enabled = true,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
table.insert(UISpecialFrames, "WorldMapFrame")
|
||||
|
||||
function _G.ToggleWorldMap()
|
||||
if WorldMapFrame:IsShown() then
|
||||
WorldMapFrame:Hide()
|
||||
else
|
||||
WorldMapFrame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local delay = CreateFrame("Frame")
|
||||
delay:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
delay:SetScript("OnEvent", function()
|
||||
-- do not load if other map addon is loaded
|
||||
if Cartographer then return end
|
||||
if METAMAP_TITLE then return end
|
||||
|
||||
UIPanelWindows["WorldMapFrame"] = { area = "center" }
|
||||
|
||||
-- make sure the hooks get only applied once
|
||||
if not this.hooked then
|
||||
this.hooked = true
|
||||
|
||||
HookScript(WorldMapFrame, "OnShow", function()
|
||||
-- customize
|
||||
this:EnableKeyboard(false)
|
||||
this:EnableMouseWheel(1)
|
||||
|
||||
-- set back to default scale
|
||||
WorldMapFrame:SetScale(.85)
|
||||
end)
|
||||
|
||||
HookScript(WorldMapFrame, "OnMouseWheel", function()
|
||||
if IsShiftKeyDown() then
|
||||
WorldMapFrame:SetAlpha(WorldMapFrame:GetAlpha() + arg1/10)
|
||||
elseif IsControlKeyDown() then
|
||||
WorldMapFrame:SetScale(WorldMapFrame:GetScale() + arg1/10)
|
||||
end
|
||||
end)
|
||||
|
||||
HookScript(WorldMapFrame, "OnMouseDown",function()
|
||||
WorldMapFrame:StartMoving()
|
||||
end)
|
||||
|
||||
HookScript(WorldMapFrame, "OnMouseUp",function()
|
||||
WorldMapFrame:StopMovingOrSizing()
|
||||
end)
|
||||
end
|
||||
|
||||
WorldMapFrame:SetMovable(true)
|
||||
WorldMapFrame:EnableMouse(true)
|
||||
|
||||
WorldMapFrame:SetScale(.85)
|
||||
WorldMapFrame:ClearAllPoints()
|
||||
WorldMapFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 30)
|
||||
WorldMapFrame:SetWidth(WorldMapButton:GetWidth() + 15)
|
||||
WorldMapFrame:SetHeight(WorldMapButton:GetHeight() + 55)
|
||||
BlackoutWorld:Hide()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
local _G = ShaguTweaks.GetGlobalEnv()
|
||||
local T = ShaguTweaks.T
|
||||
|
||||
local module = ShaguTweaks:register({
|
||||
title = T["XP Bar Text"],
|
||||
description = T["Always shows current XP and rested bonus percentage directly on the experience bar."],
|
||||
expansions = { ["vanilla"] = true, ["tbc"] = true },
|
||||
category = T["General"],
|
||||
enabled = true,
|
||||
order = 70,
|
||||
})
|
||||
|
||||
module.enable = function(self)
|
||||
-- Create a separate overlay frame anchored to the XP bar,
|
||||
-- same approach as actionbar-improved-expbar to avoid touching bar internals
|
||||
local exp = CreateFrame("Frame", nil, UIParent)
|
||||
exp:SetAllPoints(MainMenuExpBar)
|
||||
exp:SetFrameStrata("HIGH")
|
||||
|
||||
exp.text = exp:CreateFontString(nil, "OVERLAY", "GameFontWhite")
|
||||
exp.text:SetFont("Fonts\\ARIALN.TTF", 14, "OUTLINE")
|
||||
exp.text:SetPoint("CENTER", MainMenuExpBar, "CENTER", 0, 1)
|
||||
exp.text:SetJustifyH("CENTER")
|
||||
exp.text:SetTextColor(1, 1, 1)
|
||||
|
||||
local function UpdateXPText()
|
||||
local curr = UnitXP("player")
|
||||
local max = UnitXPMax("player")
|
||||
if not max or max == 0 then
|
||||
exp.text:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local rest = GetXPExhaustion() or 0
|
||||
local xpPct = math.floor(curr / max * 100)
|
||||
|
||||
local text
|
||||
if rest > 0 then
|
||||
-- Rested XP pool is 150% of max XP, not 100% (mécanique post-patch)
|
||||
local restPct = math.floor(math.min(rest / (max * 1.5) * 100, 100))
|
||||
text = "|cffffffff" .. xpPct .. "%|r |cffaaaaaa(|cffa78aca" .. restPct .. "%|cffaaaaaa)|r"
|
||||
else
|
||||
text = "|cffffffff" .. xpPct .. "%|r"
|
||||
end
|
||||
|
||||
exp.text:SetText(text)
|
||||
exp.text:Show()
|
||||
end
|
||||
|
||||
local events = CreateFrame("Frame", nil, UIParent)
|
||||
events:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
events:RegisterEvent("PLAYER_XP_UPDATE")
|
||||
events:RegisterEvent("UPDATE_EXHAUSTION")
|
||||
events:RegisterEvent("PLAYER_LEVEL_UP")
|
||||
events:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
if not this.loaded then
|
||||
this.loaded = true
|
||||
-- hide blizzard's default overlay that renders the original xp text
|
||||
MainMenuBarOverlayFrame:Hide()
|
||||
UpdateXPText()
|
||||
end
|
||||
else
|
||||
UpdateXPText()
|
||||
end
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user