688 lines
16 KiB
Lua
688 lines
16 KiB
Lua
------------------------------------------------------------
|
|
-- pfUI-DQB
|
|
-- Quest & Gossip module
|
|
--
|
|
-- Controls the visual appearance of Blizzard Quest/Gossip
|
|
-- frames without modifying pfUI itself.
|
|
------------------------------------------------------------
|
|
|
|
local DQB = pfUI and pfUI.dqb
|
|
|
|
if not DQB then
|
|
return
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Helpers
|
|
------------------------------------------------------------
|
|
|
|
local function GetConfig()
|
|
return pfUI_config
|
|
and pfUI_config.dqb
|
|
and pfUI_config.dqb.questgossip
|
|
end
|
|
|
|
|
|
local function IsModuleEnabled()
|
|
if not DQB:IsEnabled() then
|
|
return false
|
|
end
|
|
|
|
local config = GetConfig()
|
|
|
|
return config ~= nil
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Color
|
|
------------------------------------------------------------
|
|
|
|
local function HexToRGB(hex)
|
|
if not hex then
|
|
return 1, 1, 1
|
|
end
|
|
|
|
hex = tostring(hex)
|
|
|
|
hex = string.gsub(hex, "#", "")
|
|
|
|
if string.len(hex) ~= 6 then
|
|
return 1, 1, 1
|
|
end
|
|
|
|
local r = tonumber(string.sub(hex, 1, 2), 16)
|
|
local g = tonumber(string.sub(hex, 3, 4), 16)
|
|
local b = tonumber(string.sub(hex, 5, 6), 16)
|
|
|
|
if not r or not g or not b then
|
|
return 1, 1, 1
|
|
end
|
|
|
|
return r / 255, g / 255, b / 255
|
|
end
|
|
|
|
|
|
local function GetBackgroundColor()
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return 0, 0, 0, 0.85
|
|
end
|
|
|
|
local r, g, b = HexToRGB(config.background_color)
|
|
|
|
local alpha = tonumber(config.background_alpha)
|
|
|
|
if not alpha then
|
|
alpha = 0.85
|
|
end
|
|
|
|
if alpha < 0 then
|
|
alpha = 0
|
|
elseif alpha > 1 then
|
|
alpha = 1
|
|
end
|
|
|
|
return r, g, b, alpha
|
|
end
|
|
|
|
|
|
local function GetTextColor()
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return 1, 1, 1, 1
|
|
end
|
|
|
|
local r, g, b = HexToRGB(config.text_color)
|
|
|
|
return r, g, b, 1
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Font
|
|
------------------------------------------------------------
|
|
|
|
local function GetTextFont()
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return pfUI.font_default or STANDARD_TEXT_FONT
|
|
end
|
|
|
|
local font = config.text_font
|
|
|
|
if not font or font == "" then
|
|
return pfUI.font_default or STANDARD_TEXT_FONT
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- "Arial" is kept as a friendly default value.
|
|
-- WoW does not normally expose an Arial path, so use
|
|
-- pfUI's configured default font in that case.
|
|
--------------------------------------------------------
|
|
|
|
if string.lower(font) == "arial" then
|
|
return pfUI.font_default or STANDARD_TEXT_FONT
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- pfUI media path
|
|
--
|
|
-- Example:
|
|
-- font:default
|
|
--------------------------------------------------------
|
|
|
|
if string.find(font, "font:") then
|
|
return pfUI.media[font]
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Direct font path
|
|
--------------------------------------------------------
|
|
|
|
if string.find(font, "\\") then
|
|
return font
|
|
end
|
|
|
|
if string.find(font, "/") then
|
|
return font
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Unknown short name.
|
|
-- Fall back to pfUI default.
|
|
--------------------------------------------------------
|
|
|
|
return pfUI.font_default or STANDARD_TEXT_FONT
|
|
end
|
|
|
|
|
|
local function GetTextSize()
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return 12
|
|
end
|
|
|
|
local size = tonumber(config.text_size)
|
|
|
|
if not size then
|
|
size = 12
|
|
end
|
|
|
|
if size < 1 then
|
|
size = 1
|
|
end
|
|
|
|
return size
|
|
end
|
|
|
|
|
|
local function GetTextStyle()
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return ""
|
|
end
|
|
|
|
local style = config.text_style
|
|
|
|
if not style then
|
|
return ""
|
|
end
|
|
|
|
style = tostring(style)
|
|
|
|
if style == "" then
|
|
return ""
|
|
end
|
|
|
|
return style
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Text styling
|
|
------------------------------------------------------------
|
|
|
|
local function ApplyText(text)
|
|
if not text then
|
|
return
|
|
end
|
|
|
|
if not IsModuleEnabled() then
|
|
return
|
|
end
|
|
|
|
local config = GetConfig()
|
|
|
|
if not config or config.text_global ~= "1" then
|
|
return
|
|
end
|
|
|
|
local r, g, b, a = GetTextColor()
|
|
local font = GetTextFont()
|
|
local size = GetTextSize()
|
|
local style = GetTextStyle()
|
|
|
|
--------------------------------------------------------
|
|
-- Text colour
|
|
--------------------------------------------------------
|
|
|
|
text:SetTextColor(r, g, b, a)
|
|
|
|
--------------------------------------------------------
|
|
-- Shadow
|
|
--------------------------------------------------------
|
|
|
|
text:SetShadowColor(0, 0, 0, 1)
|
|
text:SetShadowOffset(1, -1)
|
|
|
|
--------------------------------------------------------
|
|
-- Font
|
|
--------------------------------------------------------
|
|
|
|
if font then
|
|
text:SetFont(font, size, style)
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Apply to all FontStrings belonging to a frame
|
|
------------------------------------------------------------
|
|
|
|
local function ApplyFrameText(frame)
|
|
if not frame then
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Regions
|
|
--------------------------------------------------------
|
|
|
|
local regions = { frame:GetRegions() }
|
|
|
|
for _, region in pairs(regions) do
|
|
if region and region:GetObjectType() == "FontString" then
|
|
ApplyText(region)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Children
|
|
--------------------------------------------------------
|
|
|
|
local children = { frame:GetChildren() }
|
|
|
|
for _, child in pairs(children) do
|
|
ApplyFrameText(child)
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Gossip / Quest option buttons
|
|
------------------------------------------------------------
|
|
|
|
local function ApplyOptionButtons()
|
|
if not IsModuleEnabled() then
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Gossip options
|
|
--------------------------------------------------------
|
|
|
|
for i = 1, 32 do
|
|
|
|
local gossipButton = _G["GossipTitleButton" .. i]
|
|
|
|
if gossipButton then
|
|
ApplyFrameText(gossipButton)
|
|
end
|
|
|
|
----------------------------------------------------
|
|
-- Quest options in greeting
|
|
----------------------------------------------------
|
|
|
|
local questButton = _G["QuestTitleButton" .. i]
|
|
|
|
if questButton then
|
|
ApplyFrameText(questButton)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Main Quest/Gossip text
|
|
------------------------------------------------------------
|
|
|
|
local function ApplyQuestGossipText()
|
|
if not IsModuleEnabled() then
|
|
return
|
|
end
|
|
|
|
local texts = {
|
|
|
|
----------------------------------------------------
|
|
-- Quest
|
|
----------------------------------------------------
|
|
|
|
QuestTitleText,
|
|
QuestDescriptionText,
|
|
|
|
QuestProgressTitleText,
|
|
QuestProgressText,
|
|
QuestProgressRequiredItemsText,
|
|
QuestProgressRequiredMoneyText,
|
|
|
|
QuestRewardTitleText,
|
|
QuestRewardText,
|
|
QuestRewardRewardTitleText,
|
|
QuestRewardItemChooseText,
|
|
QuestRewardItemReceiveText,
|
|
QuestRewardSpellLearnText,
|
|
|
|
QuestDetailItemReceiveText,
|
|
QuestDetailSpellLearnText,
|
|
|
|
----------------------------------------------------
|
|
-- Greeting / Gossip
|
|
----------------------------------------------------
|
|
|
|
GreetingText,
|
|
GossipGreetingText,
|
|
CurrentQuestsText,
|
|
AvailableQuestsText,
|
|
|
|
----------------------------------------------------
|
|
-- Objectives
|
|
----------------------------------------------------
|
|
|
|
QuestObjectiveText,
|
|
QuestObjectivesText,
|
|
QuestObjectiveTitleText,
|
|
QuestObjectivesTitleText,
|
|
|
|
----------------------------------------------------
|
|
-- NPC names
|
|
----------------------------------------------------
|
|
|
|
QuestFrameNpcNameText,
|
|
GossipFrameNpcNameText,
|
|
}
|
|
|
|
for _, text in pairs(texts) do
|
|
ApplyText(text)
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Apply recursively as a safety net.
|
|
--
|
|
-- This catches text fields that Blizzard creates
|
|
-- dynamically or which are not present in the static
|
|
-- list above.
|
|
--------------------------------------------------------
|
|
|
|
if QuestFrame then
|
|
ApplyFrameText(QuestFrame)
|
|
end
|
|
|
|
if GossipFrame then
|
|
ApplyFrameText(GossipFrame)
|
|
end
|
|
|
|
ApplyOptionButtons()
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Background
|
|
------------------------------------------------------------
|
|
|
|
local backgroundFrames = {}
|
|
|
|
|
|
local function CreateBackground(frame)
|
|
if not frame then
|
|
return nil
|
|
end
|
|
|
|
if frame.dqbBackground then
|
|
return frame.dqbBackground
|
|
end
|
|
|
|
local background = frame:CreateTexture(nil, "BACKGROUND")
|
|
|
|
background:SetAllPoints()
|
|
|
|
frame.dqbBackground = background
|
|
|
|
table.insert(backgroundFrames, {
|
|
frame = frame,
|
|
background = background,
|
|
})
|
|
|
|
return background
|
|
end
|
|
|
|
|
|
local function ApplyBackground(frame)
|
|
if not frame then
|
|
return
|
|
end
|
|
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return
|
|
end
|
|
|
|
local background = CreateBackground(frame)
|
|
|
|
if not background then
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- DQB background disabled
|
|
--------------------------------------------------------
|
|
|
|
if config.background_global ~= "1" then
|
|
background:Hide()
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- DQB background enabled
|
|
--------------------------------------------------------
|
|
|
|
local r, g, b, a = GetBackgroundColor()
|
|
|
|
background:SetTexture(1, 1, 1, 1)
|
|
background:SetVertexColor(r, g, b, a)
|
|
background:Show()
|
|
end
|
|
|
|
|
|
local function ApplyScrollBackground(scroll)
|
|
if not scroll then
|
|
return
|
|
end
|
|
|
|
local config = GetConfig()
|
|
|
|
if not config then
|
|
return
|
|
end
|
|
|
|
local background = scroll.dqbBackground
|
|
|
|
if not background then
|
|
background = scroll:CreateTexture(nil, "BACKGROUND")
|
|
background:SetAllPoints()
|
|
scroll.dqbBackground = background
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Disabled
|
|
--------------------------------------------------------
|
|
|
|
if config.background_global ~= "1" then
|
|
background:Hide()
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Enabled
|
|
--------------------------------------------------------
|
|
|
|
local r, g, b, a = GetBackgroundColor()
|
|
|
|
background:SetTexture(1, 1, 1, 1)
|
|
background:SetVertexColor(r, g, b, a)
|
|
background:Show()
|
|
end
|
|
|
|
|
|
local function ApplyAllBackgrounds()
|
|
if not IsModuleEnabled() then
|
|
return
|
|
end
|
|
|
|
--------------------------------------------------------
|
|
-- Main frames
|
|
--------------------------------------------------------
|
|
|
|
ApplyBackground(QuestFrame)
|
|
ApplyBackground(GossipFrame)
|
|
|
|
--------------------------------------------------------
|
|
-- Quest panels
|
|
--------------------------------------------------------
|
|
|
|
ApplyScrollBackground(QuestGreetingScrollFrame)
|
|
ApplyScrollBackground(QuestDetailScrollFrame)
|
|
ApplyScrollBackground(QuestProgressScrollFrame)
|
|
ApplyScrollBackground(QuestRewardScrollFrame)
|
|
|
|
--------------------------------------------------------
|
|
-- Gossip
|
|
--------------------------------------------------------
|
|
|
|
ApplyScrollBackground(GossipGreetingScrollFrame)
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Hooks
|
|
------------------------------------------------------------
|
|
|
|
local function HookFunction(name, func)
|
|
if _G[name] then
|
|
hooksecurefunc(name, func)
|
|
end
|
|
end
|
|
|
|
|
|
local function InstallHooks()
|
|
|
|
--------------------------------------------------------
|
|
-- Quest updates
|
|
--------------------------------------------------------
|
|
|
|
HookFunction("QuestFrameItems_Update", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
HookFunction("QuestFrameProgressItems_Update", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
HookFunction("QuestRewardItem_OnClick", function()
|
|
ApplyQuestGossipText()
|
|
end)
|
|
|
|
|
|
HookFunction("QuestFrame_SetTextColor", function(text)
|
|
ApplyText(text)
|
|
end)
|
|
|
|
|
|
HookFunction("QuestFrame_SetTitleTextColor", function(text)
|
|
ApplyText(text)
|
|
end)
|
|
|
|
|
|
HookFunction("QuestInfo_Display", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
--------------------------------------------------------
|
|
-- Gossip updates
|
|
--------------------------------------------------------
|
|
|
|
HookFunction("GossipFrameUpdate", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
HookFunction("GossipFrameAvailableQuestsUpdate", function()
|
|
ApplyOptionButtons()
|
|
ApplyQuestGossipText()
|
|
end)
|
|
|
|
|
|
HookFunction("GossipFrameActiveQuestsUpdate", function()
|
|
ApplyOptionButtons()
|
|
ApplyQuestGossipText()
|
|
end)
|
|
|
|
|
|
HookFunction("GossipFrameOptionsUpdate", function()
|
|
ApplyOptionButtons()
|
|
ApplyQuestGossipText()
|
|
end)
|
|
|
|
|
|
--------------------------------------------------------
|
|
-- Quest panels
|
|
--------------------------------------------------------
|
|
|
|
HookFunction("QuestFrameGreetingPanel_OnShow", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
HookFunction("QuestFrameDetailPanel_OnShow", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
HookFunction("QuestFrameProgressPanel_OnShow", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
|
|
|
|
HookFunction("QuestFrameRewardPanel_OnShow", function()
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end)
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Apply current configuration
|
|
------------------------------------------------------------
|
|
|
|
local function Apply()
|
|
if not IsModuleEnabled() then
|
|
return
|
|
end
|
|
|
|
ApplyQuestGossipText()
|
|
ApplyAllBackgrounds()
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Register module
|
|
------------------------------------------------------------
|
|
|
|
DQB:RegisterModule("questgossip", function()
|
|
|
|
--------------------------------------------------------
|
|
-- Install hooks only once
|
|
--------------------------------------------------------
|
|
|
|
if DQB.questGossipHooksInstalled then
|
|
Apply()
|
|
return
|
|
end
|
|
|
|
DQB.questGossipHooksInstalled = true
|
|
|
|
InstallHooks()
|
|
|
|
--------------------------------------------------------
|
|
-- Initial application
|
|
--------------------------------------------------------
|
|
|
|
Apply()
|
|
end) |