Files
pfUI-DQB/modules/gossipquest.lua
T
2026-09-05 12:49:21 +01:00

1496 lines
33 KiB
Lua

------------------------------------------------------------
-- pfUI-DQB
-- modules/gossipquest.lua
--
-- DQB Quest & Gossip module.
--
-- This module is based on the original pfUI
-- "Gossip and Quest" skin, but is completely controlled
-- by pfUI-DQB configuration.
--
-- The original pfUI files are NOT modified.
------------------------------------------------------------
local DQB = pfUI and pfUI.dqb
if not DQB then
return
end
DQB:RegisterModule("GossipQuest", function()
--------------------------------------------------------
-- Make sure pfUI API is available
--------------------------------------------------------
if not pfUI or not pfUI.api then
return
end
local API = pfUI.api
local SkinButton = API.SkinButton
local SkinCloseButton = API.SkinCloseButton
local SkinScrollbar = API.SkinScrollbar
local StripTextures = API.StripTextures
local CreateBackdrop = API.CreateBackdrop
local SetHighlight = API.SetHighlight
local SetAllPointsOffset = API.SetAllPointsOffset
--------------------------------------------------------
-- Configuration
--------------------------------------------------------
local config =
pfUI_config
and pfUI_config.dqb
and pfUI_config.dqb.questgossip
if not config then
return
end
local custom = config.custom or {}
--------------------------------------------------------
-- Active styles
--------------------------------------------------------
local usePfUIStyle =
config.pfui_style == "1"
local useCustomStyle =
custom.enable == "1"
--------------------------------------------------------
-- pfUI opacity
--------------------------------------------------------
local pfuiAlpha =
tonumber(config.pfui_alpha)
if not pfuiAlpha then
pfuiAlpha = 0.50
end
if pfuiAlpha < 0 then
pfuiAlpha = 0
elseif pfuiAlpha > 1 then
pfuiAlpha = 1
end
--------------------------------------------------------
-- Custom settings
--------------------------------------------------------
local removeParchment =
custom.remove_parchment == "1"
local backgroundColor =
custom.background_color or "000000"
local backgroundAlpha =
tonumber(custom.background_alpha) or 0.50
if backgroundAlpha < 0 then
backgroundAlpha = 0
elseif backgroundAlpha > 1 then
backgroundAlpha = 1
end
local customFont =
custom.font
local titleColor =
custom.title_color or "ffd700"
local textColor =
custom.text_color or "ffffff"
--------------------------------------------------------
-- Determine active style
--------------------------------------------------------
local styleEnabled =
usePfUIStyle or useCustomStyle
local activeAlpha
local activeBackgroundColor
local activeFont
local activeTitleColor
local activeTextColor
if usePfUIStyle then
activeAlpha = pfuiAlpha
----------------------------------------------------
-- Use pfUI background color
----------------------------------------------------
if pfUI_config
and pfUI_config.appearance
and pfUI_config.appearance.background
and pfUI_config.appearance.background.color then
activeBackgroundColor =
pfUI_config.appearance.background.color
else
activeBackgroundColor = "000000"
end
activeFont =
pfUI.font_default
activeTitleColor =
"ffd700"
activeTextColor =
"ffffff"
elseif useCustomStyle then
activeAlpha =
backgroundAlpha
activeBackgroundColor =
backgroundColor
activeFont =
customFont
activeTitleColor =
titleColor
activeTextColor =
textColor
else
styleEnabled = false
end
--------------------------------------------------------
-- Convert hexadecimal color
--------------------------------------------------------
local function HexToRGB(hex)
if not hex then
return 1, 1, 1
end
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
--------------------------------------------------------
-- Colors
--------------------------------------------------------
local titleR,
titleG,
titleB =
HexToRGB(activeTitleColor)
local textR,
textG,
textB =
HexToRGB(activeTextColor)
local bgR,
bgG,
bgB =
HexToRGB(activeBackgroundColor)
--------------------------------------------------------
-- Frames and panels
--------------------------------------------------------
local frames = {
"Quest",
"Gossip"
}
local panels = {
"Greeting",
"Detail",
"Progress",
"Reward"
}
--------------------------------------------------------
-- Buttons
--------------------------------------------------------
local buttons = {
QuestFrameGreetingGoodbyeButton,
GossipFrameGreetingGoodbyeButton,
QuestFrameDeclineButton,
QuestFrameAcceptButton,
QuestFrameGoodbyeButton,
QuestFrameCompleteButton,
QuestFrameCancelButton,
QuestFrameCompleteQuestButton
}
--------------------------------------------------------
-- Text helpers
--------------------------------------------------------
local function SetTextColor(text, r, g, b)
if not text then
return
end
text:SetTextColor(
r,
g,
b,
1
)
text:SetShadowColor(
0,
0,
0,
1
)
text:SetShadowOffset(
1,
-1
)
end
local function SetWhite(text)
SetTextColor(
text,
textR,
textG,
textB
)
end
local function SetGold(text)
SetTextColor(
text,
titleR,
titleG,
titleB
)
end
--------------------------------------------------------
-- Font
--------------------------------------------------------
local function SetFont(text)
if not text then
return
end
if not activeFont
or activeFont == "" then
return
end
if not text.GetFont
or not text.SetFont then
return
end
local font,
size,
flags =
text:GetFont()
if not size then
size = 12
end
text:SetFont(
activeFont,
size,
flags or ""
)
end
--------------------------------------------------------
-- Configured text
--------------------------------------------------------
local function SetConfiguredText(text)
if not text then
return
end
SetWhite(text)
SetFont(text)
end
--------------------------------------------------------
-- Button text
--------------------------------------------------------
local function SetButtonText(button)
if not button then
return
end
local text =
button:GetFontString()
if text then
SetConfiguredText(text)
end
if button.normalText then
SetConfiguredText(
button.normalText
)
end
if button.highlightText then
SetConfiguredText(
button.highlightText
)
end
if button.disabledText then
SetConfiguredText(
button.disabledText
)
end
local regions = {
button:GetRegions()
}
for _, region in pairs(regions) do
if region
and region:GetObjectType()
== "FontString" then
SetConfiguredText(region)
end
end
end
--------------------------------------------------------
-- Gossip / Quest option buttons
--------------------------------------------------------
local function SetGossipButtons()
for i = 1, 32 do
SetButtonText(
_G["GossipTitleButton" .. i]
)
SetButtonText(
_G["QuestTitleButton" .. i]
)
end
end
--------------------------------------------------------
-- Quest Objectives title
--------------------------------------------------------
local function SetObjectivesTitle(frame)
if not frame then
return
end
local regions = {
frame:GetRegions()
}
for _, region in pairs(regions) do
if region
and region:GetObjectType()
== "FontString" then
local text =
region:GetText()
if text then
local lower =
string.lower(text)
if string.find(
lower,
"quest objectives"
)
or lower == "objectives:"
or lower == "objectives" then
SetGold(region)
SetFont(region)
end
end
end
end
local children = {
frame:GetChildren()
}
for _, child in pairs(children) do
SetObjectivesTitle(child)
end
end
--------------------------------------------------------
-- Rewards title
--------------------------------------------------------
local function SetRewardsTitle(frame)
if not frame then
return
end
local regions = {
frame:GetRegions()
}
for _, region in pairs(regions) do
if region
and region:GetObjectType()
== "FontString" then
local text =
region:GetText()
if text then
local lower =
string.lower(text)
if lower == "rewards"
or lower == "rewards:" then
SetGold(region)
SetFont(region)
end
end
end
end
local children = {
frame:GetChildren()
}
for _, child in pairs(children) do
SetRewardsTitle(child)
end
end
--------------------------------------------------------
-- Apply quest / gossip text
--------------------------------------------------------
local function SetQuestText()
if not styleEnabled then
return
end
----------------------------------------------------
-- Titles
----------------------------------------------------
SetGold(
QuestTitleText
)
SetGold(
QuestProgressTitleText
)
SetGold(
QuestRewardTitleText
)
SetGold(
QuestProgressRequiredItemsText
)
----------------------------------------------------
-- Normal text
----------------------------------------------------
SetConfiguredText(
QuestDescriptionText
)
SetConfiguredText(
QuestProgressText
)
SetConfiguredText(
QuestProgressRequiredMoneyText
)
SetConfiguredText(
QuestRewardText
)
SetConfiguredText(
QuestRewardRewardTitleText
)
SetConfiguredText(
QuestRewardItemChooseText
)
SetConfiguredText(
QuestRewardItemReceiveText
)
SetConfiguredText(
QuestRewardSpellLearnText
)
SetConfiguredText(
QuestDetailItemReceiveText
)
SetConfiguredText(
QuestDetailSpellLearnText
)
SetConfiguredText(
GreetingText
)
SetConfiguredText(
GossipGreetingText
)
SetConfiguredText(
CurrentQuestsText
)
SetConfiguredText(
AvailableQuestsText
)
SetConfiguredText(
QuestObjectiveText
)
SetConfiguredText(
QuestObjectivesText
)
SetConfiguredText(
QuestObjectiveTitleText
)
SetConfiguredText(
QuestObjectivesTitleText
)
SetConfiguredText(
QuestFrameNpcNameText
)
SetConfiguredText(
GossipFrameNpcNameText
)
----------------------------------------------------
-- Gossip / Quest buttons
----------------------------------------------------
SetGossipButtons()
----------------------------------------------------
-- Dynamic titles
----------------------------------------------------
SetObjectivesTitle(
QuestFrame
)
SetObjectivesTitle(
GossipFrame
)
SetRewardsTitle(
QuestFrame
)
SetRewardsTitle(
GossipFrame
)
end
--------------------------------------------------------
-- Stop if no style is selected
--------------------------------------------------------
if not styleEnabled then
if DQB.Debug then
DQB:Debug(
"GossipQuest disabled: no style selected"
)
end
return
end
--------------------------------------------------------
-- pfUI button skin
--------------------------------------------------------
if usePfUIStyle then
for _, button in pairs(buttons) do
if button
and SkinButton then
SkinButton(button)
end
end
end
--------------------------------------------------------
-- Quest reward highlight
--------------------------------------------------------
local QuestRewardItemHighlight
if usePfUIStyle
and QuestRewardScrollChildFrame then
if _G["QuestRewardItemHighlight"] then
StripTextures(
_G["QuestRewardItemHighlight"]
)
end
QuestRewardItemHighlight =
CreateFrame(
"Frame",
nil,
QuestRewardScrollChildFrame
)
local bg =
QuestRewardItemHighlight:CreateTexture(
nil,
"OVERLAY"
)
bg:SetTexture(
1,
1,
1,
0.2
)
bg:SetAllPoints()
QuestRewardItemHighlight.bg =
bg
QuestRewardItemHighlight:Hide()
end
--------------------------------------------------------
-- Quest reward update
--------------------------------------------------------
if QuestRewardItemHighlight then
hooksecurefunc(
"QuestFrameItems_Update",
function()
QuestRewardItemHighlight:Hide()
SetQuestText()
end
)
else
hooksecurefunc(
"QuestFrameItems_Update",
function()
SetQuestText()
end
)
end
--------------------------------------------------------
-- Quest reward item selection
--------------------------------------------------------
if QuestRewardItemHighlight then
hooksecurefunc(
"QuestRewardItem_OnClick",
function()
if this
and this.type == "choice"
and this.backdrop then
QuestRewardItemHighlight:SetAllPoints(
this.backdrop
)
QuestRewardItemHighlight:Show()
end
end
)
end
--------------------------------------------------------
-- Quest text color hooks
--------------------------------------------------------
if QuestFrame_SetTextColor then
hooksecurefunc(
"QuestFrame_SetTextColor",
function(text)
SetConfiguredText(text)
end
)
end
--------------------------------------------------------
-- Quest title color hooks
--------------------------------------------------------
if QuestFrame_SetTitleTextColor then
hooksecurefunc(
"QuestFrame_SetTitleTextColor",
function(text)
SetGold(text)
SetFont(text)
end
)
end
--------------------------------------------------------
-- Quest info
--------------------------------------------------------
if QuestInfo_Display then
hooksecurefunc(
"QuestInfo_Display",
function()
SetQuestText()
end
)
end
--------------------------------------------------------
-- Gossip update
--------------------------------------------------------
if GossipFrameUpdate then
hooksecurefunc(
"GossipFrameUpdate",
function()
SetQuestText()
SetGossipButtons()
end
)
end
--------------------------------------------------------
-- Gossip available quests
--------------------------------------------------------
if GossipFrameAvailableQuestsUpdate then
hooksecurefunc(
"GossipFrameAvailableQuestsUpdate",
function()
SetGossipButtons()
end
)
end
--------------------------------------------------------
-- Gossip active quests
--------------------------------------------------------
if GossipFrameActiveQuestsUpdate then
hooksecurefunc(
"GossipFrameActiveQuestsUpdate",
function()
SetGossipButtons()
end
)
end
--------------------------------------------------------
-- Gossip options
--------------------------------------------------------
if GossipFrameOptionsUpdate then
hooksecurefunc(
"GossipFrameOptionsUpdate",
function()
SetGossipButtons()
end
)
end
--------------------------------------------------------
-- Greeting panel
--------------------------------------------------------
if QuestFrameGreetingPanel_OnShow then
hooksecurefunc(
"QuestFrameGreetingPanel_OnShow",
function()
SetQuestText()
SetGossipButtons()
end
)
end
--------------------------------------------------------
-- Detail panel
--------------------------------------------------------
if QuestFrameDetailPanel_OnShow then
hooksecurefunc(
"QuestFrameDetailPanel_OnShow",
function()
SetQuestText()
end
)
end
--------------------------------------------------------
-- Progress panel
--------------------------------------------------------
if QuestFrameProgressPanel_OnShow then
hooksecurefunc(
"QuestFrameProgressPanel_OnShow",
function()
SetQuestText()
end
)
end
--------------------------------------------------------
-- Reward panel
--------------------------------------------------------
if QuestFrameRewardPanel_OnShow then
hooksecurefunc(
"QuestFrameRewardPanel_OnShow",
function()
SetQuestText()
SetRewardsTitle(
QuestRewardScrollChildFrame
)
SetRewardsTitle(
QuestFrameRewardPanel
)
end
)
end
--------------------------------------------------------
-- pfUI item frames
--------------------------------------------------------
if usePfUIStyle then
for _, baseName in pairs({
"QuestProgressItem",
"QuestDetailItem",
"QuestRewardItem"
}) do
for i = 1, 6 do
local name =
baseName .. i
local item =
_G[name]
local icon =
_G[name .. "IconTexture"]
local count =
_G[name .. "Count"]
local title =
_G[name .. "Name"]
if item
and icon
and count
and title then
local xsize =
item:GetWidth() - 12
local ysize =
item:GetHeight() - 12
item:SetWidth(
xsize
)
StripTextures(
item
)
CreateBackdrop(
item,
nil,
nil,
0.75
)
SetAllPointsOffset(
item.backdrop,
item,
4
)
SetHighlight(
item
)
icon:SetWidth(
ysize
)
icon:SetHeight(
ysize
)
icon:ClearAllPoints()
icon:SetPoint(
"LEFT",
6,
0
)
icon:SetTexCoord(
0.08,
0.92,
0.08,
0.92
)
icon:SetParent(
item.backdrop
)
icon:SetDrawLayer(
"OVERLAY"
)
count:SetParent(
item.backdrop
)
count:SetDrawLayer(
"OVERLAY"
)
title:SetParent(
item.backdrop
)
title:SetDrawLayer(
"OVERLAY"
)
SetConfiguredText(
title
)
end
end
end
end
--------------------------------------------------------
-- Remove Blizzard parchment textures
--
-- This is ALWAYS done for pfUI Style.
--------------------------------------------------------
local function RemoveParchment(panel)
if not panel then
return
end
local panelName =
panel:GetName()
if not panelName then
return
end
local materialNames = {
panelName .. "MaterialTopLeft",
panelName .. "MaterialTopRight",
panelName .. "MaterialBotLeft",
panelName .. "MaterialBotRight"
}
for _, name in pairs(materialNames) do
local texture =
_G[name]
if texture then
texture:Hide()
end
end
end
--------------------------------------------------------
-- Create background inside panel
--
-- IMPORTANT:
-- We do NOT create a backdrop around QuestFrame or
-- GossipFrame. The original Blizzard frame geometry
-- remains untouched.
--------------------------------------------------------
local function ApplyPanelBackground(
panel,
alpha
)
if not panel then
return
end
if panel.dqbBackground then
panel.dqbBackground:SetTexture(
bgR,
bgG,
bgB,
alpha
)
panel.dqbBackground:Show()
return
end
local bg =
panel:CreateTexture(
nil,
"BACKGROUND"
)
bg:SetAllPoints(
panel
)
bg:SetTexture(
bgR,
bgG,
bgB,
alpha
)
panel.dqbBackground =
bg
end
--------------------------------------------------------
-- Apply visual styling
--------------------------------------------------------
for _, frameName in pairs(frames) do
local frame =
_G[frameName .. "Frame"]
if frame then
------------------------------------------------
-- IMPORTANT:
-- No CreateBackdrop(frame)
-- No CreateBackdropShadow(frame)
--
-- The original frame geometry stays intact.
------------------------------------------------
------------------------------------------------
-- Close button
------------------------------------------------
local closeButton =
_G[
frame:GetName()
.. "CloseButton"
]
if closeButton
and SkinCloseButton then
-- Do not pass the parent frame.
-- This keeps Blizzard's original position.
SkinCloseButton(
closeButton
)
end
------------------------------------------------
-- Portrait
------------------------------------------------
local portrait =
_G[
frame:GetName()
.. "Portrait"
]
if portrait then
portrait:Hide()
end
------------------------------------------------
-- NPC name
------------------------------------------------
local NPCName =
_G[
frame:GetName()
.. "NpcNameText"
]
if NPCName then
SetConfiguredText(
NPCName
)
end
------------------------------------------------
-- Panels
------------------------------------------------
for _, panelName in pairs(panels) do
------------------------------------------------
-- Gossip only uses Greeting
------------------------------------------------
if frameName == "Gossip"
and panelName ~= "Greeting" then
break
end
local fname =
frame:GetName()
.. panelName
.. "Panel"
local panel =
_G[fname]
if panel then
------------------------------------------------
-- Remove Blizzard panel textures
------------------------------------------------
StripTextures(
panel
)
------------------------------------------------
-- pfUI style
------------------------------------------------
if usePfUIStyle then
-- pfUI Style ALWAYS removes parchment.
RemoveParchment(
panel
)
-- Background is applied directly
-- inside the original panel.
ApplyPanelBackground(
panel,
activeAlpha
)
elseif useCustomStyle then
------------------------------------------------
-- Custom Style
--
-- Keep existing Custom behavior.
------------------------------------------------
if removeParchment then
RemoveParchment(
panel
)
end
ApplyPanelBackground(
panel,
activeAlpha
)
end
------------------------------------------------
-- Scroll frame
------------------------------------------------
local scroll =
_G[
frameName
.. panelName
.. "ScrollFrame"
]
if scroll then
scroll:SetHeight(
330
)
local scrollbar =
_G[
scroll:GetName()
.. "ScrollBar"
]
if scrollbar
and SkinScrollbar then
SkinScrollbar(
scrollbar
)
end
end
end
end
end
end
--------------------------------------------------------
-- Final text pass
--------------------------------------------------------
SetQuestText()
--------------------------------------------------------
-- Debug
--------------------------------------------------------
if DQB.Debug then
DQB:Debug(
"GossipQuest module applied"
)
end
end)