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.

339 lines
11 KiB

local _, addon = ...
local L = addon.L;
local API = addon.API;
local GetTextReadingTime = API.GetTextReadingTime;
local GetTextColorByIndex = API.GetTextColorByIndex;
local GetTitleForQuestID = API.GetTitleForQuestID;
local GetLFGProposal = GetLFGProposal;
local UIErrorsFrame = UIErrorsFrame;
local AlertFrame = CreateFrame("Frame");
addon.AlertFrame = AlertFrame;
AlertFrame:SetFrameStrata("DIALOG");
AlertFrame:SetFixedFrameStrata(true);
AlertFrame:SetSize(64, 12);
local FontString = AlertFrame:CreateFontString(nil, "OVERLAY", "DUIFont_AlertFont"); --Top right of the screen
FontString:SetPoint("TOPRIGHT", AlertFrame, "TOPRIGHT", 0, 0);
--FontString:SetText("1/1 Photo shared with Maurice") --Debug
local LFGAlert = CreateFrame("Frame", nil, AlertFrame);
LFGAlert.initialized = false;
LFGAlert:SetIgnoreParentAlpha(true);
LFGAlert:SetPoint("TOP", UIParent, "TOP", 0, -48);
local COLOR_YELLOW = 1;
local COLOR_GREEN = 3;
local COLOR_RED = 4;
local ACCEPTED_TYPES = {
--https://warcraft.wiki.gg/wiki/API_GetGameMessageInfo
--1: Ivory 3:Green 4:Red
-- [LE_GAME_ or ] = 1,
[LE_GAME_ERR_QUEST_ACCEPTED_S or 179] = COLOR_GREEN,
[LE_GAME_ERR_QUEST_COMPLETE_S or 180] = COLOR_GREEN,
[LE_GAME_ERR_QUEST_REWARD_EXP_I or 196] = COLOR_GREEN,
[LE_GAME_ERR_QUEST_REWARD_MONEY_S or 197] = COLOR_GREEN;
[LE_GAME_ERR_QUEST_OBJECTIVE_COMPLETE_S or 303] = COLOR_YELLOW,
--[LE_GAME_ERR_QUEST_UNKNOWN_COMPLETE or 304] = COLOR_YELLOW, --Objective Complete.
[LE_GAME_ERR_QUEST_ADD_KILL_SII or 305] = COLOR_YELLOW,
[LE_GAME_ERR_QUEST_ADD_FOUND_SII or 306] = COLOR_YELLOW,
[LE_GAME_ERR_QUEST_ADD_ITEM_SII or 307] = COLOR_YELLOW,
[LE_GAME_ERR_QUEST_ADD_PLAYER_KILL_SII or 308] = COLOR_YELLOW,
[LE_GAME_ERR_QUEST_FAILED_S or 181] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_BAG_FULL_S or 182] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_MAX_COUNT_S or 183] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_MISSING_ITEMS or 185] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_NOT_ENOUGH_MONEY or 187] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_EXPANSION or 188] = COLOR_RED,
[LE_GAME_ERR_QUEST_ONLY_ONE_TIMED or 189] = COLOR_RED,
[LE_GAME_ERR_QUEST_NEED_PREREQS or 190] = COLOR_RED,
[LE_GAME_ERR_QUEST_NEED_PREREQS_CUSTOM or 191] = COLOR_RED,
[LE_GAME_ERR_QUEST_ALREADY_ON or 192] = COLOR_RED,
[LE_GAME_ERR_QUEST_ALREADY_DONE or 193] = COLOR_RED,
[LE_GAME_ERR_QUEST_ALREADY_DONE_DAILY or 194] = COLOR_RED,
[LE_GAME_ERR_QUEST_LOG_FULL or 199] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_TOO_MANY_DAILY_QUESTS_I or 629] = COLOR_RED,
[LE_GAME_ERR_QUEST_FORCE_REMOVED_S or 844] = COLOR_RED,
[LE_GAME_ERR_QUEST_FAILED_SPELL or 858] = COLOR_RED,
[LE_GAME_ERR_QUEST_TURN_IN_FAIL_REASON or 1040] = COLOR_RED,
};
function AlertFrame:OnShow()
self:RegisterEvent("UI_ERROR_MESSAGE");
self:RegisterEvent("UI_INFO_MESSAGE");
self:RegisterEvent("QUEST_ACCEPTED");
self:RegisterEvent("QUEST_TURNED_IN");
self:RegisterEvent("LFG_PROPOSAL_SHOW");
self:RegisterEvent("LFG_PROPOSAL_DONE");
self:RegisterEvent("LFG_PROPOSAL_FAILED");
end
function AlertFrame:OnHide()
self:Clear();
self:UnregisterEvent("UI_ERROR_MESSAGE");
self:UnregisterEvent("UI_INFO_MESSAGE");
self:UnregisterEvent("QUEST_ACCEPTED");
self:UnregisterEvent("QUEST_TURNED_IN");
self:UnregisterEvent("LFG_PROPOSAL_SHOW");
self:UnregisterEvent("LFG_PROPOSAL_DONE");
self:UnregisterEvent("LFG_PROPOSAL_FAILED");
end
function AlertFrame:OnEvent(event, ...)
if event == "UI_INFO_MESSAGE" then
self:TryDisplayMessage(...);
elseif event == "UI_ERROR_MESSAGE" then
self:TryDisplayMessage(...);
elseif event == "QUEST_ACCEPTED" then
local questID = ...
if API.ShouldShowQuestAcceptedAlert(questID) then --Emissary Quests (LEG, BFA) are auto accepted upon login
self:DisplayQuestMessage(questID, L["Format Quest Accepted"], COLOR_YELLOW);
end
elseif event == "QUEST_TURNED_IN" then
local questID, xpReward, moneyReward = ...
self:DisplayQuestMessage(questID, L["Format Quest Completed"], COLOR_GREEN);
elseif event == "LFG_PROPOSAL_SHOW" then
self:OnLFGProposal();
elseif event == "LFG_PROPOSAL_DONE" or event == "LFG_PROPOSAL_FAILED" then
self:HideLFGDialog();
end
end
AlertFrame:SetScript("OnShow", AlertFrame.OnShow);
AlertFrame:SetScript("OnHide", AlertFrame.OnHide);
AlertFrame:SetScript("OnEvent", AlertFrame.OnEvent);
function AlertFrame:TryDisplayMessage(messageType, message, r, g, b)
local colorIndex = messageType and ACCEPTED_TYPES[messageType];
if colorIndex then
self:QueueMessage(message, colorIndex);
end
end
function AlertFrame:Clear(alsoClearDefaultUI)
if self.queue then
self.queue = nil;
self.t = nil;
self.current = nil;
self.total = nil;
self:SetScript("OnUpdate", nil);
FontString:SetText(nil);
self:SetAlpha(0);
if alsoClearDefaultUI and UIErrorsFrame then
UIErrorsFrame:Clear();
end
end
end
function AlertFrame:OnUpdate_OnHold(elapsed)
self.t = self.t + elapsed;
if self.t >= 0 then
self.t = 0;
self:SetScript("OnUpdate", self.OnUpdate_FadeOut);
end
end
function AlertFrame:OnUpdate_FadeIn(elapsed)
self.t = self.t + elapsed;
local alpha = self.t * 4;
if alpha < 0 then
alpha = 0;
elseif alpha >= 1 then
alpha = 1;
self.t = -self.onHoldDuration;
self:SetScript("OnUpdate", self.OnUpdate_OnHold);
end
self:SetAlpha(alpha);
end
function AlertFrame:OnUpdate_FadeOut(elapsed)
self.t = self.t + elapsed;
local alpha = 1 - self.t * 4;
if alpha < 0 then
alpha = 0;
self.t = 0;
self:SetScript("OnUpdate", nil);
self:DisplayNextMessage();
elseif alpha >= 1 then
alpha = 1;
end
self:SetAlpha(alpha);
end
function AlertFrame:DisplayMessage(message, colorIndex)
FontString:SetText(message);
local color = GetTextColorByIndex(colorIndex);
local r, g, b = color:GetRGB();
FontString:SetTextColor(r, g, b);
--print(color:WrapTextInColorCode(message)); --debug
return (message and GetTextReadingTime(message)) or 0
end
function AlertFrame:DisplayNextMessage()
self.current = self.current + 1;
local index = self.current;
if self.queue[index] then
self.onHoldDuration = self:DisplayMessage(self.queue[index][1], self.queue[index][2])
self.t = 0;
self:SetScript("OnUpdate", self.OnUpdate_FadeIn);
else
self:Clear(true);
end
end
function AlertFrame:QueueMessage(message, colorIndex)
if not self:IsShown() then return end;
if not self.queue then
self.queue = {};
end
if not self.total then
self.total = 0;
end
self.total = self.total + 1;
self.queue[self.total] = {message, colorIndex};
if not self.current then
self.current = 0;
self:DisplayNextMessage();
end
end
function AlertFrame:DisplayQuestMessage(questID, stringFormat, colorIndex)
local title = questID and GetTitleForQuestID(questID);
if title and title ~= "" then
self:QueueMessage(stringFormat:format(title), colorIndex);
end
end
local LFGALERT_ALPHA_HIGH = 0.8;
local LFGALERT_ALPHA_LOW = 0.3;
local function LFGAlert_OnUpdate(self, elapsed)
self.alpha = self.alpha + self.delta*elapsed;
if self.alpha > LFGALERT_ALPHA_HIGH then
self.alpha = LFGALERT_ALPHA_HIGH;
self.delta = -self.delta;
elseif self.alpha < LFGALERT_ALPHA_LOW then
self.alpha = LFGALERT_ALPHA_LOW;
self.delta = -self.delta
end
self.Background:SetAlpha(self.alpha);
end
local function LFGAlert_OnMouseDown(self)
if not InCombatLockdown() then
UIParent:Show();
SetUIVisibility(true);
self:Hide();
end
end
local function CreateBounceAnimation(texture)
local ag = texture:CreateAnimationGroup();
ag:SetLooping("REPEAT");
local a1 = ag:CreateAnimation("Translation");
a1:SetOrder(1);
a1:SetOffset(0, -8);
a1:SetDuration(0.6);
a1:SetSmoothing("IN");
local a2 = ag:CreateAnimation("Translation");
a2:SetOrder(2);
a2:SetOffset(0, 8);
a2:SetDuration(0.6);
a2:SetSmoothing("OUT");
return ag
end
function AlertFrame:ShowLFGDialog()
if not LFGAlert.initialized then
LFGAlert.initialized = true;
local iconSize = 32;
local gap = 4;
LFGAlert.Icon = LFGAlert:CreateTexture(nil, "OVERLAY");
LFGAlert.Icon:SetSize(iconSize, iconSize);
LFGAlert.Icon:SetPoint("LEFT", LFGAlert, "LEFT", 0, 0);
LFGAlert.Icon:SetTexture("Interface/AddOns/DialogueUI/Art/Theme_Shared/LFGEye.png");
LFGAlert.Text = LFGAlert:CreateFontString(nil, "OVERLAY", "DUIFont_AlertFont"); --Top right of the screen
LFGAlert.Text:SetPoint("LEFT", LFGAlert, "LEFT", iconSize + gap, 0);
LFGAlert.Text:SetText(L["Ready To Enter"]);
LFGAlert.Text:SetTextColor(1, 1, 1);
local width = LFGAlert.Text:GetWrappedWidth() + iconSize + gap;
LFGAlert:SetSize(width, iconSize);
LFGAlert.Background = LFGAlert:CreateTexture(nil, "BACKGROUND");
LFGAlert.Background:SetSize(256, 256);
LFGAlert.Background:SetPoint("CENTER", LFGAlert, "CENTER", -8, -4);
LFGAlert.Background:SetTexture("Interface/AddOns/DialogueUI/Art/Theme_Shared/TopAlertBackground.png");
--LFGAlert.Background:SetVertexColor(66/255, 183/255, 97/255);
LFGAlert.Background:SetAlpha(0.67);
LFGAlert:SetScript("OnHide", function()
LFGAlert:Hide();
LFGAlert:SetScript("OnUpdate", nil);
LFGAlert.alpha = 0;
end);
LFGAlert:SetScript("OnMouseDown", LFGAlert_OnMouseDown);
LFGAlert.Anim1 = CreateBounceAnimation(LFGAlert.Icon);
LFGAlert.Anim2 = CreateBounceAnimation(LFGAlert.Text);
end
LFGAlert:SetFrameStrata("LOW");
LFGAlert.alpha = LFGALERT_ALPHA_LOW;
LFGAlert.delta = 0.833;
--LFGAlert:SetScript("OnUpdate", LFGAlert_OnUpdate);
LFGAlert:Show();
LFGAlert:StopAnimating();
LFGAlert.Anim1:Play();
LFGAlert.Anim2:Play();
API.UIFrameFade(LFGAlert, 0.25, 1, 0);
end
function AlertFrame:HideLFGDialog()
LFGAlert:Hide();
end
function AlertFrame:OnLFGProposal()
local proposalExists, id, typeID, subtypeID, name, backgroundTexture, role, hasResponded, totalEncounters, completedEncounters, numMembers, isLeader, isHoliday, proposalCategory, isSilent = GetLFGProposal();
if (not proposalExists) or isSilent then
return
end
if UIParent:IsVisible() then
return
end
self:ShowLFGDialog();
end