initial commit
This commit is contained in:
313
Modules/Nameplates/Plugins/QuestIcons.lua
Normal file
313
Modules/Nameplates/Plugins/QuestIcons.lua
Normal file
@@ -0,0 +1,313 @@
|
||||
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
||||
local NP = E:GetModule('NamePlates')
|
||||
local oUF = E.oUF
|
||||
|
||||
local _G = _G
|
||||
local pairs, ipairs, ceil, floor, tonumber = pairs, ipairs, ceil, floor, tonumber
|
||||
local wipe, strmatch, strlower, strfind = wipe, strmatch, strlower, strfind
|
||||
|
||||
local GetLocale = GetLocale
|
||||
local IsInInstance = IsInInstance
|
||||
local UnitIsPlayer = UnitIsPlayer
|
||||
local GetQuestLogSpecialItemInfo = GetQuestLogSpecialItemInfo
|
||||
local C_QuestLog_GetTitleForLogIndex = C_QuestLog.GetTitleForLogIndex
|
||||
local C_QuestLog_GetNumQuestLogEntries = C_QuestLog.GetNumQuestLogEntries
|
||||
local C_QuestLog_GetQuestIDForLogIndex = C_QuestLog.GetQuestIDForLogIndex
|
||||
local ThreatTooltip = THREAT_TOOLTIP:gsub('%%d', '%%d-')
|
||||
|
||||
local questIcons = {
|
||||
iconTypes = { 'Default', 'Item', 'Skull', 'Chat' },
|
||||
indexByID = {}, --[questID] = questIndex
|
||||
activeQuests = {} --[questTitle] = questID
|
||||
}
|
||||
|
||||
NP.QuestIcons = questIcons
|
||||
|
||||
local typesLocalized = {
|
||||
enUS = {
|
||||
--- short matching applies here so,
|
||||
-- kill: killed, destory: destoryed, etc ...
|
||||
KILL = {'slain', 'destroy', 'eliminate', 'repel', 'kill', 'defeat'},
|
||||
CHAT = {'speak', 'talk'}
|
||||
},
|
||||
deDE = {
|
||||
KILL = {'besiegen', 'besiegt', 'getötet', 'töten', 'tötet', 'vernichtet', 'zerstört', 'genährt'},
|
||||
CHAT = {'befragt', 'sprecht'}
|
||||
},
|
||||
ruRU = {
|
||||
KILL = {'убит', 'уничтож', 'разбомблен', 'разбит', 'сразит'},
|
||||
CHAT = {'поговорит', 'спрашивать'}
|
||||
},
|
||||
esMX = {
|
||||
-- asesinad: asesinado, asesinados, asesinada, asesinadas
|
||||
-- derrota: derrotar, derrotado, derrotados, derrotada, derrotadas
|
||||
-- destrui: destruir, destruido, destruidos, destruida, destruidas
|
||||
-- elimin: eliminar, elimine, eliminadas, eliminada, eliminados, eliminado
|
||||
-- repel: repele, repelido, repelidos, repelida, repelidas
|
||||
KILL = {'asesinad', 'destrui', 'elimin', 'repel', 'derrota'},
|
||||
CHAT = {'habla', 'pídele'}
|
||||
},
|
||||
ptBR = {
|
||||
-- destrui: above but also destruição
|
||||
-- repel: repelir, repelido, repelidos, repelida, repelidas
|
||||
KILL = {'morto', 'morta', 'matar', 'destrui', 'elimin', 'repel', 'derrota'},
|
||||
CHAT = {'falar', 'pedir'}
|
||||
},
|
||||
frFR = {
|
||||
-- tué: tués, tuée, tuées
|
||||
-- abattu: abattus, abattue
|
||||
-- détrui: détruite, détruire, détruit, détruits, détruites
|
||||
-- repouss: repousser, repoussés, repoussée, repoussées
|
||||
-- élimin: éliminer, éliminé, éliminés, éliminée, éliminées
|
||||
KILL = {'tué', 'tuer', 'attaqué', 'attaque', 'abattre', 'abattu', 'détrui', 'élimin', 'repouss', 'vaincu', 'vaincre'},
|
||||
-- demande: demander, demandez
|
||||
-- parle: parler, parlez
|
||||
CHAT = {'parle', 'demande'}
|
||||
},
|
||||
koKR = {
|
||||
KILL = {'쓰러뜨리기', '물리치기', '공격', '파괴'},
|
||||
CHAT = {'대화'}
|
||||
},
|
||||
zhCN = {
|
||||
KILL = {'消灭', '摧毁', '击败', '毁灭', '击退'},
|
||||
CHAT = {'交谈', '谈一谈'}
|
||||
},
|
||||
zhTW = {
|
||||
KILL = {'毀滅', '擊退', '殺死'},
|
||||
CHAT = {'交談', '說話'}
|
||||
},
|
||||
}
|
||||
|
||||
local questTypes = typesLocalized[GetLocale()] or typesLocalized.enUS
|
||||
|
||||
local function CheckTextForQuest(text)
|
||||
local x, y = strmatch(text, '(%d+)/(%d+)')
|
||||
if x and y then
|
||||
return floor(y - x)
|
||||
elseif not strmatch(text, ThreatTooltip) then
|
||||
local progress = tonumber(strmatch(text, '([%d%.]+)%%'))
|
||||
if progress and progress <= 100 then
|
||||
return ceil(100 - progress), true
|
||||
end
|
||||
end
|
||||
end
|
||||
NP.QuestIcons.CheckTextForQuest = CheckTextForQuest
|
||||
|
||||
local function GetQuests(unitID)
|
||||
if IsInInstance() then return end
|
||||
|
||||
E.ScanTooltip:SetOwner(_G.UIParent, 'ANCHOR_NONE')
|
||||
E.ScanTooltip:SetUnit(unitID)
|
||||
E.ScanTooltip:Show()
|
||||
|
||||
local QuestList, notMyQuest, activeID
|
||||
for i = 3, E.ScanTooltip:NumLines() do
|
||||
local str = _G['ElvUI_ScanTooltipTextLeft' .. i]
|
||||
local text = str and str:GetText()
|
||||
if not text or text == '' then return end
|
||||
|
||||
if UnitIsPlayer(text) then
|
||||
notMyQuest = text ~= E.myname
|
||||
elseif text and not notMyQuest then
|
||||
local count, percent = CheckTextForQuest(text)
|
||||
|
||||
-- this line comes from one line up in the tooltip
|
||||
local activeQuest = questIcons.activeQuests[text]
|
||||
if activeQuest then activeID = activeQuest end
|
||||
|
||||
if count then
|
||||
local type, index, texture, _
|
||||
if activeID then
|
||||
index = questIcons.indexByID[activeID]
|
||||
_, texture = GetQuestLogSpecialItemInfo(index)
|
||||
end
|
||||
|
||||
if texture then
|
||||
type = 'QUEST_ITEM'
|
||||
else
|
||||
local lowerText = strlower(text)
|
||||
|
||||
-- check kill type first
|
||||
for _, listText in ipairs(questTypes.KILL) do
|
||||
if strfind(lowerText, listText, nil, true) then
|
||||
type = 'KILL'
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- check chat type if kill type doesn't exist
|
||||
if not type then
|
||||
for _, listText in ipairs(questTypes.CHAT) do
|
||||
if strfind(lowerText, listText, nil, true) then
|
||||
type = 'CHAT'
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not QuestList then QuestList = {} end
|
||||
QuestList[#QuestList + 1] = {
|
||||
isPercent = percent,
|
||||
itemTexture = texture,
|
||||
objectiveCount = count,
|
||||
questType = type or 'DEFAULT',
|
||||
-- below keys are currently unused
|
||||
questLogIndex = index,
|
||||
questID = activeID
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
E.ScanTooltip:Hide()
|
||||
return QuestList
|
||||
end
|
||||
|
||||
local function hideIcons(element)
|
||||
for _, object in pairs(questIcons.iconTypes) do
|
||||
local icon = element[object]
|
||||
icon:Hide()
|
||||
|
||||
if icon.Text then
|
||||
icon.Text:SetText('')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self, event, arg1)
|
||||
local element = self.QuestIcons
|
||||
if not element then return end
|
||||
|
||||
local unit = (event == 'UNIT_NAME_UPDATE' and arg1) or self.unit
|
||||
if unit ~= self.unit then return end
|
||||
|
||||
if element.PreUpdate then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
hideIcons(element)
|
||||
|
||||
local QuestList = GetQuests(unit)
|
||||
if QuestList then
|
||||
element:Show()
|
||||
else
|
||||
element:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
local shownCount
|
||||
for i = 1, #QuestList do
|
||||
local quest = QuestList[i]
|
||||
local objectiveCount = quest.objectiveCount
|
||||
local questType = quest.questType
|
||||
local isPercent = quest.isPercent
|
||||
|
||||
if isPercent or objectiveCount > 0 then
|
||||
local icon
|
||||
if questType == 'DEFAULT' then
|
||||
icon = element.Default
|
||||
elseif questType == 'KILL' then
|
||||
icon = element.Skull
|
||||
elseif questType == 'CHAT' then
|
||||
icon = element.Chat
|
||||
elseif questType == 'QUEST_ITEM' then
|
||||
icon = element.Item
|
||||
end
|
||||
|
||||
if icon and not icon:IsShown() then
|
||||
shownCount = (shownCount and shownCount + 1) or 0
|
||||
|
||||
local size = icon.size or 25
|
||||
local setPosition = icon.position or 'TOPLEFT'
|
||||
local newPosition = E.InversePoints[setPosition]
|
||||
local offset = shownCount * (5 + size)
|
||||
|
||||
icon:Show()
|
||||
icon:ClearAllPoints()
|
||||
icon:Point(newPosition, element, newPosition, (strmatch(setPosition, 'LEFT') and -offset) or offset, 0)
|
||||
|
||||
if questType ~= 'CHAT' and icon.Text and (isPercent or objectiveCount > 1) then
|
||||
icon.Text:SetText((isPercent and objectiveCount..'%') or objectiveCount)
|
||||
end
|
||||
|
||||
if questType == 'QUEST_ITEM' then
|
||||
element.Item:SetTexture(quest.itemTexture)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if element.PostUpdate then
|
||||
return element:PostUpdate()
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
return (self.QuestIcons.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
local function Enable(self)
|
||||
local element = self.QuestIcons
|
||||
if element then
|
||||
element.__owner = self
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if element.Default:IsObjectType('Texture') and not element.Default:GetAtlas() then
|
||||
element.Default:SetAtlas('SmallQuestBang')
|
||||
end
|
||||
if element.Skull:IsObjectType('Texture') and not element.Skull:GetTexture() then
|
||||
element.Skull:SetTexture(E.Media.Textures.SkullIcon)
|
||||
end
|
||||
if element.Chat:IsObjectType('StatusBar') and not element.Chat:GetTexture() then
|
||||
element.Chat:SetTexture([[Interface\WorldMap\ChatBubble_64.PNG]])
|
||||
end
|
||||
|
||||
self:RegisterEvent('QUEST_LOG_UPDATE', Path, true)
|
||||
self:RegisterEvent('UNIT_NAME_UPDATE', Path, true)
|
||||
self:RegisterEvent('PLAYER_ENTERING_WORLD', Path, true)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
local element = self.QuestIcons
|
||||
if element then
|
||||
element:Hide()
|
||||
hideIcons(element)
|
||||
|
||||
self:UnregisterEvent('QUEST_LOG_UPDATE', Path)
|
||||
self:UnregisterEvent('UNIT_NAME_UPDATE', Path)
|
||||
self:UnregisterEvent('PLAYER_ENTERING_WORLD', Path)
|
||||
end
|
||||
end
|
||||
|
||||
local frame = CreateFrame('Frame')
|
||||
frame:RegisterEvent('QUEST_ACCEPTED')
|
||||
frame:RegisterEvent('QUEST_REMOVED')
|
||||
frame:RegisterEvent('PLAYER_ENTERING_WORLD')
|
||||
frame:SetScript('OnEvent', function(self, event)
|
||||
wipe(questIcons.indexByID)
|
||||
wipe(questIcons.activeQuests)
|
||||
|
||||
for i = 1, C_QuestLog_GetNumQuestLogEntries() do
|
||||
local id = C_QuestLog_GetQuestIDForLogIndex(i)
|
||||
if id and id > 0 then
|
||||
questIcons.indexByID[id] = i
|
||||
|
||||
local title = C_QuestLog_GetTitleForLogIndex(i)
|
||||
if title then questIcons.activeQuests[title] = id end
|
||||
end
|
||||
end
|
||||
|
||||
if event == 'PLAYER_ENTERING_WORLD' then
|
||||
self:UnregisterEvent(event)
|
||||
end
|
||||
end)
|
||||
|
||||
oUF:AddElement('QuestIcons', Path, Enable, Disable)
|
||||
Reference in New Issue
Block a user