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.

463 lines
14 KiB

-------------------------------------------------------------------------------
---------------------------------- NAMESPACE ----------------------------------
-------------------------------------------------------------------------------
local ADDON_NAME, ns = ...
local Class = ns.Class
local L = ns.locale
local Green = ns.status.Green
local Orange = ns.status.Orange
local Red = ns.status.Red
-------------------------------------------------------------------------------
local function Icon(icon) return '|T'..icon..':0:0:1:-1|t ' end
-- in zhCN’s built-in font, ARHei.ttf, the glyph of U+2022 <bullet> is missing.
-- use U+00B7 <middle dot> instead.
local bullet = (GetLocale() == "zhCN" and "·" or "")
-------------------------------------------------------------------------------
----------------------------------- REWARD ------------------------------------
-------------------------------------------------------------------------------
local Reward = Class('Reward')
function Reward:Initialize(attrs)
if attrs then
for k, v in pairs(attrs) do self[k] = v end
end
end
function Reward:IsEnabled()
if self.class and self.class ~= ns.class then return false end
if self.faction and self.faction ~= ns.faction then return false end
if self.display_option and not ns:GetOpt(self.display_option) then return false end
return true
end
function Reward:IsObtainable() return true end
function Reward:IsObtained() return true end
-- These functions drive the appearance of the tooltip
function Reward:GetLines() return function () end end
function Reward:GetCategoryIcon() end
function Reward:GetStatus() end
function Reward:GetText() return UNKNOWN end
function Reward:Prepare() end
function Reward:Render(tooltip)
local text = self:GetText()
local status = self:GetStatus()
-- Add category icon (if registered)
local icon = self:GetCategoryIcon()
if text and icon then
text = Icon(icon)..text
end
-- Add indent if requested
if self.indent then
text = ' '..text
end
-- Render main line and optional status
if text and status then
tooltip:AddDoubleLine(text, status)
elseif text then
tooltip:AddLine(text)
end
-- Render follow-up lines (example: achievement criteria)
for text, status, r, g, b in self:GetLines() do
if text and status then
tooltip:AddDoubleLine(text, status, r, g, b)
elseif text then
tooltip:AddLine(text, r, g, b)
end
end
end
-------------------------------------------------------------------------------
----------------------------------- SECTION -----------------------------------
-------------------------------------------------------------------------------
local Section = Class('Section', Reward)
function Section:Initialize(title)
self.title = title
end
function Section:IsEnabled() return true end
function Section:Prepare()
ns.PrepareLinks(self.title)
end
function Section:Render(tooltip)
tooltip:AddLine(ns.RenderLinks(self.title, true)..':')
end
-------------------------------------------------------------------------------
----------------------------------- SPACER ------------------------------------
-------------------------------------------------------------------------------
local Spacer = Class('Spacer', Reward)
function Spacer:IsEnabled() return true end
function Spacer:Render(tooltip)
tooltip:AddLine(' ')
end
-------------------------------------------------------------------------------
--------------------------------- ACHIEVEMENT ---------------------------------
-------------------------------------------------------------------------------
local Achievement = Class('Achievement', Reward)
local GetCriteriaInfo = function (id, criteria)
local results = {GetAchievementCriteriaInfoByID(id, criteria)}
if not results[1] then
if criteria <= GetAchievementNumCriteria(id) then
results = {GetAchievementCriteriaInfo(id, criteria)}
else
ns.Error('unknown achievement criteria ('..id..', '..criteria..')')
return UNKNOWN
end
end
return unpack(results)
end
function Achievement:Initialize(attrs)
Reward.Initialize(self, attrs)
self.criteria = ns.AsIDTable(self.criteria)
end
function Achievement:IsObtained()
local _,_,_,completed,_,_,_,_,_,_,_,_,earnedByMe = GetAchievementInfo(self.id)
completed = completed and (not ns:GetOpt('use_char_achieves') or earnedByMe)
if completed then return true end
if self.criteria then
for i, c in ipairs(self.criteria) do
local _, _, completed = GetCriteriaInfo(self.id, c.id)
if not completed then return false end
end
return true
end
return false
end
function Achievement:GetText()
local _,name,_,_,_,_,_,_,_,icon = GetAchievementInfo(self.id)
return Icon(icon)..ACHIEVEMENT_COLOR_CODE..'['..name..']|r'
end
function Achievement:GetStatus()
if not self.oneline and self.criteria then return end
return self:IsObtained() and Green(L['completed']) or Red(L['incomplete'])
end
function Achievement:GetLines()
local completed = self:IsObtained()
local index = 0
return function ()
-- ignore sub-lines if oneline is enabled or no criteria were given
if self.oneline or not self.criteria then return end
-- increment our criteria counter
index = index + 1
if index > #self.criteria then return end
local c = self.criteria[index]
local cname, _, ccomp, qty, req = GetCriteriaInfo(self.id, c.id)
if (cname == '' or c.qty) then
cname = c.suffix or cname
cname = (completed and req..'/'..req or qty..'/'..req)..' '..cname
end
local r, g, b = .6, .6, .6
local ctext = " "..bullet.." "..cname
if (completed or ccomp) then
r, g, b = 0, 1, 0
end
local note, status = c.note
if c.quest then
if C_QuestLog.IsQuestFlaggedCompleted(c.quest) then
status = ns.status.Green(L['defeated'])
else
status = ns.status.Red(L['undefeated'])
end
note = note and (note..' '..status) or status
end
return ctext, note, r, g, b
end
end
-------------------------------------------------------------------------------
----------------------------------- CURRENCY ----------------------------------
-------------------------------------------------------------------------------
local Currency = Class('Currency', Reward)
function Currency:GetText()
local info = C_CurrencyInfo.GetCurrencyInfo(self.id)
local text = C_CurrencyInfo.GetCurrencyLink(self.id, 0)
if self.note then -- additional info
text = text..' ('..self.note..')'
end
return Icon(info.iconFileID)..text
end
-------------------------------------------------------------------------------
------------------------------------ ITEM -------------------------------------
-------------------------------------------------------------------------------
local Item = Class('Item', Reward)
function Item:Initialize(attrs)
Reward.Initialize(self, attrs)
if not self.item then
error('Item() reward requires an item id to be set')
end
self.itemLink = L["retrieving"]
self.itemIcon = 'Interface\\Icons\\Inv_misc_questionmark'
local item = _G.Item:CreateFromItemID(self.item)
if not item:IsItemEmpty() then
item:ContinueOnItemLoad(function()
self.itemLink = item:GetItemLink()
self.itemIcon = item:GetItemIcon()
end)
end
end
function Item:Prepare()
ns.PrepareLinks(self.note)
end
function Item:IsObtained()
if self.quest then return C_QuestLog.IsQuestFlaggedCompleted(self.quest) end
return true
end
function Item:GetText()
local text = self.itemLink
if self.type then -- mount, pet, toy, etc
text = text..' ('..self.type..')'
end
if self.note then -- additional info
text = text..' ('..ns.RenderLinks(self.note, true)..')'
end
return Icon(self.itemIcon)..text
end
function Item:GetStatus()
if self.status then
return format('(%s)', self.status)
elseif self.quest then
local completed = C_QuestLog.IsQuestFlaggedCompleted(self.quest)
return completed and Green(L['completed']) or Red(L['incomplete'])
elseif self.weekly then
local completed = C_QuestLog.IsQuestFlaggedCompleted(self.weekly)
return completed and Green(L['weekly']) or Red(L['weekly'])
end
end
-------------------------------------------------------------------------------
------------------------------------ MOUNT ------------------------------------
-------------------------------------------------------------------------------
local Mount = Class('Mount', Item, {
display_option='show_mount_rewards',
type=L["mount"]
})
function Mount:IsObtained()
return select(11, C_MountJournal.GetMountInfoByID(self.id))
end
function Mount:GetStatus()
local collected = select(11, C_MountJournal.GetMountInfoByID(self.id))
return collected and Green(L["known"]) or Red(L["missing"])
end
-------------------------------------------------------------------------------
------------------------------------- PET -------------------------------------
-------------------------------------------------------------------------------
local Pet = Class('Pet', Item, {
display_option='show_pet_rewards',
type=L["pet"]
})
function Pet:Initialize(attrs)
if attrs.item then
Item.Initialize(self, attrs)
else
Reward.Initialize(self, attrs)
local name, icon = C_PetJournal.GetPetInfoBySpeciesID(self.id)
self.itemIcon = icon
self.itemLink = '|cff1eff00['..name..']|r'
end
end
function Pet:IsObtained()
return C_PetJournal.GetNumCollectedInfo(self.id) > 0
end
function Pet:GetStatus()
local n, m = C_PetJournal.GetNumCollectedInfo(self.id)
return (n > 0) and Green(n..'/'..m) or Red(n..'/'..m)
end
-------------------------------------------------------------------------------
------------------------------------ QUEST ------------------------------------
-------------------------------------------------------------------------------
local Quest = Class('Quest', Reward)
function Quest:Initialize(attrs)
Reward.Initialize(self, attrs)
if type(self.id) == 'number' then
self.id = {self.id}
end
C_QuestLog.GetTitleForQuestID(self.id[1]) -- fetch info from server
end
function Quest:IsObtained()
for i, id in ipairs(self.id) do
if not C_QuestLog.IsQuestFlaggedCompleted(id) then return false end
end
return true
end
function Quest:GetText()
local name = C_QuestLog.GetTitleForQuestID(self.id[1])
return ns.GetIconLink('quest_ay', 13)..' '..(name or UNKNOWN)
end
function Quest:GetStatus()
if #self.id == 1 then
local completed = C_QuestLog.IsQuestFlaggedCompleted(self.id[1])
return completed and Green(L['completed']) or Red(L['incomplete'])
else
local count = 0
for i, id in ipairs(self.id) do
if C_QuestLog.IsQuestFlaggedCompleted(id) then count = count + 1 end
end
local status = count..'/'..#self.id
return (count == #self.id) and Green(status) or Red(status)
end
end
-------------------------------------------------------------------------------
------------------------------------ SPELL ------------------------------------
-------------------------------------------------------------------------------
local Spell = Class('Spell', Item, { type = L["spell"] })
function Spell:IsObtained()
return IsSpellKnown(self.spell)
end
function Spell:GetStatus()
local collected = IsSpellKnown(self.spell)
return collected and Green(L["known"]) or Red(L["missing"])
end
-------------------------------------------------------------------------------
------------------------------------- TOY -------------------------------------
-------------------------------------------------------------------------------
local Toy = Class('Toy', Item, {
display_option='show_toy_rewards',
type=L["toy"]
})
function Toy:IsObtained()
return PlayerHasToy(self.item)
end
function Toy:GetStatus()
local collected = PlayerHasToy(self.item)
return collected and Green(L["known"]) or Red(L["missing"])
end
-------------------------------------------------------------------------------
---------------------------------- TRANSMOG -----------------------------------
-------------------------------------------------------------------------------
local Transmog = Class('Transmog', Item, {
display_option='show_transmog_rewards'
})
local CTC = C_TransmogCollection
function Transmog:Initialize(attrs)
Item.Initialize(self, attrs)
if self.slot then
self.type = self.slot -- backwards compat
end
end
function Transmog:IsObtained()
-- Check if the player knows the appearance
if CTC.PlayerHasTransmog(self.item) then return true end
-- Verify the item drops for any of the players specs
local specs = GetItemSpecInfo(self.item)
if type(specs) == 'table' and #specs == 0 then return true end
-- Verify the player can learn the item's appearance
local sourceID = select(2, CTC.GetItemInfo(self.item))
if sourceID then
local infoReady, canCollect = CTC.PlayerCanCollectSource(sourceID)
if infoReady and not canCollect then return true end
end
return false
end
function Transmog:GetStatus()
local collected = CTC.PlayerHasTransmog(self.item)
local status = collected and Green(L["known"]) or Red(L["missing"])
if not collected then
-- check if we can't learn this item
local sourceID = select(2, CTC.GetItemInfo(self.item))
if not (sourceID and select(2, CTC.PlayerCanCollectSource(sourceID))) then
status = Orange(L["unlearnable"])
else
-- check if the item doesn't drop
local specs = GetItemSpecInfo(self.item)
if type(specs) == 'table' and #specs == 0 then
status = Orange(L["unobtainable"])
end
end
end
return status
end
-------------------------------------------------------------------------------
ns.reward = {
Reward=Reward,
Section=Section,
Spacer=Spacer,
Achievement=Achievement,
Currency=Currency,
Item=Item,
Mount=Mount,
Pet=Pet,
Quest=Quest,
Spell=Spell,
Toy=Toy,
Transmog=Transmog
}