568cd44af8
Brings the still-needed changes from questie-phase1perf that main lacked. Main already had the Lua 5.0 shims (QuestieLoader bit/strsplit, QuestieStream and QuestieSerializer math.mod sweep), so those are omitted. - QuestieNameplate: skip missing entries instead of return-aborting the whole activeGUIDs loop (one bad unit no longer stalls every nameplate update) - QuestieQuest.ClearAllNotes: skip DB-missing quests instead of aborting, so remaining quests' notes still get cleared - QuestieOptionsTracker: fix fadeTickerValue:Cancel -> fadeTicker:Cancel (3x); fadeTickerValue is a number, the ticker handle is fadeTicker - QuestieCommsData: nil-guard GetNPC/GetObject before reading .name - QuestieAnnounce: bound the alreadySentBandaid dedup cache (reset at 1000) - QuestieDB.IsComplete: hoist GetQuest into expectedQuest (one call, not two) - QuestieFramePool/QuestieFrame: drop the dead BaseOnUpdate ticker branch (BaseOnUpdate was never defined; behavior was always OnUpdate=nil) - QuestieLib: document unused questId arg on Ascension_IsScalingEnabled - Database/Corrections x3: strip stray UTF-8 BOM - Questie-X.toc: remove duplicate QuestieSlash.lua load line
199 lines
7.6 KiB
Lua
199 lines
7.6 KiB
Lua
local Questie = _G.Questie
|
|
---@class QuestieAnnounce
|
|
local QuestieAnnounce = QuestieLoader:CreateModule("QuestieAnnounce")
|
|
local _QuestieAnnounce = {}
|
|
---@type QuestieDB
|
|
local QuestieDB = QuestieLoader:ImportModule("QuestieDB")
|
|
---@type QuestieLink
|
|
local QuestieLink = QuestieLoader:ImportModule("QuestieLink")
|
|
---@type l10n
|
|
local l10n = QuestieLoader:ImportModule("l10n")
|
|
|
|
--- COMPATIBILITY ---
|
|
local IsInGroup = QuestieCompat.IsInGroup
|
|
local IsInRaid = QuestieCompat.IsInRaid
|
|
local LE_PARTY_CATEGORY_INSTANCE = QuestieCompat.LE_PARTY_CATEGORY_INSTANCE
|
|
|
|
local itemCache = {} -- cache data since this happens on item looted it could happen a lot with auto loot
|
|
|
|
local alreadySentBandaid = {} -- TODO: rewrite the entire thing its a lost cause
|
|
local alreadySentBandaidCount = 0 -- bound the dedup cache so it can't grow unbounded across a session
|
|
|
|
local _GetAnnounceMarker
|
|
|
|
---@return string
|
|
_GetAnnounceMarker = function()
|
|
local locale = l10n:GetUILocale()
|
|
if IsInRaid() or IsInGroup() then
|
|
if locale == "ruRU" then
|
|
return "{звезда} Questie: ";
|
|
elseif locale == "frFR" then
|
|
return "{rt1} Questie : ";
|
|
else
|
|
return "{rt1} Questie: "
|
|
end
|
|
else
|
|
return ""
|
|
end
|
|
end
|
|
|
|
function QuestieAnnounce:AnnounceObjectiveToChannel(questId, itemId, objectiveText, objectiveProgress)
|
|
if _QuestieAnnounce:AnnounceEnabledAndPlayerInChannel() and Questie.db.profile.questAnnounceObjectives then
|
|
-- no hyperlink required here
|
|
local questLink = QuestieLink:GetQuestLinkStringById(questId);
|
|
|
|
local objective
|
|
if itemId then
|
|
local itemLink = select(2, GetItemInfo(itemId))
|
|
objective = objectiveProgress.." "..itemLink
|
|
else
|
|
objective = objectiveProgress.." "..objectiveText
|
|
end
|
|
|
|
local message = _GetAnnounceMarker() .. l10n("%s for %s!", objective, questLink)
|
|
_QuestieAnnounce:AnnounceToChannel(message)
|
|
end
|
|
end
|
|
|
|
local _has_seen_incomplete = {}
|
|
local _has_sent_announce = {}
|
|
|
|
function QuestieAnnounce:ObjectiveChanged(questId, text, numFulfilled, numRequired)
|
|
-- Announce completed objective
|
|
if (numRequired ~= numFulfilled) then
|
|
_has_seen_incomplete[text] = true
|
|
elseif _has_seen_incomplete[text] and not _has_sent_announce[text] then
|
|
_has_seen_incomplete[text] = nil
|
|
_has_sent_announce[text] = true
|
|
QuestieAnnounce:AnnounceObjectiveToChannel(questId, nil, text, tostring(numFulfilled) .. "/" .. tostring(numRequired))
|
|
end
|
|
end
|
|
|
|
|
|
function QuestieAnnounce:AnnounceQuestItemLootedToChannel(questId, itemId)
|
|
if _QuestieAnnounce:AnnounceEnabledAndPlayerInChannel() and Questie.db.profile.questAnnounceItems then
|
|
local questHyperLink = QuestieLink:GetQuestLinkStringById(questId);
|
|
local itemLink = select(2, GetItemInfo(itemId))
|
|
|
|
local message = _GetAnnounceMarker() .. l10n("Picked up %s which starts %s!", itemLink, questHyperLink)
|
|
_QuestieAnnounce:AnnounceToChannel(message)
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function _QuestieAnnounce:AnnounceSelf(questId, itemId)
|
|
local questHyperLink = QuestieLink:GetQuestHyperLink(questId);
|
|
local itemLink = select(2, GetItemInfo(itemId));
|
|
|
|
Questie:Print(l10n("You picked up %s which starts %s!", itemLink, questHyperLink));
|
|
end
|
|
|
|
---@return boolean
|
|
function _QuestieAnnounce:AnnounceEnabledAndPlayerInChannel()
|
|
if Questie.db.profile.questAnnounceLocally == true then
|
|
return true -- we always want to print if this option is enabled
|
|
elseif Questie.db.profile.questAnnounceChannel == "both" then
|
|
return IsInRaid() or IsInGroup()
|
|
elseif Questie.db.profile.questAnnounceChannel == "raid" then
|
|
return IsInRaid()
|
|
elseif Questie.db.profile.questAnnounceChannel == "party" then
|
|
return IsInGroup() and not IsInRaid()
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function _QuestieAnnounce.GetChatMessageChannel()
|
|
if IsInRaid() then
|
|
return "RAID"
|
|
elseif IsInGroup(LE_PARTY_CATEGORY_INSTANCE) then
|
|
return "INSTANCE_CHAT"
|
|
else
|
|
return "PARTY"
|
|
end
|
|
end
|
|
|
|
function _QuestieAnnounce:AnnounceToChannel(message)
|
|
Questie:Debug(Questie.DEBUG_DEVELOP, "[QuestieAnnounce] raw msg: ", message)
|
|
if (not message) or alreadySentBandaid[message] or Questie.db.profile.questieShutUp then
|
|
return
|
|
end
|
|
|
|
if not alreadySentBandaid[message] then
|
|
alreadySentBandaid[message] = true
|
|
alreadySentBandaidCount = alreadySentBandaidCount + 1
|
|
-- Reset the dedup cache after enough distinct messages so it cannot grow
|
|
-- unbounded over a long session. Reassigning ({}) instead of wipe() keeps
|
|
-- this Lua 5.0 (Turtle) safe.
|
|
if alreadySentBandaidCount >= 1000 then
|
|
alreadySentBandaid = {}
|
|
alreadySentBandaidCount = 0
|
|
end
|
|
end
|
|
|
|
if IsInRaid() or IsInGroup() then
|
|
SendChatMessage(message, _QuestieAnnounce.GetChatMessageChannel())
|
|
elseif Questie.db.profile.questAnnounceLocally == true then
|
|
Questie:Print(message)
|
|
end
|
|
end
|
|
|
|
local playerNameCache
|
|
---@return string
|
|
local function _GetPlayerName()
|
|
playerNameCache = UnitName("player")
|
|
return playerNameCache
|
|
end
|
|
|
|
function QuestieAnnounce:ItemLooted(text, notPlayerName, _, _, playerName)
|
|
if (playerNameCache or _GetPlayerName()) == playerName or (string.len(playerName) == 0 and playerNameCache == notPlayerName) then
|
|
local itemId = tonumber(string.match(text, "item:(%d+)"))
|
|
if not itemId then return end
|
|
local startQuestId = itemCache[itemId]
|
|
-- startQuestId can have boolean false as value, need to compare to nil
|
|
-- check QueryItemSingle because this event can fire before db init is complete
|
|
if (startQuestId == nil) and QuestieDB.QueryItemSingle then
|
|
startQuestId = QuestieDB.QueryItemSingle(itemId, "startQuest")
|
|
-- filter 0 values away so itemCache value is a valid questId if it evaluates to true
|
|
-- we do "or false" here because nil would mean not cached
|
|
startQuestId = (startQuestId and startQuestId > 0) and startQuestId or false
|
|
itemCache[itemId] = startQuestId
|
|
end
|
|
|
|
if startQuestId then
|
|
if not QuestieAnnounce:AnnounceQuestItemLootedToChannel(startQuestId, itemId) then
|
|
_QuestieAnnounce:AnnounceSelf(startQuestId, itemId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function QuestieAnnounce:AcceptedQuest(questId)
|
|
if (_QuestieAnnounce:AnnounceEnabledAndPlayerInChannel()) and Questie.db.profile.questAnnounceAccepted then
|
|
local questLink = QuestieLink:GetQuestLinkStringById(questId)
|
|
|
|
local message = _GetAnnounceMarker() .. l10n("Quest %s: %s", l10n('Accepted'), questLink or "no quest name")
|
|
_QuestieAnnounce:AnnounceToChannel(message)
|
|
end
|
|
end
|
|
|
|
function QuestieAnnounce:AbandonedQuest(questId)
|
|
if (_QuestieAnnounce:AnnounceEnabledAndPlayerInChannel()) and Questie.db.profile.questAnnounceAbandoned then
|
|
local questLink = QuestieLink:GetQuestLinkStringById(questId)
|
|
|
|
local message = _GetAnnounceMarker() .. l10n("Quest %s: %s", l10n('Abandoned'), questLink or "no quest name")
|
|
_QuestieAnnounce:AnnounceToChannel(message)
|
|
end
|
|
end
|
|
|
|
function QuestieAnnounce:CompletedQuest(questId)
|
|
if (_QuestieAnnounce:AnnounceEnabledAndPlayerInChannel()) and Questie.db.profile.questAnnounceCompleted then
|
|
local questLink = QuestieLink:GetQuestLinkStringById(questId)
|
|
|
|
local message = _GetAnnounceMarker() .. l10n("Quest %s: %s", l10n('Completed'), questLink or "no quest name")
|
|
_QuestieAnnounce:AnnounceToChannel(message)
|
|
end
|
|
end
|