You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

882 lines
28 KiB

local _, addon = ...
local L = addon.L;
local API = addon.API;
local C_TooltipInfo = addon.TooltipAPI;
local ThemeUtil = addon.ThemeUtil;
local match = string.match;
local GetNumLetters = strlenutf8 or string.len;
local Round = API.Round;
local IsQuestItem = API.IsQuestItem;
local PI = math.pi;
local After = C_Timer.After;
-- User Settings
local IGNORE_SEEN_ITEM = false;
local DBKEY_POSITION = "QuestItemDisplayPosition";
------------------
local MAX_TEXT_WIDTH = 224; --256 when font size >12
local TEXT_SPACING = 2;
local ICON_SIZE = 32;
local PADDING_OUTER = 12; --To boundary
local PADDING_TEXT_BUTTON_V = 4;
local PADDING_TEXT_BUTTON_H = 8;
local GAP_TEXT_ICON = 8;
local GAP_TITLE_DESC = 4;
local CLOSE_BUTTON_SIZE = 34;
local QUEUE_MARKER_SIZE = 17;
local READING_SPEED_LETTER = 180 * 5; --WPM * avg. word length
local DURATION_MIN = 5;
local PLAYER_GUID;
local PLAYER_NAME;
local SEEN_ITEMS_SESSION = {}; --Items seen in this game session
local SEEN_ITEMS_ALL = {}; --Items discovered by any of the characters
local READABLE_ITEM = ITEM_CAN_BE_READ or "<This item can be read>";
local START_QUEST_ITEM = ITEM_STARTS_QUEST or "This Item Begins a Quest";
local QuestItemDisplay = CreateFrame("Frame");
QuestItemDisplay:Hide();
addon.QuestItemDisplay = QuestItemDisplay;
function QuestItemDisplay:Init()
self.Init = nil;
self:SetSize(8, 8);
self.queue = {};
local bg = self:CreateTexture(nil, "BACKGROUND");
self.Background = bg;
local margin = 24;
bg:SetTextureSliceMargins(margin, margin, margin, margin);
bg:SetTextureSliceMode(1);
bg:SetAllPoints(true);
bg:SetTexCoord(0.25, 0.5, 0.25, 0.5);
local bgShadow = self:CreateTexture(nil, "BACKGROUND", nil, -1);
self.BackgroundShadow = bgShadow;
local margin = 24;
bgShadow:SetTextureSliceMargins(margin, margin, margin, margin);
bgShadow:SetTextureSliceMode(0);
bgShadow:SetTexCoord(0.515625, 0.765625, 0.25, 0.5);
local pixelOffset = 16.0;
local offset = API.GetPixelForScale(self:GetEffectiveScale(), pixelOffset);
bgShadow:ClearAllPoints();
bgShadow:SetPoint("TOPLEFT", self, "TOPLEFT", -offset, offset);
bgShadow:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", offset, -offset);
local icon = self:CreateTexture(nil, "ARTWORK");
self.ItemIcon = icon;
icon:SetSize(ICON_SIZE, ICON_SIZE);
icon:SetPoint("TOPLEFT", self, "TOPLEFT", PADDING_OUTER, -PADDING_OUTER);
API.RemoveIconBorder(icon);
local title = self:CreateFontString(nil, "OVERLAY", "DUIFont_Quest_SubHeader", 1);
self.ItemName = title;
title:SetJustifyH("LEFT");
title:SetJustifyV("TOP");
title:SetSpacing(TEXT_SPACING);
title:SetWidth(MAX_TEXT_WIDTH);
local desc = self:CreateFontString(nil, "OVERLAY", "DUIFont_Item", 1);
self.Description = desc;
desc:SetJustifyH("LEFT");
desc:SetJustifyV("TOP");
desc:SetSpacing(TEXT_SPACING);
desc:SetWidth(MAX_TEXT_WIDTH);
desc:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -GAP_TITLE_DESC);
local ttBG = self:CreateTexture(nil, "BORDER");
self.TitleBackground = ttBG;
ttBG:SetHeight(CLOSE_BUTTON_SIZE);
ttBG:SetPoint("LEFT", icon, "RIGHT", -24, 8);
ttBG:SetPoint("RIGHT", self, "RIGHT", 0, 0);
ttBG:SetTexCoord(0.1875, 1, 0, 0.125);
ttBG:SetBlendMode("ADD");
ttBG:SetAlpha(0.15);
local ib = self:CreateTexture(nil, "OVERLAY");
self.IconBorder = ib;
local margin = 18;
ib:SetTextureSliceMargins(margin, margin, margin, margin);
ib:SetTextureSliceMode(0);
ib:SetTexCoord(0, 0.15625, 0, 0.15625);
--Pseudo Text Button <Click to Read>
local tbBG = self:CreateTexture(nil, "ARTWORK");
self.TextButtonBackground = tbBG;
local margin = 8;
tbBG:SetTextureSliceMargins(margin, margin, margin, margin);
tbBG:SetTextureSliceMode(0);
tbBG:Hide();
tbBG:ClearAllPoints();
tbBG:SetPoint("TOPLEFT", desc, "BOTTOMLEFT", 0, -GAP_TITLE_DESC);
tbBG:SetTexCoord(0, 0.5, 0.515625, 0.578125);
local ButtonText = self:CreateFontString(nil, "OVERLAY", "DUIFont_Item", 1);
self.ButtonText = ButtonText;
ButtonText:SetJustifyH("LEFT");
ButtonText:SetJustifyV("TOP");
ButtonText:Hide();
ButtonText:SetPoint("TOPLEFT", tbBG, "TOPLEFT", PADDING_TEXT_BUTTON_H, -PADDING_TEXT_BUTTON_V);
local ButtonIcon = self:CreateTexture(nil, "OVERLAY");
self.ButtonIcon = ButtonIcon;
ButtonIcon:SetSize(12, 12);
ButtonIcon:SetPoint("LEFT", tbBG, "LEFT", PADDING_TEXT_BUTTON_V, 0);
ButtonIcon:Hide();
--Pseudo Close Button
local bt = self:CreateTexture(nil, "OVERLAY");
self.CloseButtonTexture = bt;
bt:SetSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE);
bt:SetPoint("CENTER", self, "TOPRIGHT", -8, -8);
bt:SetTexCoord(0, 0.125, 0.25, 0.375);
local function CreateSwipe(isRight)
local sw = self:CreateTexture(nil, "OVERLAY", nil, 1);
sw:SetSize(CLOSE_BUTTON_SIZE/2, CLOSE_BUTTON_SIZE);
if isRight then
sw:SetPoint("LEFT", bt, "CENTER", 0, 0);
sw:SetTexCoord(0.0625, 0.125, 0.375, 0.5);
else
sw:SetPoint("RIGHT", bt, "CENTER", 0, 0);
sw:SetTexCoord(0, 0.0625, 0.375, 0.5);
end
local mask = self:CreateMaskTexture(nil, "OVERLAY", nil, 1);
sw:AddMaskTexture(mask);
mask:SetTexture("Interface/AddOns/DialogueUI/Art/BasicShapes/Mask-RightWhite", "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE");
mask:SetSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE);
mask:SetPoint("CENTER", bt, "CENTER", 0, 0);
return sw, mask
end
self.Swipe1, self.SwipeMask1 = CreateSwipe(true);
self.Swipe2, self.SwipeMask2 = CreateSwipe();
self.SwipeMask2:SetRotation(-PI);
local function CreateQueueMarker()
--Sit below the frame, marker indicates the number of items in the queue
local texture = self:CreateTexture(nil, "OVERLAY");
texture:SetTexture(ThemeUtil:GetTextureFile("QuestItemDisplay-UI.png"));
texture:SetTexCoord(0, 0.0625, 0.1875, 0.25);
texture:SetSize(QUEUE_MARKER_SIZE, QUEUE_MARKER_SIZE);
return texture
end
local function RemoveQueueMarker(texture)
texture:Hide();
texture:ClearAllPoints();
end
self.queueMarkerPool = API.CreateObjectPool(CreateQueueMarker, RemoveQueueMarker);
self.AnimIn = self:CreateAnimationGroup(nil, "DUIGenericPopupAnimationTemplate");
self.AnimIn:SetScript("OnFinished", function()
self:UpdateQueueMarkers();
end);
self:SetScript("OnHide", self.OnHide);
self:LoadPosition();
self:LoadTheme();
self:UpdatePixel();
addon.PixelUtil:AddPixelPerfectObject(self);
--Drag to reposition
self:SetClampedToScreen(true);
self:SetMovable(true);
local DragFrame = CreateFrame("Frame", nil, self);
DragFrame:SetAllPoints(true);
DragFrame:SetFrameLevel(self:GetFrameLevel() + 1);
DragFrame:SetScript("OnEnter", self.OnEnter);
DragFrame:SetScript("OnLeave", self.OnLeave);
DragFrame:SetScript("OnMouseUp", self.OnMouseUp);
DragFrame:RegisterForDrag("LeftButton");
DragFrame:SetScript("OnDragStart", function()
self:StartMoving();
self.isMoving = true;
end);
DragFrame:SetScript("OnDragStop", function()
self:StopMovingOrSizing();
self:SavePosition();
self.isMoving = nil;
end);
self:SetFrameStrata("FULLSCREEN_DIALOG");
self:SetFixedFrameStrata(true);
end
function QuestItemDisplay:UpdatePixel(scale)
if not self.IconBorder then return end;
if not scale then
scale = self:GetEffectiveScale();
end
local borderOffsetPixel = 10.0;
local offset = API.GetPixelForScale(scale, borderOffsetPixel);
self.IconBorder:ClearAllPoints();
self.IconBorder:SetPoint("TOPLEFT", self.ItemIcon, "TOPLEFT", -offset, offset);
self.IconBorder:SetPoint("BOTTOMRIGHT", self.ItemIcon, "BOTTOMRIGHT", offset, -offset);
end
function QuestItemDisplay:ResetPosition()
if self:IsUsingCustomPosition() then
addon.SetDBValue(DBKEY_POSITION, nil);
end
self:LoadPosition();
addon.SettingsUI:RequestUpdate();
end
function QuestItemDisplay:IsUsingCustomPosition()
return addon.GetDBValue(DBKEY_POSITION) ~= nil
end
function QuestItemDisplay:LoadPosition()
local position = addon.GetDBValue(DBKEY_POSITION);
self:ClearAllPoints();
if position then
self:SetPoint("LEFT", UIParent, "BOTTOMLEFT", position[1], position[2]);
else
self:SetPoint("LEFT", nil, "LEFT", 32, 32);
end
end
function QuestItemDisplay:SavePosition()
local x = self:GetLeft();
local _, y = self:GetCenter();
if not x and y then return end;
local position = {
Round(x),
Round(y);
};
addon.SetDBValue(DBKEY_POSITION, position);
addon.SettingsUI:RequestUpdate();
end
local function Countdown_OnUpdate(self, elapsed)
self.t = self.t + elapsed;
self.progress = self.t / self.duration;
if self.progress >= 1 then
self.progress = nil;
self.t = nil;
self:SetScript("OnUpdate", nil);
self:OnCountdownFinished();
self.Swipe1:Hide();
elseif self.progress >= 0.5 then
self.SwipeMask1:SetRotation((self.progress/0.5 - 1) * PI);
self.Swipe2:Hide();
else
self.SwipeMask2:SetRotation((self.progress/0.5 - 1) * PI);
end
end
local function FadeOut_OnUpdate(self, elapsed)
self.alpha = self.alpha - 2 * elapsed;
if self.alpha <= 0 then
self:SetAlpha(0);
if self.alpha <= -1 then --extend fade out duration (delay)
self:SetScript("OnUpdate", nil);
self.isFadingOut = nil;
self:Hide();
self:ProcessQueue();
end
else
self:SetAlpha(self.alpha);
end
end
function QuestItemDisplay:SetCountdown(second)
self.duration = second;
self.t = 0;
self.Swipe1:Show();
self.Swipe2:Show();
self.SwipeMask1:SetRotation(0);
self.SwipeMask2:SetRotation(-PI);
self.isCountingDown = true;
self.isFadingOut = nil;
self:SetScript("OnUpdate", Countdown_OnUpdate);
end
function QuestItemDisplay:OnCountdownFinished()
self.isCountingDown = nil;
self.alpha = self:GetAlpha();
self.isFadingOut = true;
self:SetScript("OnUpdate", FadeOut_OnUpdate);
self:ReleaseActionButton();
end
function QuestItemDisplay:LoadTheme()
if self.Init then
return
end
local file = ThemeUtil:GetTextureFile("QuestItemDisplay-UI.png");
local isDarkMode = ThemeUtil:IsDarkMode();
self.Background:SetTexture(file);
self.BackgroundShadow:SetTexture(file);
self.IconBorder:SetTexture(file);
self.TitleBackground:SetTexture(file);
self.TextButtonBackground:SetTexture(file);
self.CloseButtonTexture:SetTexture(file);
self.Swipe1:SetTexture(file);
self.Swipe2:SetTexture(file);
if isDarkMode then
self.themeID = 2;
ThemeUtil:SetFontColor(self.ButtonText, "DarkModeGold");
else
self.themeID = 1;
ThemeUtil:SetFontColor(self.ButtonText, "Ivory");
end
local function SetBackGround(texture)
texture:SetTexture(file);
end
self.queueMarkerPool:ProcessAllObjects(SetBackGround);
end
function QuestItemDisplay:Layout(hasDescription)
self.ItemName:ClearAllPoints();
self.ItemName:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0);
local titleWidth = self.ItemName:GetWrappedWidth() + CLOSE_BUTTON_SIZE;
local descWidth;
local textButtonAnchor;
if hasDescription then
descWidth = self.Description:GetWrappedWidth();
textButtonAnchor = self.Description;
else
descWidth = 0;
textButtonAnchor = self.ItemName;
end
self.TextButtonBackground:ClearAllPoints();
self.TextButtonBackground:SetPoint("TOPLEFT", textButtonAnchor, "BOTTOMLEFT", 0, -GAP_TITLE_DESC);
local textButtonWidth, bottomObject;
if self.ButtonText:IsShown() then
self.ButtonText:ClearAllPoints();
local iconWidth;
if self.ButtonIcon:IsShown() then
iconWidth = 16;
self.ButtonText:SetPoint("LEFT", self.ButtonIcon, "RIGHT", 0, 0);
else
iconWidth = 0;
self.ButtonText:SetPoint("TOPLEFT", self.TextButtonBackground, "TOPLEFT", PADDING_TEXT_BUTTON_H, -PADDING_TEXT_BUTTON_V);
end
textButtonWidth = iconWidth + self.ButtonText:GetWrappedWidth() + 2*PADDING_TEXT_BUTTON_H;
bottomObject = self.TextButtonBackground;
self.TextButtonBackground:SetHeight(Round(self.ButtonText:GetHeight() + 2 * PADDING_TEXT_BUTTON_V));
else
textButtonWidth = 0;
bottomObject = self.Description;
end
local textWidth = Round(math.max(titleWidth, descWidth, textButtonWidth));
self.TextButtonBackground:SetWidth(textWidth);
local textHeight = Round(self.ItemName:GetTop() - bottomObject:GetBottom());
self.ItemName:ClearAllPoints();
if textHeight < ICON_SIZE then
self.ItemName:SetPoint("TOPLEFT", self.ItemIcon, "TOPRIGHT", GAP_TEXT_ICON, 0.5*(textHeight - ICON_SIZE));
textHeight = ICON_SIZE;
else
self.ItemName:SetPoint("TOPLEFT", self.ItemIcon, "TOPRIGHT", GAP_TEXT_ICON, 0);
end
self:SetSize(textWidth + ICON_SIZE + 2*PADDING_OUTER + GAP_TEXT_ICON, textHeight + 2*PADDING_OUTER);
end
function QuestItemDisplay:ShouldDeferDisplay()
if addon.DialogueUI:IsShown() then
return true
end
end
function QuestItemDisplay:TryDisplayItem(itemID, isRequery)
if self.Init then
self:Init();
end
if self:IsShown() then
self:QueueItem(itemID);
return
end
local tooltipData = C_TooltipInfo.GetItemByID(itemID);
if not (tooltipData and tooltipData.lines) then
self:ProcessQueue();
return
end
local name, description, extraText;
local isReadable, isStartQuestItem, startQuestID, isOnQuest;
for i, line in ipairs(tooltipData.lines) do
if line.leftText and line.type ~= 20 then
if i == 1 then
name = line.leftText;
else
if match(line.leftText, "^[\"“]") then
description = line.leftText;
elseif line.leftText == READABLE_ITEM or line.leftText == START_QUEST_ITEM then
local color;
if self.themeID == 1 then
color = "700b0b"; --700b0b 9B2020
else
color = "b04a4a";
end
extraText = "|cff"..color..line.leftText.."|r";
if line.leftText == READABLE_ITEM then
isReadable = true;
else
isStartQuestItem = true;
end
end
end
end
end
self:ShowTextButton(false);
local itemInfo = API.GetBagQuestItemInfo(itemID);
if itemInfo then
startQuestID = itemInfo.questID;
if startQuestID then
local questName = API.GetQuestName(startQuestID);
if questName then
extraText = nil;
end
elseif itemInfo.isReadable then
isReadable = true;
extraText = nil;
end
else
if isReadable or isStartQuestItem then
--Event Order: item has not been pushed into bags
--clear name to force a requery
name = nil;
end
end
if isReadable and self:ShouldDeferDisplay() then
--We defer readable items to the end of NPC interaction, because using the item exits interaction
self:QueueItem(itemID);
self.anyDeferred = true;
return
end
if not (name and (description or extraText or isReadable)) then
if not isRequery then
if not self.pauseUpdate then
self.pauseUpdate = true;
After(0.5, function()
self.pauseUpdate = nil;
self:TryDisplayItem(itemID, true);
end);
end
else
self:ProcessQueue();
end
return
end
if extraText then
if description then
description = description.."\n"..extraText;
else
description = extraText;
end
end
local icon = C_Item.GetItemIconByID(itemID);
self.ItemIcon:SetTexture(icon);
self.ItemName:SetText(name);
self.Description:SetText(description);
local buttonText;
if isReadable then
self:SetReadableItem(itemID);
elseif startQuestID then
self:SetStartQuestItem(itemID, startQuestID, isOnQuest);
end
self.itemID = itemID;
self.usable = false;
self:Layout(description ~= nil);
self.AnimIn:Stop();
self.AnimIn:Play();
self:Show();
local readTime = math.max(DURATION_MIN, 1 + (GetNumLetters(name) + (description and GetNumLetters(description) or 0) + (buttonText and GetNumLetters(buttonText) or 0)) / READING_SPEED_LETTER * 60);
self:SetCountdown(readTime);
end
function QuestItemDisplay:ShowTextButton(state)
if self.TextButtonBackground then
self.TextButtonBackground:SetShown(state);
self.ButtonText:SetShown(state);
if not state then
self.ButtonIcon:Hide();
end
end
end
function QuestItemDisplay:SetTextButtonEnabled(isEnabled)
local colorKey;
if isEnabled then
if self.themeID == 2 then
colorKey = "DarkModeGold";
else
colorKey = "Ivory";
end
if self.ActionButton and self.ActionButton:IsFocused() then
self:SetTextBackgroundID(2);
else
self:SetTextBackgroundID(1);
end
else
if self.themeID == 2 then
colorKey = "DarkModeGrey70";
else
colorKey = "DarkBrown"; --LightBrown
end
self:SetTextBackgroundID(3);
end
ThemeUtil:SetFontColor(self.ButtonText, colorKey);
end
function QuestItemDisplay:SetTextBackgroundID(id)
if id == 1 then --Normal
self.TextButtonBackground:SetTexCoord(0, 0.5, 0.515625, 0.578125);
elseif id == 2 then --Highlighted
self.TextButtonBackground:SetTexCoord(0, 0.5, 0.59375, 0.65625);
elseif id == 3 then --Disabled
self.TextButtonBackground:SetTexCoord(0, 0.5, 0.671875, 0.734375);
end
end
local function onEnterCombatCallback()
QuestItemDisplay:SetTextButtonEnabled(false);
end
function QuestItemDisplay:GetActionButton()
local ActionButton = addon.AcquireSecureActionButton("QuestItemDisplay");
if ActionButton then
self.ActionButton = ActionButton;
ActionButton:SetScript("OnEnter", function()
self:OnEnter();
self:SetTextBackgroundID(2);
end);
ActionButton:SetScript("OnLeave", function()
self:OnLeave();
self:SetTextBackgroundID(1);
end);
ActionButton:SetScript("PostClick", function(f, button)
self:OnMouseUp(button);
self:Clear();
end);
ActionButton:SetParent(self);
ActionButton:SetFrameStrata(self:GetFrameStrata());
ActionButton:SetFrameLevel(self:GetFrameLevel() + 5);
ActionButton.onEnterCombatCallback = onEnterCombatCallback;
--ActionButton:ShowDebugHitRect(true);
self:SetTextButtonEnabled(true);
return ActionButton
else
self:SetTextButtonEnabled(false);
end
end
function QuestItemDisplay:ReleaseActionButton()
if self.ActionButton then
self.ActionButton:Release();
end
end
function QuestItemDisplay:SetUsableItem(itemID, buttonText)
local ActionButton = self:GetActionButton();
if ActionButton then
ActionButton:SetUseItemByID(itemID, "LeftButton");
ActionButton:CoverObject(self.TextButtonBackground, 4);
end
self:ShowTextButton(true);
self.ButtonText:SetText(buttonText);
self:RegisterEvent("PLAYER_REGEN_ENABLED");
end
function QuestItemDisplay:SetReadableItem(itemID)
self.itemType = "book";
local buttonText= L["Click To Read"];
self:SetUsableItem(itemID, buttonText);
end
function QuestItemDisplay:SetStartQuestItem(itemID, startQuestID, isOnQuest)
self.itemType = "questOffer";
self.startQuestID = startQuestID;
local icon = "Interface/AddOns/DialogueUI/Art/Icons/QuestItem-NotOnQuest.png";
self.ButtonIcon:SetTexture(icon);
self.ButtonIcon:Show();
local questName = API.GetQuestName(startQuestID);
if not (questName and questName ~= "") then
questName = "Quest: "..startQuestID;
After(0.2, function()
if self:IsVisible() and self.itemID == itemID then
questName = API.GetQuestName(startQuestID);
self.ButtonText:SetText(questName);
end
end);
end
self:SetUsableItem(itemID, questName);
end
function QuestItemDisplay:UpdateQueueMarkers()
self.queueMarkerPool:Release();
local numQueued = #self.queue;
if numQueued > 0 then
local fromOffsetX = -numQueued * QUEUE_MARKER_SIZE * 0.5;
local offsetY = 0;
for i = 0, numQueued - 1 do
local marker = self.queueMarkerPool:Acquire();
marker:SetPoint("TOPLEFT", self, "BOTTOM", fromOffsetX + i * QUEUE_MARKER_SIZE, offsetY);
end
end
end
function QuestItemDisplay:QueueItem(itemID)
if itemID == self.itemID then return end;
for i, id in ipairs(self.queue) do
if id == itemID then
return
end
end
table.insert(self.queue, itemID);
if not self.AnimIn:IsPlaying() then
self:UpdateQueueMarkers();
end
end
function QuestItemDisplay:ProcessQueue()
if #self.queue > 0 then
local itemID = table.remove(self.queue, 1);
self:UpdateQueueMarkers();
self:TryDisplayItem(itemID);
else
self:Clear();
end
end
function QuestItemDisplay:Clear()
self:SetScript("OnUpdate", nil);
self.t = nil;
self.progress = nil;
self.isCountingDown = nil;
self.itemID = nil;
self.itemType = nil;
self.startQuestID = nil;
self.anyDeferred = nil;
self.queue = {};
self:Hide();
end
function QuestItemDisplay:OnHide()
self.isCountingDown = nil;
self.isFadingOut = nil;
self:StopAnimating();
self:UnregisterEvent("PLAYER_REGEN_ENABLED");
if self.isMoving then
self.isMoving = nil;
self:StopMovingOrSizing();
end
end
function QuestItemDisplay:OnEnter()
if QuestItemDisplay.isCountingDown then
QuestItemDisplay:SetScript("OnUpdate", nil);
end
end
function QuestItemDisplay:OnLeave()
if QuestItemDisplay.isCountingDown then
QuestItemDisplay:SetScript("OnUpdate", Countdown_OnUpdate);
end
end
function QuestItemDisplay:OnMouseUp(button)
if button == "RightButton" then
QuestItemDisplay:Clear();
elseif button == "LeftButton" then
if QuestItemDisplay.CloseButtonTexture:IsMouseOver() then
QuestItemDisplay:Clear();
end
elseif button == "MiddleButton" then
QuestItemDisplay:ResetPosition();
end
end
function QuestItemDisplay:OnEvent(event, ...)
if event == "CHAT_MSG_LOOT" then
self:CHAT_MSG_LOOT(...);
elseif event == "PLAYER_REGEN_ENABLED" then
if self.itemID and not self.isFadingOut then
if self.itemType == "book" then
self:SetReadableItem(self.itemID);
elseif self.itemType == "questOffer" then
local questName = self.ButtonText:GetText();
self:SetUsableItem(self.itemID, questName);
end
end
end
end
function QuestItemDisplay:CHAT_MSG_LOOT_RETAIL(text, playerName, languageName, channelName, playerName2, specialFlags, zoneChannelID, channelIndex, channelBaseName, languageID, lineID, guid)
--Payloads are different on Classic!
if guid ~= PLAYER_GUID then return end;
self:ProcessLootMessage(text);
end
QuestItemDisplay.CHAT_MSG_LOOT = QuestItemDisplay.CHAT_MSG_LOOT_RETAIL;
function QuestItemDisplay:CHAT_MSG_LOOT_CLASSIC(text, _, _, _, playerName)
if playerName ~= PLAYER_NAME then return end;
self:ProcessLootMessage(text);
end
function QuestItemDisplay:ProcessLootMessage(text)
--Some readable items are not Quest Type (e.g. Secrets of Azeroth). We don't support these items.
local itemID = match(text, "item:(%d+)", 1);
if itemID then
itemID = tonumber(itemID);
if itemID and not SEEN_ITEMS_SESSION[itemID] then
SEEN_ITEMS_SESSION[itemID] = true;
if IsQuestItem(itemID) then
if (not IGNORE_SEEN_ITEM) or (not SEEN_ITEMS_ALL[itemID]) then
SEEN_ITEMS_ALL[itemID] = true;
self:TryDisplayItem(itemID);
end
end
end
end
end
function QuestItemDisplay:LoadSaves()
if not DialogueUI_Saves then return end;
if (not DialogueUI_Saves.QuestItems) or type(DialogueUI_Saves.QuestItems) ~= "table" then
DialogueUI_Saves.QuestItems = {};
end
SEEN_ITEMS_ALL = DialogueUI_Saves.QuestItems;
end
function QuestItemDisplay:EnterEditMode()
if self.Init then
self:Init();
end
self:Clear();
self.ItemName:SetText(L["Quest Item Display"]);
self.Description:SetText(L["Drag To Move"]);
self.ItemIcon:SetTexture(134400); --QuestionMark
self.Swipe1:Hide();
self.Swipe2:Hide();
self:ShowTextButton(false);
self:Layout(true);
self.AnimIn:Stop();
self.AnimIn:Play();
self:Show();
end
function QuestItemDisplay:EnableModule(state)
if state then
self:RegisterEvent("CHAT_MSG_LOOT");
self:SetScript("OnEvent", self.OnEvent);
self:LoadSaves();
else
self:UnregisterEvent("CHAT_MSG_LOOT");
self:Clear();
self:SetScript("OnEvent", nil);
end
end
do
if addon.IsToCVersionEqualOrNewerThan(100000) then
QuestItemDisplay.CHAT_MSG_LOOT = QuestItemDisplay.CHAT_MSG_LOOT_RETAIL;
else
QuestItemDisplay.CHAT_MSG_LOOT = QuestItemDisplay.CHAT_MSG_LOOT_CLASSIC;
end
end
do
local function GetPlayerGUID()
PLAYER_GUID = UnitGUID("player");
PLAYER_NAME = UnitName("player");
end
addon.CallbackRegistry:Register("PLAYER_ENTERING_WORLD", GetPlayerGUID);
local function Settings_QuestItemDisplay(dbValue)
QuestItemDisplay:EnableModule(dbValue == true);
end
addon.CallbackRegistry:Register("SettingChanged.QuestItemDisplay", Settings_QuestItemDisplay);
local function Settings_QuestItemDisplayHideSeen(dbValue)
IGNORE_SEEN_ITEM = dbValue == true;
end
addon.CallbackRegistry:Register("SettingChanged.QuestItemDisplayHideSeen", Settings_QuestItemDisplayHideSeen);
end
do
local function DialogueUI_OnHide()
if QuestItemDisplay.anyDeferred then
After(0.25, function()
QuestItemDisplay:ProcessQueue();
end);
end
end
addon.CallbackRegistry:Register("DialogueUI.Hide", DialogueUI_OnHide);
end