Add files via upload

This commit is contained in:
Dusk-92
2026-07-28 14:26:42 +02:00
committed by GitHub
commit d2ae117132
87 changed files with 36309 additions and 0 deletions
+86
View File
@@ -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
+23
View File
@@ -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
+30
View File
@@ -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
+45
View File
@@ -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
+517
View File
@@ -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
+125
View File
@@ -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
+32
View File
@@ -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
+287
View File
@@ -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
+218
View File
@@ -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
+107
View File
@@ -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
+47
View File
@@ -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
+87
View File
@@ -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
+14
View File
@@ -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
+14
View File
@@ -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
+222
View File
@@ -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
+38
View File
@@ -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
+144
View File
@@ -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
+57
View File
@@ -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
+48
View File
@@ -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
+30
View File
@@ -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
+103
View File
@@ -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
+92
View File
@@ -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
+118
View File
@@ -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
+24
View File
@@ -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
+53
View File
@@ -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
+62
View File
@@ -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
+172
View File
@@ -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
+175
View File
@@ -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
+228
View File
@@ -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
+71
View File
@@ -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
+144
View File
@@ -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
+96
View File
@@ -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
+199
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+113
View File
@@ -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
+78
View File
@@ -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
+80
View File
@@ -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
+85
View File
@@ -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
+107
View File
@@ -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
+68
View File
@@ -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
+73
View File
@@ -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
+67
View File
@@ -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