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.
274 lines
7.9 KiB
274 lines
7.9 KiB
local _, L = ...
|
|
local NPC, Text = ImmersionFrame, ImmersionFrame.TalkBox.TextFrame.Text
|
|
----------------------------------
|
|
local playbackQueue, questCache = {}, {}
|
|
local QUEST_TOAST_CACHE_LIMIT = 30
|
|
----------------------------------
|
|
|
|
local function IsTextCached(text, tbl)
|
|
for i, toast in ipairs(tbl) do
|
|
if toast.text == text then
|
|
return i
|
|
end
|
|
end
|
|
end
|
|
|
|
local function IsFrameReady()
|
|
local event = NPC.lastEvent or ''
|
|
local notInGossip = event:match('GOSSIP') and not UnitExists('npc')
|
|
local notInQuest = NPC:IsObstructingQuestEvent(event) and GetQuestID() == 0
|
|
return notInGossip or notInQuest
|
|
end
|
|
|
|
local function CanToastPlay()
|
|
return IsFrameReady() and #playbackQueue > 0
|
|
end
|
|
|
|
local function PopToast(i)
|
|
local toast = tremove(playbackQueue, i)
|
|
if ( toast and toast.questID ~= 0 and not IsTextCached(toast.text, questCache) ) then
|
|
tinsert(questCache, 1, toast)
|
|
questCache[QUEST_TOAST_CACHE_LIMIT] = nil
|
|
end
|
|
end
|
|
|
|
local function RemoveToastByKey(key, value)
|
|
local i = 1
|
|
while playbackQueue[i] do
|
|
if playbackQueue[i][key] == value then
|
|
PopToast(i)
|
|
else
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
local function PlayToast(toast)
|
|
NPC:PlayIntro('IMMERSION_TOAST', true)
|
|
NPC:UpdateTalkingHead(toast.title, toast.text, toast.purpose, toast.display, true)
|
|
end
|
|
|
|
local function QueueToast(tbl, title, text, purpose, unit)
|
|
if not IsTextCached(text, tbl) then
|
|
tinsert(tbl, {
|
|
title = title;
|
|
text = text;
|
|
purpose = purpose;
|
|
questID = GetQuestID();
|
|
youSaid = L.ClickedTitleCache or {};
|
|
display = ImmersionAPI:GetCreatureID(unit);
|
|
})
|
|
end
|
|
end
|
|
|
|
----------------------------------
|
|
|
|
function NPC:PlaySuperTrackedQuestToast(questID)
|
|
for i, toast in ipairs(questCache) do
|
|
if ( toast.questID == questID ) and
|
|
----------------------------------
|
|
IsFrameReady() and
|
|
not IsOptionFrameOpen() and
|
|
not self:IsToastObstructed() then
|
|
----------------------------------
|
|
PlayToast(tremove(questCache, i))
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
function NPC:PlayToasts(obstructingFrameOpen)
|
|
if CanToastPlay() and not obstructingFrameOpen and not self:IsToastObstructed() then
|
|
local toast = playbackQueue[1]
|
|
if toast then
|
|
PlayToast(toast)
|
|
end
|
|
end
|
|
end
|
|
|
|
function NPC:QueueToast(...)
|
|
QueueToast(playbackQueue, ...)
|
|
end
|
|
|
|
function NPC:QueueQuestToast(...)
|
|
QueueToast(questCache, ...)
|
|
end
|
|
|
|
function NPC:RemoveToastByText(text)
|
|
RemoveToastByKey('text', text)
|
|
if CanToastPlay() then
|
|
self:PlayToasts()
|
|
elseif IsFrameReady() then
|
|
self:PlayOutro()
|
|
end
|
|
end
|
|
|
|
function NPC:ClearToasts()
|
|
for i=1, #playbackQueue do
|
|
PopToast(1)
|
|
end
|
|
end
|
|
|
|
----------------------------------
|
|
|
|
do -- OBSTRUCTION:
|
|
-- The toast should not play text while *obstructing* frames are showing.
|
|
-- The user should be limited to one focal point at a time, so the case where
|
|
-- multiple frames are playing text at the same time must be handled.
|
|
local obstructorsShowing = 0
|
|
local function ObstructorOnShow()
|
|
obstructorsShowing = obstructorsShowing + 1
|
|
if ( obstructorsShowing > 0 ) and ( NPC.playbackEvent == 'IMMERSION_TOAST' ) then
|
|
NPC:PlayOutro(true)
|
|
Text:PauseTimer()
|
|
end
|
|
end
|
|
|
|
local function ObstructorOnHide()
|
|
obstructorsShowing = obstructorsShowing - 1
|
|
if ( obstructorsShowing < 1 ) and ( NPC.playbackEvent == 'IMMERSION_TOAST' ) then
|
|
NPC:PlayToasts()
|
|
end
|
|
end
|
|
|
|
local function AddToastObstructor(frame)
|
|
assert(C_Widget.IsFrameWidget(frame), 'ImmersionToast:AddObstructor(frame): invalid frame widget')
|
|
frame:HookScript('OnShow', ObstructorOnShow)
|
|
frame:HookScript('OnHide', ObstructorOnHide)
|
|
|
|
obstructorsShowing = obstructorsShowing + (frame:IsVisible() and 1 or 0)
|
|
end
|
|
|
|
function NPC:IsToastObstructed()
|
|
return obstructorsShowing > 0
|
|
end
|
|
|
|
-- Force base frames and TalkingHeadFrame.
|
|
if LevelUpDisplay then AddToastObstructor(LevelUpDisplay) end
|
|
if AlertFrame then AddToastObstructor(AlertFrame) end
|
|
|
|
if TalkingHeadFrame then
|
|
AddToastObstructor(TalkingHeadFrame)
|
|
elseif TalkingHead_LoadUI then
|
|
hooksecurefunc('TalkingHead_LoadUI', function() AddToastObstructor(TalkingHeadFrame) end)
|
|
end
|
|
end
|
|
|
|
|
|
--[[ Keep in case of reimplementing this functionality
|
|
|
|
function Toast:DisplayClickableQuest(questID)
|
|
local hasQuestID = ( questID and questID ~= 0)
|
|
local logIndex = ( hasQuestID and GetQuestLogIndexByID(questID) )
|
|
local isQuestActive = ( logIndex and logIndex ~= 0 )
|
|
local isQuestTurnIn = ( hasQuestID and IsQuestComplete(questID) )
|
|
local isQuestCompleted = ( hasQuestID and IsQuestFlaggedCompleted(questID) )
|
|
|
|
if hasQuestID then
|
|
self.Subtitle:SetVertexColor(1, .82, 0)
|
|
self.ToastType:SetTexture(nil)
|
|
else
|
|
self.Subtitle:SetVertexColor(.75, .75, .75)
|
|
end
|
|
|
|
self.logIndex = nil
|
|
self.questID = nil
|
|
self.QuestButton:Hide()
|
|
|
|
if isQuestTurnIn or isQuestActive then
|
|
self.logIndex = logIndex
|
|
self.questID = questID
|
|
self.CacheType:SetTexture(nil)
|
|
self.QuestButton:Show()
|
|
elseif isQuestCompleted then
|
|
self.CacheType:SetTexture('Interface\\GossipFrame\\BankerGossipIcon')
|
|
elseif hasQuestID then
|
|
self.CacheType:SetTexture('Interface\\GossipFrame\\AvailableQuestIcon')
|
|
end
|
|
end
|
|
|
|
-- Show quest details if available.
|
|
function Toast:OnQuestButtonClicked()
|
|
if self.logIndex and self.questID then
|
|
SetSuperTrackedQuestID(self.questID)
|
|
end
|
|
end
|
|
|
|
local QUEST_ICONS
|
|
do local QUEST_ICONS_FILE = 'Interface\\QuestFrame\\QuestTypeIcons'
|
|
local QUEST_ICONS_FILE_WIDTH = 128
|
|
local QUEST_ICONS_FILE_HEIGHT = 64
|
|
local QUEST_ICON_SIZE = 18
|
|
|
|
local function CreateQuestIconTextureMarkup(left, right, top, bottom)
|
|
return CreateTextureMarkup(
|
|
QUEST_ICONS_FILE,
|
|
QUEST_ICONS_FILE_WIDTH,
|
|
QUEST_ICONS_FILE_HEIGHT,
|
|
QUEST_ICON_SIZE, QUEST_ICON_SIZE,
|
|
left / QUEST_ICONS_FILE_WIDTH,
|
|
right / QUEST_ICONS_FILE_WIDTH,
|
|
top / QUEST_ICONS_FILE_HEIGHT,
|
|
bottom / QUEST_ICONS_FILE_HEIGHT) .. ' '
|
|
end
|
|
|
|
QUEST_ICONS = {
|
|
item = CreateQuestIconTextureMarkup(18, 36, 36, 54);
|
|
object = CreateQuestIconTextureMarkup(72, 90, 0, 18);
|
|
event = CreateQuestIconTextureMarkup(36, 54, 18, 36);
|
|
monster = CreateQuestIconTextureMarkup(0, 18, 36, 54);
|
|
-- reputation = CreateQuestIconTextureMarkup();
|
|
-- log = CreateQuestIconTextureMarkup();
|
|
-- player = CreateQuestIconTextureMarkup();
|
|
}
|
|
end
|
|
|
|
function Toast:OnQuestButtonMouseover()
|
|
if self.questID then
|
|
local logIndex = GetQuestLogIndexByID(self.questID)
|
|
if logIndex then
|
|
local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID = GetQuestLogTitle(logIndex)
|
|
|
|
GameTooltip:SetOwner(self.QuestButton, 'ANCHOR_TOPLEFT')
|
|
GameTooltip:AddLine(title)
|
|
|
|
if isComplete and isComplete > 0 then
|
|
local completionText = GetQuestLogCompletionText(logIndex) or QUEST_WATCH_QUEST_READY
|
|
GameTooltip:AddLine(completionText, 1, 1, 1, true)
|
|
else
|
|
local _, objectiveText = GetQuestLogQuestText(logIndex)
|
|
GameTooltip:AddLine(objectiveText, 1, 1, 1, true)
|
|
|
|
local requiredMoney = GetQuestLogRequiredMoney(logIndex)
|
|
local numObjectives = GetNumQuestLeaderBoards(logIndex)
|
|
|
|
if numObjectives > 0 then
|
|
GameTooltip:AddLine(' ')
|
|
end
|
|
|
|
for i = 1, numObjectives do
|
|
local text, objectiveType, finished = GetQuestLogLeaderBoard(i, logIndex)
|
|
if text then
|
|
local color = HIGHLIGHT_FONT_COLOR
|
|
local marker = QUEST_ICONS[objectiveType] or QUEST_DASH
|
|
if finished then
|
|
color = GRAY_FONT_COLOR
|
|
end
|
|
GameTooltip:AddLine(marker..text, color.r, color.g, color.b, true)
|
|
end
|
|
end
|
|
if requiredMoney > 0 then
|
|
local playerMoney = GetMoney()
|
|
local color = HIGHLIGHT_FONT_COLOR
|
|
if requiredMoney <= playerMoney then
|
|
playerMoney = requiredMoney
|
|
color = GRAY_FONT_COLOR
|
|
end
|
|
GameTooltip:AddLine(QUEST_DASH..GetMoneyString(playerMoney)..' / '..GetMoneyString(requiredMoney), color.r, color.g, color.b)
|
|
end
|
|
GameTooltip:Show()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
]]--
|
|
|