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.
1646 lines
52 KiB
1646 lines
52 KiB
local _, addonTable = ...
|
|
|
|
-- Upvalues
|
|
local R = Rarity
|
|
local GUI = Rarity.GUI
|
|
local CONSTANTS = addonTable.constants
|
|
|
|
--- WoW API
|
|
local GetItemInfo = _G.C_Item.GetItemInfo
|
|
local GetBestMapForUnit = C_Map.GetBestMapForUnit
|
|
local IsWorldQuestActive = C_TaskQuest.IsActive
|
|
local IsQuestFlaggedCompleted = _G.C_QuestLog.IsQuestFlaggedCompleted
|
|
local C_Covenants = _G.C_Covenants
|
|
|
|
local FormatTime = Rarity.Utils.PrettyPrint.FormatTime
|
|
local sort2 = Rarity.Utils.Sorting.sort2
|
|
local GetDate = Rarity.Utils.Time.GetDate
|
|
local AuctionDB = Rarity.AuctionDB
|
|
local scanTip = Rarity.GUI.scanTip
|
|
local GetMapNameByID = Rarity.MapInfo.GetMapNameByID
|
|
|
|
-- Main window
|
|
-- LibQTip stuff
|
|
|
|
-- Externals
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("Rarity")
|
|
local lbz = LibStub("LibBabble-Zone-3.0"):GetUnstrictLookupTable()
|
|
local lbsz = LibStub("LibBabble-SubZone-3.0"):GetUnstrictLookupTable()
|
|
local lbb = LibStub("LibBabble-Boss-3.0"):GetUnstrictLookupTable()
|
|
|
|
-- Settings
|
|
local STATUS_TOOLTIP_MAX_WIDTH = 200
|
|
|
|
-- Locals
|
|
local tooltip, tooltip2, quicktip
|
|
local renderingQuicktip = false
|
|
local numHolidayReminders = 0
|
|
local showedHolidayReminderOverflow = false
|
|
local renderingTip = false
|
|
local headers = {}
|
|
|
|
-- Constants
|
|
-- Sort parameters
|
|
local SORT_NONE = CONSTANTS.SORT_METHODS.SORT_NONE
|
|
local SORT_NAME = CONSTANTS.SORT_METHODS.SORT_NAME
|
|
local SORT_DIFFICULTY = CONSTANTS.SORT_METHODS.SORT_DIFFICULTY
|
|
local SORT_PROGRESS = CONSTANTS.SORT_METHODS.SORT_PROGRESS
|
|
local SORT_CATEGORY = CONSTANTS.SORT_METHODS.SORT_CATEGORY
|
|
local SORT_ZONE = CONSTANTS.SORT_METHODS.SORT_ZONE
|
|
-- Tooltip formatting
|
|
local TIP_LEFT = "TIP_LEFT"
|
|
local TIP_RIGHT = "TIP_RIGHT"
|
|
local TIP_HIDDEN = "TIP_HIDDEN"
|
|
-- Categories of origin
|
|
local HOLIDAY = "HOLIDAY"
|
|
-- Types of items
|
|
local MOUNT = "MOUNT"
|
|
local PET = "PET"
|
|
local ITEM = "ITEM"
|
|
-- Color codes
|
|
local red = Rarity.Enum.Colors.Red
|
|
local blue = Rarity.Enum.Colors.Blue
|
|
local green = Rarity.Enum.Colors.Green
|
|
local yellow = Rarity.Enum.Colors.Yellow
|
|
local gray = Rarity.Enum.Colors.Gray
|
|
local white = Rarity.Enum.Colors.White
|
|
|
|
-- Addon-scoped functions
|
|
function R:InTooltip()
|
|
return Rarity.Tooltips:IsTooltipAcquired("RarityTooltip")
|
|
end
|
|
|
|
function R:HideQuicktip()
|
|
if quicktip and quicktip:IsVisible() then
|
|
quicktip:Release()
|
|
end
|
|
end
|
|
|
|
function R:ShowQuicktip(hidden)
|
|
if renderingQuicktip then
|
|
return
|
|
end
|
|
renderingQuicktip = true
|
|
|
|
if Rarity.Tooltips:IsTooltipAcquired("RarityQuicktip") and quicktip then
|
|
-- Don't show the tooltip if it's already showing
|
|
if quicktip:IsVisible() then
|
|
renderingQuicktip = false
|
|
return
|
|
end
|
|
quicktip:Clear()
|
|
else
|
|
quicktip = Rarity.Tooltips:AcquireTooltip("RarityQuicktip", 3, "LEFT", "LEFT")
|
|
-- intentionally one column more than we need to avoid text clipping
|
|
quicktip:SetScale(self.db.profile.tooltipScale or 1)
|
|
end
|
|
|
|
quicktip:AddHeader(L["Rarity"])
|
|
quicktip:AddSeparator(1, 1, 1, 1, 1)
|
|
quicktip:AddLine(L["Left click"], L["Open Rarity window"])
|
|
quicktip:AddLine(L["Right click"], L["Toggle tracker"])
|
|
quicktip:AddLine(L["Shift + Left click"], L["Open settings"])
|
|
quicktip:AddLine(L["Ctrl + Left click"], L["Change sorting"])
|
|
|
|
quicktip:SetAutoHideDelay(0.1, Rarity.frame, function()
|
|
quicktip = nil
|
|
Rarity.Tooltips:ReleaseTooltip("RarityQuicktip")
|
|
end)
|
|
|
|
quicktip:SmartAnchorTo(Rarity.frame)
|
|
quicktip:UpdateScrolling()
|
|
quicktip:Show()
|
|
|
|
renderingQuicktip = false
|
|
end
|
|
|
|
function R:HideTooltip()
|
|
if tooltip:IsVisible() then
|
|
tooltip:Release()
|
|
end
|
|
end
|
|
|
|
-- Local functions
|
|
|
|
local function colorizeV(s, r, g, b)
|
|
if r and g and b and s then
|
|
return format("|cff%02x%02x%02x%s|r", (r or 1) * 255, (g or 1) * 255, (b or 1) * 255, s)
|
|
else
|
|
return s
|
|
end
|
|
end
|
|
|
|
local function tooltip2AddDoubleLine(value1, value2)
|
|
local lineIndex = tooltip2:AddLine()
|
|
local labelProvider = Rarity.Tooltips:GetLabelProvider()
|
|
tooltip2:SetCell(lineIndex, 1, value1, nil, nil, 1, labelProvider, nil, nil, STATUS_TOOLTIP_MAX_WIDTH)
|
|
tooltip2:SetCell(lineIndex, 2, value2)
|
|
end
|
|
|
|
local colorize = Rarity.Utils.String.Colorize
|
|
|
|
-- Local functions
|
|
|
|
local function onClickItem(cell, item)
|
|
local trackedItem = Rarity.Tracking:GetTrackedItem()
|
|
|
|
if IsShiftKeyDown() then
|
|
if not item or type(item) ~= "table" or not item.itemId then
|
|
return
|
|
end
|
|
local v = item
|
|
local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, itemSellPrice =
|
|
GetItemInfo(v.itemId)
|
|
local attempts = v.attempts or 0
|
|
if v.lastAttempts then
|
|
attempts = attempts - v.lastAttempts
|
|
end
|
|
local dropChance = Rarity.Statistics.GetRealDropPercentage(v)
|
|
local chance = 100 * (1 - math.pow(1 - dropChance, attempts))
|
|
local medianLoots = Round(math.log(1 - 0.5) / math.log(1 - dropChance))
|
|
local lucky = L["lucky"]
|
|
if medianLoots < attempts then
|
|
lucky = L["unlucky"]
|
|
end
|
|
local s = format(L["%s: 0/%d attempts so far (%.2f%% - %s)"], itemLink or item.name, attempts, chance, lucky)
|
|
if attempts == 1 then
|
|
s = format(L["%s: 0/%d attempt so far (%.2f%% - %s)"], itemLink or item.name, attempts, chance, lucky)
|
|
end
|
|
if attempts <= 0 then
|
|
s = format("%s", itemLink or item.name)
|
|
end
|
|
ChatEdit_InsertLink(s)
|
|
elseif IsControlKeyDown() then
|
|
if not item or type(item) ~= "table" or not item.itemId then
|
|
return
|
|
end
|
|
if item.coords ~= nil and type(item.coords) == "table" then
|
|
local added = 0
|
|
local instance = 0
|
|
for _, coord in pairs(item.coords) do
|
|
local good = false
|
|
if coord.q ~= nil then
|
|
if IsQuestFlaggedCompleted(coord.q) == false then
|
|
good = true
|
|
end
|
|
else
|
|
good = true
|
|
end
|
|
if
|
|
good
|
|
and TomTom ~= nil
|
|
and TomTom.AddWaypoint ~= nil
|
|
and coord.m ~= nil
|
|
and coord.x ~= nil
|
|
and coord.y ~= nil
|
|
then
|
|
local extraName = ""
|
|
if coord.n ~= nil then
|
|
extraName = " (" .. coord.n .. ")"
|
|
end
|
|
if coord.i ~= true then
|
|
TomTom:AddWaypoint(
|
|
coord.m,
|
|
coord.x / 100.0,
|
|
coord.y / 100.0,
|
|
{ title = item.name .. extraName, from = "Rarity" }
|
|
)
|
|
added = added + 1
|
|
end
|
|
if coord.i == true then
|
|
instance = instance + 1
|
|
end
|
|
if TomTom.SetClosestWaypoint ~= nil then
|
|
TomTom:SetClosestWaypoint()
|
|
end
|
|
end
|
|
end
|
|
if added > 0 then
|
|
Rarity:Print(format(L["Added %d |4waypoint:waypoints; to TomTom"], added))
|
|
end
|
|
if instance > 0 then
|
|
Rarity:Print(
|
|
format(
|
|
L["%d |4waypoint:waypoints; |4is:are; located inside |4an instance:instances; and |4was:were; not added"],
|
|
instance
|
|
)
|
|
)
|
|
end
|
|
end
|
|
else
|
|
if trackedItem ~= item and Rarity.Session:IsActive() then
|
|
Rarity.Session:End()
|
|
end
|
|
Rarity.Tracking:SetTrackedItem(nil, 2)
|
|
Rarity.Tracking:Update(item)
|
|
end
|
|
end
|
|
|
|
local function tooltip2AddLine(value)
|
|
local lineIndex = tooltip2:AddLine()
|
|
local labelProvider = Rarity.Tooltips:GetLabelProvider()
|
|
tooltip2:SetCell(lineIndex, 1, value, nil, nil, 2, labelProvider, nil, nil, STATUS_TOOLTIP_MAX_WIDTH)
|
|
end
|
|
|
|
local function showSubTooltip(cell, item)
|
|
if not item or not item.itemId then
|
|
return
|
|
end
|
|
|
|
if Rarity.Tooltips:IsTooltipAcquired("RaritySubTooltip") and tooltip2 then
|
|
Rarity.Tooltips:ReleaseTooltip(tooltip2)
|
|
tooltip2 = nil
|
|
end
|
|
tooltip2 = Rarity.Tooltips:AcquireTooltip("RaritySubTooltip", 3, "LEFT", "RIGHT")
|
|
tooltip2:ClearAllPoints()
|
|
tooltip2:SetClampedToScreen(true)
|
|
|
|
if R.db.profile.statusTip == TIP_RIGHT then
|
|
tooltip2:SetPoint("LEFT", cell, "RIGHT", 30, 0)
|
|
elseif R.db.profile.statusTip == TIP_LEFT then
|
|
tooltip2:SetPoint("RIGHT", cell, "LEFT", -30, 0)
|
|
end
|
|
|
|
local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, itemSellPrice
|
|
|
|
_, -- itemName,
|
|
itemLink,
|
|
itemRarity,
|
|
itemLevel,
|
|
itemMinLevel,
|
|
itemType,
|
|
itemSubType,
|
|
itemStackCount,
|
|
itemEquipLoc,
|
|
itemTexture,
|
|
itemSellPrice =
|
|
GetItemInfo(item.itemId)
|
|
|
|
-- Rarity extended information tooltip
|
|
if R.db.profile.statusTip == TIP_HIDDEN then
|
|
return
|
|
end
|
|
|
|
if itemTexture ~= nil then
|
|
tooltip2:AddHeader(itemLink or item.name, "|T" .. itemTexture .. ":22|t")
|
|
else
|
|
tooltip2:AddHeader(itemLink or item.name)
|
|
end
|
|
scanTip:ClearLines()
|
|
if item.isToy then
|
|
scanTip:SetToyByItemID(item.itemId)
|
|
else
|
|
scanTip:SetItemByID(item.itemId)
|
|
end
|
|
for i = 2, scanTip:NumLines() do
|
|
local myLeft = _G["__Rarity_ScanTipTextLeft" .. i]
|
|
local txtLeft = myLeft:GetText()
|
|
local leftR, leftG, leftB, leftAlpha = myLeft:GetTextColor()
|
|
local myRight = _G["__Rarity_ScanTipTextRight" .. i]
|
|
local txtRight = myRight:GetText()
|
|
local rightR, rightG, rightB, rightAlpha = myRight:GetTextColor()
|
|
if txtRight then
|
|
tooltip2AddDoubleLine(colorizeV(txtLeft, leftR, leftG, leftB), colorizeV(txtRight, rightR, rightG, rightB))
|
|
else
|
|
tooltip2AddLine(colorizeV(txtLeft, leftR, leftG, leftB))
|
|
end
|
|
end
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
|
|
local catIcon = ""
|
|
if item.cat and Rarity.catIcons[item.cat] then
|
|
catIcon = [[ |TInterface\AddOns\Rarity\Icons\]] .. Rarity.catIcons[item.cat] .. ".blp:0:4|t"
|
|
end
|
|
if R.string_types[item.type] ~= nil then
|
|
tooltip2AddLine(colorize((R.string_types[item.type] or "UNKNOWN") .. catIcon, yellow))
|
|
end
|
|
if item.groupSize and item.groupSize > 1 then
|
|
tooltip2AddLine(colorize(format(L["Usually requires a group of around %d players"], item.groupSize), red))
|
|
end
|
|
if item.method == CONSTANTS.DETECTION_METHODS.SPECIAL and item.obtain then
|
|
tooltip2AddLine(colorize(item.obtain, blue))
|
|
else
|
|
local actualMethod = item.method
|
|
if item.method == CONSTANTS.DETECTION_METHODS.BOSS and item.groupSize and item.groupSize > 1 then
|
|
actualMethod = CONSTANTS.DETECTION_METHODS.BOSS
|
|
else
|
|
if item.method == CONSTANTS.DETECTION_METHODS.BOSS then
|
|
actualMethod = CONSTANTS.DETECTION_METHODS.NPC
|
|
end
|
|
end
|
|
tooltip2AddLine(colorize(R.string_methods[actualMethod], blue))
|
|
end
|
|
if item.pickpocket then
|
|
local class, classFileName = UnitClass("player")
|
|
local pickcolor
|
|
if classFileName == "ROGUE" then
|
|
pickcolor = green
|
|
else
|
|
pickcolor = red
|
|
end
|
|
tooltip2AddLine(colorize(L["Requires Pickpocketing"], pickcolor))
|
|
end
|
|
if item.method == CONSTANTS.DETECTION_METHODS.ZONE or item.method == CONSTANTS.DETECTION_METHODS.FISHING then
|
|
if item.zones and type(item.zones) == "table" then
|
|
for k, v in pairs(item.zones) do
|
|
local zone = lbz[v]
|
|
if not zone then
|
|
zone = lbsz[v]
|
|
end
|
|
if not zone then
|
|
-- zone = v -- Why?
|
|
end
|
|
if not tonumber(v) then
|
|
tooltip2AddLine(colorize(" " .. v, gray))
|
|
end
|
|
end
|
|
end
|
|
elseif item.method == CONSTANTS.DETECTION_METHODS.ARCH then
|
|
if item.raceId then
|
|
tooltip2AddLine(colorize(" " .. R.string_archraces[item.raceId], gray))
|
|
end
|
|
elseif item.method == CONSTANTS.DETECTION_METHODS.USE then
|
|
if item.items and type(item.items) == "table" then
|
|
for k, v in pairs(item.items) do
|
|
_, -- itemName,
|
|
itemLink,
|
|
itemRarity,
|
|
itemLevel,
|
|
itemMinLevel,
|
|
itemType,
|
|
itemSubType,
|
|
itemStackCount,
|
|
itemEquipLoc,
|
|
_, -- itemTexture,
|
|
itemSellPrice =
|
|
GetItemInfo(v)
|
|
if itemLink then
|
|
tooltip2AddLine(" " .. itemLink)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Source text, bonus satchel, black market, etc.
|
|
local hadSource = false
|
|
if
|
|
item.type == CONSTANTS.ITEM_TYPES.MOUNT
|
|
and item.spellId ~= nil
|
|
and Rarity.mount_sources[item.spellId] ~= nil
|
|
then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
tooltip2AddLine(Rarity.mount_sources[item.spellId])
|
|
hadSource = true
|
|
end
|
|
if
|
|
item.type == CONSTANTS.ITEM_TYPES.PET
|
|
and item.creatureId ~= nil
|
|
and Rarity.pet_sources[item.creatureId] ~= nil
|
|
then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
tooltip2AddLine(Rarity.pet_sources[item.creatureId])
|
|
hadSource = true
|
|
end
|
|
if item.sourceText ~= nil and item.sourceText ~= "" then
|
|
tooltip2AddLine(item.sourceText)
|
|
hadSource = true
|
|
end
|
|
if item.worldBossFactionless then
|
|
tooltip2AddLine(
|
|
colorize(
|
|
L["All players can participate in killing this world boss once per week, regardless of faction"],
|
|
blue
|
|
)
|
|
)
|
|
end
|
|
if item.wasGuaranteed then
|
|
tooltip2AddLine(
|
|
colorize(L["This was a guaranteed drop for players who defeated the encounter when it was current"], blue)
|
|
)
|
|
end
|
|
if item.bonusSatchel then
|
|
tooltip2AddLine(colorize(L["Contained in bonus satchels"], yellow))
|
|
end
|
|
if item.blackMarket then
|
|
tooltip2AddLine(colorize(L["Appears in the Black Market"], yellow))
|
|
end
|
|
if item.enableCoin then
|
|
tooltip2AddLine(colorize(L["Can be obtained with a bonus roll"], yellow))
|
|
end
|
|
if item.requiresAlliance then
|
|
tooltip2AddLine(
|
|
colorize(L["This item is only obtainable by Alliance players"], R.Caching:IsAlliance() and green or red)
|
|
)
|
|
end
|
|
if item.requiresHorde then
|
|
tooltip2AddLine(
|
|
colorize(L["This item is only obtainable by Horde players"], R.Caching:IsHorde() and green or red)
|
|
)
|
|
end
|
|
if
|
|
hadSource
|
|
or item.bonusSatchel
|
|
or item.blackMarket
|
|
or item.wasGuaranteed
|
|
or item.worldBossFactionless
|
|
or item.requiresAlliance
|
|
or item.requiresHorde
|
|
then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
end
|
|
|
|
-- Zone(s)
|
|
local zoneText = ""
|
|
local currentZone = GetBestMapForUnit("player")
|
|
if item.coords ~= nil and type(item.coords) == "table" then
|
|
local zoneList = {}
|
|
for _, zoneValue in pairs(item.coords) do
|
|
if type(zoneValue) == "table" and zoneValue.m ~= nil then
|
|
local doThisZone = false
|
|
if zoneList[zoneValue.m] == nil then
|
|
zoneList[zoneValue.m] = true
|
|
doThisZone = true
|
|
end
|
|
if doThisZone then
|
|
if zoneText ~= "" then
|
|
zoneText = zoneText .. ", "
|
|
end
|
|
if currentZone == zoneValue.m then
|
|
zoneText = zoneText .. colorize(GetMapNameByID(zoneValue.m) or "", green)
|
|
else
|
|
zoneText = zoneText .. colorize(GetMapNameByID(zoneValue.m) or "", gray)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if zoneText ~= "" then
|
|
tooltip2AddLine(L["Found in: "] .. zoneText)
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
end
|
|
end
|
|
|
|
-- Collection info
|
|
if item.method == CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
local collectText = ""
|
|
if type(item.collectedItemId) ~= "table" then
|
|
itemName,
|
|
itemLink,
|
|
itemRarity,
|
|
itemLevel,
|
|
itemMinLevel,
|
|
itemType,
|
|
itemSubType,
|
|
itemStackCount,
|
|
itemEquipLoc,
|
|
_, -- itemTexture,
|
|
itemSellPrice =
|
|
GetItemInfo(item.collectedItemId)
|
|
collectText = itemLink or itemName or ""
|
|
else
|
|
for k, v in pairs(item.collectedItemId) do
|
|
itemName,
|
|
itemLink,
|
|
itemRarity,
|
|
itemLevel,
|
|
itemMinLevel,
|
|
itemType,
|
|
itemSubType,
|
|
itemStackCount,
|
|
itemEquipLoc,
|
|
_, -- itemTexture,
|
|
itemSellPrice =
|
|
GetItemInfo(v)
|
|
if collectText ~= "" then
|
|
collectText = collectText .. ", "
|
|
end
|
|
collectText = collectText .. (itemLink or itemName or "")
|
|
end
|
|
end
|
|
tooltip2AddLine(colorize(format(L["Collect %d %s"], item.chance or 100, collectText), white))
|
|
if item.obtain then
|
|
tooltip2AddLine(colorize(item.obtain, white))
|
|
end
|
|
else
|
|
tooltip2AddLine(colorize(format(L["1 in %d chance"], item.chance or 100), white))
|
|
end
|
|
local dropChance = Rarity.Statistics.GetRealDropPercentage(item)
|
|
local medianLoots = Round(math.log(1 - 0.5) / math.log(1 - dropChance))
|
|
if item.method ~= CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
tooltip2AddLine(colorize(format(L["Lucky if you obtain in %d or less"], medianLoots), gray))
|
|
end
|
|
|
|
-- Time and progress
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
local len = (Rarity.Session:GetLastTime() or 0) - (Rarity.Session:GetStartTime() or 0)
|
|
local tracked = Rarity.Tracking:FindTrackedItem()
|
|
if not Rarity.Session:IsActive() or not len or tracked ~= item then
|
|
len = 0
|
|
end
|
|
|
|
if item.totalFinds and item.method ~= CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
tooltip2AddLine(colorize(L["Since last drop"], yellow))
|
|
end
|
|
local attempts = (item.attempts or 0) - (item.lastAttempts or 0)
|
|
if item.method == CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
tooltip2AddDoubleLine(L["Collected"], attempts)
|
|
else
|
|
tooltip2AddDoubleLine(L["Attempts"], attempts)
|
|
end
|
|
if
|
|
item.method == CONSTANTS.DETECTION_METHODS.NPC
|
|
or item.method == CONSTANTS.DETECTION_METHODS.ZONE
|
|
or item.method == CONSTANTS.DETECTION_METHODS.FISHING
|
|
or item.method == CONSTANTS.DETECTION_METHODS.USE
|
|
then
|
|
tooltip2AddDoubleLine(L["Time spent farming"], FormatTime((item.time or 0) - (item.lastTime or 0) + len))
|
|
end
|
|
if attempts > 0 then
|
|
if item.method == CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
local chance = 100 * (attempts / (item.chance or 100))
|
|
if chance > 100 then
|
|
chance = 100
|
|
end
|
|
if chance < 0 then
|
|
chance = 0
|
|
end
|
|
tooltip2AddDoubleLine(L["Progress"], format("%.2f%%", chance))
|
|
else
|
|
local chance = 100 * (1 - math.pow(1 - dropChance, attempts))
|
|
tooltip2AddDoubleLine(L["Chance so far"], format("%.2f%%", chance))
|
|
end
|
|
end
|
|
|
|
if item.totalFinds and item.method ~= CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
tooltip2AddLine(colorize(L["Total"], yellow))
|
|
attempts = (item.attempts or 0)
|
|
tooltip2AddDoubleLine(L["Attempts"], attempts)
|
|
if
|
|
item.method == CONSTANTS.DETECTION_METHODS.NPC
|
|
or item.method == CONSTANTS.DETECTION_METHODS.ZONE
|
|
or item.method == CONSTANTS.DETECTION_METHODS.FISHING
|
|
or item.method == CONSTANTS.DETECTION_METHODS.USE
|
|
then
|
|
tooltip2AddDoubleLine(L["Time spent farming"], FormatTime((item.time or 0) + len))
|
|
end
|
|
tooltip2AddDoubleLine(L["Total found"], item.totalFinds)
|
|
if item.finds then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
local f = sort2(item.finds)
|
|
for k, v in pairs(f) do
|
|
dropChance = Rarity.Statistics.GetRealDropPercentage(v)
|
|
local chance = 100 * (1 - math.pow(1 - dropChance, v.attempts))
|
|
if v.attempts == 1 then
|
|
tooltip2AddDoubleLine(
|
|
format(L["#%d: %d attempt (%.2f%%)"], v.num, v.attempts, chance),
|
|
FormatTime((v.time or 0) + len)
|
|
)
|
|
else
|
|
tooltip2AddDoubleLine(
|
|
format(L["#%d: %d attempts (%.2f%%)"], v.num, v.attempts, chance),
|
|
FormatTime((v.time or 0) + len)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Session/time period breakdown
|
|
if item.dates and item.method ~= CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
|
|
if item.session then
|
|
local sessionAttempts = item.session.attempts or 0
|
|
local sessionTime = item.session.time or 0
|
|
tooltip2AddDoubleLine(L["Session"], format("%d (%s)", sessionAttempts, FormatTime(sessionTime + len)))
|
|
end
|
|
|
|
local todayDate = GetDate()
|
|
local yesterDate = GetDate(86400)
|
|
local todayAttempts = item.dates[todayDate] and item.dates[todayDate].attempts or 0
|
|
local todayTime = item.dates[todayDate] and item.dates[todayDate].time or 0
|
|
if tracked == item and Rarity.Session:IsActive() then
|
|
todayTime = todayTime + len
|
|
end
|
|
local yesterAttempts = item.dates[yesterDate] and item.dates[yesterDate].attempts or 0
|
|
local yesterTime = item.dates[yesterDate] and item.dates[yesterDate].time or 0
|
|
local weekAttempts = (todayAttempts or 0) + (yesterAttempts or 0)
|
|
local weekTime = (todayTime or 0) + (yesterTime or 0)
|
|
for day = 2, 6 do
|
|
local dt = GetDate(day * 86400)
|
|
local dayAttempts = item.dates[dt] and item.dates[dt].attempts or 0
|
|
local dayTime = item.dates[dt] and item.dates[dt].time or 0
|
|
weekAttempts = weekAttempts + dayAttempts
|
|
weekTime = weekTime + dayTime
|
|
end
|
|
local monthAttempts = weekAttempts
|
|
local monthTime = weekTime
|
|
for day = 7, 29 do
|
|
local dt = GetDate(day * 86400)
|
|
local dayAttempts = item.dates[dt] and item.dates[dt].attempts or 0
|
|
local dayTime = item.dates[dt] and item.dates[dt].time or 0
|
|
monthAttempts = monthAttempts + dayAttempts
|
|
monthTime = monthTime + dayTime
|
|
end
|
|
|
|
tooltip2AddDoubleLine(L["Today"], format("%d (%s)", todayAttempts or 0, FormatTime((todayTime or 0) + len)))
|
|
tooltip2AddDoubleLine(L["Yesterday"], format("%d (%s)", yesterAttempts or 0, FormatTime(yesterTime or 0)))
|
|
tooltip2AddDoubleLine(L["Last Week"], format("%d (%s)", weekAttempts or 0, FormatTime(weekTime or 0)))
|
|
tooltip2AddDoubleLine(L["Last Month"], format("%d (%s)", monthAttempts or 0, FormatTime(monthTime or 0)))
|
|
end
|
|
|
|
-- Multi-step defeat detection
|
|
if item.defeatSteps ~= nil and type(item.defeatSteps) == "table" then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
for defeatStepQuest, defeatStepText in pairs(item.defeatSteps) do
|
|
local defeated = colorize(L["Undefeated"], green)
|
|
if IsQuestFlaggedCompleted(defeatStepQuest) then
|
|
defeated = colorize(L["Defeated"], red)
|
|
end
|
|
tooltip2AddDoubleLine(defeatStepText, defeated)
|
|
end
|
|
end
|
|
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
|
|
-- Add TSM pricing information to the tooltip
|
|
if AuctionDB:IsLoaded() and Rarity.db.profile.showTSMColumn then
|
|
local tooltipLines = {
|
|
{ priceSource = "DBMinBuyout", isMonetaryValue = true, localisedDisplayText = L["Min Buyout"] },
|
|
{ priceSource = "DBMarket", isMonetaryValue = true, localisedDisplayText = L["Market Price"] },
|
|
{
|
|
priceSource = "DBRegionMarketAvg",
|
|
isMonetaryValue = true,
|
|
localisedDisplayText = L["Region Market Avg"],
|
|
},
|
|
{ priceSource = "DBRegionSaleAvg", isMonetaryValue = true, localisedDisplayText = L["Region Sale Avg"] },
|
|
{
|
|
priceSource = "DBRegionSaleRate",
|
|
isMonetaryValue = false,
|
|
localisedDisplayText = L["Region Sale Rate"],
|
|
},
|
|
{
|
|
priceSource = "DBRegionSoldPerDay",
|
|
isMonetaryValue = false,
|
|
localisedDisplayText = L["Region Avg Daily Sold"],
|
|
},
|
|
}
|
|
|
|
local hasPrice = false
|
|
for _, lineInfo in pairs(tooltipLines) do -- Add text to tooltip if TSM4 has pricing data for this source
|
|
if not AuctionDB:IsValidPriceSource(lineInfo.priceSource) then
|
|
Rarity:Print(
|
|
format(
|
|
"Attempting to use invalid price source %s to retrieve a price for item %d via TSM_API."
|
|
.. " Please report this error so it can be fixed :)",
|
|
lineInfo.priceSource,
|
|
item.itemId
|
|
)
|
|
)
|
|
break
|
|
end
|
|
|
|
local formattedPrice = AuctionDB:GetMarketPrice(item.itemId, lineInfo.priceSource, true)
|
|
if formattedPrice ~= nil then
|
|
hasPrice = true
|
|
tooltip2AddDoubleLine(
|
|
colorize(lineInfo.localisedDisplayText, blue),
|
|
lineInfo.isMonetaryValue and formattedPrice,
|
|
nil,
|
|
nil
|
|
)
|
|
end
|
|
end
|
|
|
|
if hasPrice then
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
end
|
|
end
|
|
|
|
-- Click instructions
|
|
tooltip2AddLine(colorize(L["Click to switch to this item"], gray))
|
|
tooltip2AddLine(colorize(L["Shift-Click to link your progress to chat"], gray))
|
|
|
|
-- Waypoint instructions
|
|
if item.coords ~= nil and type(item.coords) == "table" then
|
|
local numCoords = 0
|
|
local totalCoords = 0
|
|
for _, coord in pairs(item.coords) do
|
|
if type(coord) == "table" and coord.x ~= nil and coord.y ~= nil and coord.m ~= nil then
|
|
totalCoords = totalCoords + 1
|
|
if coord.q ~= nil then
|
|
if IsQuestFlaggedCompleted(coord.q) == false then
|
|
numCoords = numCoords + 1
|
|
end
|
|
else
|
|
numCoords = numCoords + 1
|
|
end
|
|
end
|
|
end
|
|
if totalCoords > 0 then
|
|
local s = format(L["Rarity has %d |4coordinate:coordinates; for this item."], totalCoords) .. " "
|
|
if totalCoords > numCoords then
|
|
if numCoords <= 0 then
|
|
s = s .. L["You already defeated all of them."]
|
|
else
|
|
s = s .. format(L["You already defeated %d of them."], totalCoords - numCoords) .. " "
|
|
end
|
|
end
|
|
if TomTom ~= nil and TomTom.AddWaypoint ~= nil then
|
|
if numCoords > 0 then
|
|
if totalCoords > numCoords then
|
|
s = s .. L["Ctrl-Click to create the remaining TomTom waypoint(s)."]
|
|
else
|
|
s = s .. L["Ctrl-Click to create TomTom waypoint(s)."]
|
|
end
|
|
end
|
|
else
|
|
s = s .. L["Install TomTom to enable waypoint creation."]
|
|
end
|
|
tooltip2:AddSeparator(1, 1, 1, 1, 1)
|
|
tooltip2AddLine(colorize(s, green))
|
|
end
|
|
end
|
|
|
|
-- tooltip2:UpdateScrolling()
|
|
tooltip2:Show()
|
|
end
|
|
|
|
local function showSubTooltipMe(cell, group)
|
|
showSubTooltip(cell, group, "")
|
|
end
|
|
|
|
local function showSubTooltipPet(cell, group)
|
|
showSubTooltip(cell, group, "_pet")
|
|
end
|
|
|
|
local function onClickGroup(cell, group)
|
|
if type(group) == "table" then
|
|
if group.collapsed == true then
|
|
group.collapsed = false
|
|
else
|
|
group.collapsed = true
|
|
end
|
|
if tooltip then
|
|
tooltip:Hide()
|
|
end
|
|
if Rarity.Tooltips:IsTooltipAcquired("RarityTooltip") then
|
|
Rarity.Tooltips:ReleaseTooltip("RarityTooltip")
|
|
end
|
|
Rarity:ShowTooltip()
|
|
end
|
|
end
|
|
|
|
local function onClickGroup2(cell, group)
|
|
if type(group) == "table" then
|
|
if group.collapsedGroup == true then
|
|
group.collapsedGroup = false
|
|
else
|
|
group.collapsedGroup = true
|
|
end
|
|
if tooltip then
|
|
tooltip:Hide()
|
|
end
|
|
if Rarity.Tooltips:IsTooltipAcquired("RarityTooltip") then
|
|
Rarity.Tooltips:ReleaseTooltip("RarityTooltip")
|
|
end
|
|
Rarity:ShowTooltip()
|
|
end
|
|
end
|
|
|
|
local function hideSubTooltip()
|
|
if tooltip2 then
|
|
Rarity.Tooltips:ReleaseTooltip(tooltip2)
|
|
tooltip2 = nil
|
|
end
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function addGroup(group, requiresGroup)
|
|
local trackedItem = Rarity.Tracking:GetTrackedItem()
|
|
|
|
R:ProfileStart2()
|
|
|
|
local addGroupStart = debugprofilestop()
|
|
|
|
if type(group) ~= "table" then
|
|
return
|
|
end
|
|
if group.name == nil then
|
|
return
|
|
end
|
|
|
|
local dt = date("*t", time())
|
|
local line
|
|
local added = false
|
|
local headerAdded = false
|
|
local itemsExistInThisGroup = false
|
|
|
|
local addGroupSortStart = debugprofilestop()
|
|
|
|
local sortedGroup = Rarity.Utils.Sorting:SortGroup(group, R.db.profile.sortMode)
|
|
|
|
local addGroupSortEnd = debugprofilestop()
|
|
|
|
-- Inlining this because it has WAY too many interdependencies and I don't have time to unwrangle it now, but using early exit is easier this way (and more readable). It doesn't change the functionality and the small overhead shouldn't matter here
|
|
local function AddItem(k, v)
|
|
if
|
|
type(v) == "table"
|
|
and v.enabled ~= false
|
|
and (
|
|
(requiresGroup and v.groupSize ~= nil and v.groupSize > 1)
|
|
or (not requiresGroup and (v.groupSize == nil or v.groupSize <= 1))
|
|
)
|
|
then
|
|
local classGood = true
|
|
local playerClass = select(2, UnitClass("player"))
|
|
if v.disableForClass and v.disableForClass[playerClass] then
|
|
classGood = false
|
|
end
|
|
|
|
if not v.itemId then
|
|
Rarity:Error(
|
|
format(
|
|
"Failed to add tooltip line for item %s (%s) in group %s (invalid ID or the server didn't return any data)",
|
|
k,
|
|
v.name or "nil",
|
|
group.name
|
|
)
|
|
)
|
|
return
|
|
end
|
|
-- Item
|
|
if
|
|
(v.requiresHorde and R.Caching:IsHorde())
|
|
or (v.requiresAlliance and not R.Caching:IsHorde())
|
|
or (not v.requiresHorde and not v.requiresAlliance)
|
|
then
|
|
if R.db.profile.cats[v.cat] or v.cat == nil then
|
|
if not (R.db.profile.hideHighChance and (v.chance or 0) < 50) and classGood then
|
|
local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, itemSellPrice =
|
|
GetItemInfo(v.itemId)
|
|
local attempts = tonumber(v.attempts or 0) or 0
|
|
if type(attempts) ~= "number" then
|
|
attempts = 0
|
|
end
|
|
if v.lastAttempts then
|
|
attempts = attempts - v.lastAttempts
|
|
end
|
|
|
|
local lucky, chance, dropChance
|
|
|
|
if v.method ~= CONSTANTS.DETECTION_METHODS.COLLECTION then
|
|
dropChance = Rarity.Statistics.GetRealDropPercentage(v)
|
|
chance = 100 * (1 - math.pow(1 - dropChance, attempts))
|
|
local medianLoots = Round(math.log(1 - 0.5) / math.log(1 - dropChance))
|
|
lucky = colorize(L["Lucky"], green)
|
|
if (tonumber(medianLoots) or 0) < (tonumber(attempts) or 0) then
|
|
lucky = colorize(L["Unlucky"], red)
|
|
end
|
|
else
|
|
chance = 100 * (attempts / (v.chance or 100))
|
|
if chance < 0 then
|
|
chance = 0
|
|
end
|
|
if chance > 100 then
|
|
chance = 100
|
|
end
|
|
lucky = colorize(L["Lucky"], green)
|
|
end
|
|
|
|
local icon = ""
|
|
if trackedItem == v then
|
|
icon = [[|TInterface\Buttons\UI-CheckBox-Check:0|t]]
|
|
end
|
|
local duration = 0
|
|
if v.time then
|
|
duration = v.time
|
|
end
|
|
if v.lastTime then
|
|
duration = v.time - v.lastTime
|
|
end
|
|
if Rarity.Session:IsActive() and trackedItem == v then
|
|
local len = Rarity.Session:GetLastTime() - Rarity.Session:GetStartTime()
|
|
duration = duration + len
|
|
end
|
|
duration = FormatTime(duration)
|
|
local likelihood = format("%.2f%%", chance)
|
|
if attempts == 0 then
|
|
attempts = ""
|
|
lucky = ""
|
|
duration = ""
|
|
likelihood = ""
|
|
end
|
|
if duration == "0:00" then
|
|
duration = ""
|
|
end
|
|
if
|
|
v.method ~= CONSTANTS.DETECTION_METHODS.NPC
|
|
and v.method ~= CONSTANTS.DETECTION_METHODS.ZONE
|
|
and v.method ~= CONSTANTS.DETECTION_METHODS.FISHING
|
|
and v.method ~= CONSTANTS.DETECTION_METHODS.USE
|
|
then
|
|
duration = ""
|
|
end
|
|
local status = ""
|
|
if v.questId and not v.holidayTexture then
|
|
if type(v.questId) == "table" then
|
|
status = colorize(L["Undefeated"], green)
|
|
for key, questId in pairs(v.questId) do
|
|
if IsQuestFlaggedCompleted(questId) then
|
|
status = colorize(L["Defeated"], red)
|
|
end
|
|
end
|
|
else
|
|
if IsQuestFlaggedCompleted(v.questId) then
|
|
status = colorize(L["Defeated"], red)
|
|
else
|
|
status = colorize(L["Undefeated"], green)
|
|
end
|
|
end
|
|
-- If item is linked to a World Quest, flag as unavailable if WQ isn't up.
|
|
if v.worldQuestId then
|
|
if IsWorldQuestActive(v.worldQuestId) == false then
|
|
status = colorize(L["Unavailable"], gray)
|
|
end
|
|
end
|
|
elseif v.questId and v.holidayTexture then
|
|
if not Rarity.HolidayEvents.IsItemAvailableToday(v) then
|
|
status = colorize(L["Unavailable"], gray)
|
|
elseif v.christmasOnly and dt.month == 12 and dt.day < 25 then
|
|
status = colorize(L["Unavailable"], gray)
|
|
else
|
|
if type(v.questId) == "table" then
|
|
status = colorize(L["Undefeated"], green)
|
|
for key, questId in pairs(v.questId) do
|
|
if IsQuestFlaggedCompleted(questId) then
|
|
status = colorize(L["Defeated"], red)
|
|
end
|
|
end
|
|
else
|
|
if IsQuestFlaggedCompleted(v.questId) then
|
|
status = colorize(L["Defeated"], red)
|
|
else
|
|
status = colorize(L["Undefeated"], green)
|
|
end
|
|
end
|
|
end
|
|
elseif v.lockBossName or v.lockoutDetails then
|
|
-- Lockout-based defeat detection requires special treatment due to the underlying complexity
|
|
if not lbb["Theralion and Valiona"] and lbb["Valiona and Theralion"] then
|
|
-- LibBabble-Boss is still outdated -> Add correct encounter name
|
|
lbb["Theralion and Valiona"] = lbb["Valiona and Theralion"] -- Workaround for issue:
|
|
-- https://github.com/SacredDuckwhale/Rarity/issues/22 - can be removed once the library was updated
|
|
end
|
|
|
|
local isDefeated
|
|
local mode = CONSTANTS.DEFEAT_DETECTION.MODE_OR
|
|
-- OR: At least one encounter must be defeated
|
|
-- AND: All encounters must be defeated
|
|
-- (before the item will be displayed as defeated)
|
|
local usesNewDefeatDetection = v.lockoutDetails
|
|
and type(v.lockoutDetails) == "table"
|
|
and #v.lockoutDetails > 0
|
|
|
|
if usesNewDefeatDetection then -- Resolve the defeat detection using the item's parameters
|
|
isDefeated = false
|
|
local continue = true
|
|
|
|
mode = v.lockoutDetails.mode or mode
|
|
|
|
for index, sharedDifficultyGroup in ipairs(v.lockoutDetails) do
|
|
-- Check all stored lockouts and resolve the defeat detection
|
|
-- (if there are none there isn't anything left to do)
|
|
local isValidEntry = sharedDifficultyGroup.encounterName
|
|
and type(sharedDifficultyGroup.encounterName) == "string"
|
|
and sharedDifficultyGroup.instanceDifficulties
|
|
and type(sharedDifficultyGroup.instanceDifficulties) == "table"
|
|
|
|
if not isValidEntry then
|
|
Rarity:Debug(
|
|
"Invalid lockout details for item "
|
|
.. tostring(v.name)
|
|
.. " - defeat detection will not be resolved"
|
|
)
|
|
continue = false
|
|
end
|
|
|
|
local storedLockouts = Rarity.lockouts_detailed[sharedDifficultyGroup.encounterName]
|
|
or {}
|
|
|
|
local isGroupCompleted = false
|
|
for instanceDifficulty, membershipFlag in
|
|
pairs(sharedDifficultyGroup.instanceDifficulties)
|
|
do
|
|
-- Check if a lockout is stored for any of the group's members (difficulties)
|
|
if storedLockouts[instanceDifficulty] then -- Flag the entire group as locked out
|
|
isGroupCompleted = true -- isGroupCompleted = storedLockouts[instanceDifficulty]
|
|
end
|
|
end
|
|
|
|
if
|
|
mode == CONSTANTS.DEFEAT_DETECTION.MODE_AND
|
|
and not isGroupCompleted
|
|
and continue
|
|
then
|
|
-- Since at least one step isn't complete, the item shouldn't be marked as defeated
|
|
isDefeated = false
|
|
continue = false
|
|
elseif continue then -- Overwrite default value
|
|
isDefeated = true
|
|
end
|
|
|
|
-- Otherwise, at least one version was defeated, so the item should be marked as defeated
|
|
if mode == CONSTANTS.DEFEAT_DETECTION.MODE_OR and isGroupCompleted and continue then
|
|
isDefeated = true
|
|
continue = false
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Currently, only one of the two detection routines should be used
|
|
if
|
|
(
|
|
v.lockBossName
|
|
and lbb[v.lockBossName]
|
|
and (
|
|
Rarity.lockouts[lbb[v.lockBossName]] == true
|
|
or Rarity.lockouts[v.lockBossName] == true
|
|
)
|
|
) -- Legacy detection (I'll leave it be, for now)
|
|
or isDefeated
|
|
then
|
|
status = colorize(L["Defeated"], red)
|
|
else
|
|
status = colorize(L["Undefeated"], green)
|
|
end
|
|
elseif v.lockDungeonId then
|
|
if Rarity.lockouts_holiday[v.lockDungeonId] == true then
|
|
status = colorize(L["Defeated"], red)
|
|
else
|
|
if Rarity.lockouts_holiday[v.lockDungeonId] == false then
|
|
status = colorize(L["Undefeated"], green)
|
|
else
|
|
status = colorize(L["Unavailable"], gray)
|
|
end
|
|
end
|
|
elseif v.holidayTexture and not Rarity.HolidayEvents.IsItemAvailableToday(v) then
|
|
status = colorize(L["Unavailable"], gray)
|
|
end
|
|
if v.pickpocket then
|
|
local class, classFileName = UnitClass("player")
|
|
if classFileName ~= "ROGUE" then
|
|
status = colorize(L["Unavailable"], gray)
|
|
end
|
|
end
|
|
|
|
if v.requiresCovenant and v.requiredCovenantID ~= nil then
|
|
local activeCovenantID = C_Covenants.GetActiveCovenantID()
|
|
if activeCovenantID ~= v.requiredCovenantID then
|
|
status = colorize(L["Unavailable"], gray)
|
|
end
|
|
end
|
|
|
|
-- Support for Defeated items with multiple steps of defeat (supports quests only)
|
|
if
|
|
status == colorize(L["Defeated"], red)
|
|
and v.defeatAllQuests
|
|
and v.questId ~= nil
|
|
and type(v.questId) == "table"
|
|
then
|
|
local totalQuests = 0
|
|
local numCompletedQuests = 0
|
|
for _, quest in pairs(v.questId) do
|
|
totalQuests = totalQuests + 1
|
|
if IsQuestFlaggedCompleted(quest) then
|
|
numCompletedQuests = numCompletedQuests + 1
|
|
end
|
|
end
|
|
if totalQuests > numCompletedQuests then
|
|
status = colorize(
|
|
format(L["Defeated"] .. " (%d of %d)", numCompletedQuests, totalQuests),
|
|
yellow
|
|
)
|
|
end
|
|
end
|
|
|
|
if Rarity.db.profile.hideUnavailable == false or status ~= colorize(L["Unavailable"], gray) then
|
|
if Rarity.db.profile.hideDefeated == false or status ~= colorize(L["Defeated"], red) then
|
|
-- Holiday reminder
|
|
if
|
|
Rarity.db.profile.holidayReminder
|
|
and Rarity.allRemindersDone == nil
|
|
and v.holidayReminder ~= false
|
|
and (v.cat == HOLIDAY or v.worldQuestId)
|
|
and status == colorize(L["Undefeated"], green)
|
|
then
|
|
Rarity.anyReminderDone = true
|
|
numHolidayReminders = numHolidayReminders + 1
|
|
if numHolidayReminders <= 2 then
|
|
local text
|
|
if v.worldQuestId then
|
|
if IsWorldQuestActive(v.worldQuestId) then
|
|
text = format(
|
|
L["A world event is currently available for %s! Go get it!"],
|
|
itemLink or itemName or v.name
|
|
)
|
|
end
|
|
else
|
|
text = format(
|
|
L["A holiday event is available today for %s! Go get it!"],
|
|
itemLink or itemName or v.name
|
|
)
|
|
end
|
|
Rarity:Print(text)
|
|
if CVarCallbackRegistry:GetCVarValueBool("enableFloatingCombatText") then
|
|
if type(CombatText_AddMessage) == "nil" then
|
|
UIParentLoadAddOn("Blizzard_CombatText")
|
|
end
|
|
CombatText_AddMessage(text, CombatText_StandardScroll, 1, 1, 1, true, false)
|
|
else
|
|
UIErrorsFrame:AddMessage(text, 1, 1, 1, 1.0)
|
|
end
|
|
else
|
|
if showedHolidayReminderOverflow == false then
|
|
Rarity:Print(
|
|
colorize(
|
|
L["There are more holiday items available, but Rarity only reminds you about the first two."],
|
|
gray
|
|
)
|
|
)
|
|
end
|
|
showedHolidayReminderOverflow = true
|
|
end
|
|
end
|
|
|
|
if
|
|
not Rarity.db.profile.onlyShowItemsWithAttempts
|
|
or (
|
|
Rarity.db.profile.onlyShowItemsWithAttempts
|
|
and (tonumber(v.attempts or 0) or 0) > 0
|
|
)
|
|
then
|
|
if
|
|
not Rarity.db.profile.hideOutsideZone
|
|
or (
|
|
Rarity.db.profile.hideOutsideZone
|
|
and R.Waypoints:IsItemInCurrentZone(v)
|
|
and R:IsAttemptAllowed(v)
|
|
)
|
|
then
|
|
itemsExistInThisGroup = true
|
|
if
|
|
(
|
|
(not requiresGroup and group.collapsed ~= true)
|
|
or (requiresGroup and group.collapsedGroup ~= true)
|
|
) and v.itemId ~= nil
|
|
then
|
|
-- Header
|
|
if not added then
|
|
headerAdded = true
|
|
local groupName = group.name
|
|
if requiresGroup then
|
|
groupName = groupName .. L[" (Group)"]
|
|
end
|
|
if not headers[groupName] and v.itemId ~= nil then
|
|
headers[groupName] = true
|
|
local collapsed = group.collapsed or false
|
|
if
|
|
(not requiresGroup and group.collapsed == true)
|
|
or (requiresGroup and group.collapsedGroup == true)
|
|
then
|
|
line = tooltip:AddLine(
|
|
"|TInterface\\Buttons\\UI-PlusButton-Up:16|t",
|
|
colorize(groupName, yellow)
|
|
)
|
|
else
|
|
line = tooltip:AddLine(
|
|
"|TInterface\\Buttons\\UI-MinusButton-Up:16|t",
|
|
colorize(groupName, yellow),
|
|
colorize(L["Attempts"], yellow),
|
|
colorize(L["Likelihood"], yellow),
|
|
Rarity.db.profile.showTimeColumn
|
|
and colorize(L["Time"], yellow)
|
|
or nil,
|
|
Rarity.db.profile.showLuckinessColumn
|
|
and colorize(L["Luckiness"], yellow)
|
|
or nil,
|
|
Rarity.db.profile.showZoneColumn
|
|
and colorize(L["Zone"], yellow)
|
|
or nil,
|
|
colorize(L["Defeated"], yellow),
|
|
TSM_API ~= nil
|
|
and Rarity.db.profile.showTSMColumn
|
|
and colorize(L["Market Price"], yellow)
|
|
or nil
|
|
)
|
|
end
|
|
tooltip:SetLineScript(
|
|
line,
|
|
"OnMouseUp",
|
|
requiresGroup and onClickGroup2 or onClickGroup,
|
|
group
|
|
)
|
|
end
|
|
end
|
|
|
|
-- Zone
|
|
local zoneInfo = R.Waypoints:GetZoneInfoForItem(v)
|
|
local zoneText, inMyZone, zoneColor, numZones =
|
|
zoneInfo.zoneText,
|
|
zoneInfo.inMyZone,
|
|
zoneInfo.zoneColor,
|
|
zoneInfo.numZones
|
|
|
|
-- Retrieve the DBMarket price provided by the TSM_API (if loaded)
|
|
local marketPrice = Rarity.db.profile.showTSMColumn
|
|
and AuctionDB:GetMarketPrice(v.itemId, "DBMarket", true)
|
|
|
|
-- Add the item to the tooltip
|
|
local catIcon = ""
|
|
if
|
|
Rarity.db.profile.showCategoryIcons
|
|
and v.cat
|
|
and Rarity.catIcons[v.cat]
|
|
then
|
|
catIcon = [[|TInterface\AddOns\Rarity\Icons\]]
|
|
.. Rarity.catIcons[v.cat]
|
|
.. ".blp:0:4|t "
|
|
end
|
|
line = tooltip:AddLine(
|
|
icon,
|
|
catIcon
|
|
.. (itemTexture and "|T" .. itemTexture .. ":0|t " or "")
|
|
.. (itemLink or v.name or L["Unknown"]),
|
|
attempts,
|
|
likelihood,
|
|
Rarity.db.profile.showTimeColumn and duration or nil,
|
|
Rarity.db.profile.showLuckinessColumn and lucky or nil,
|
|
Rarity.db.profile.showZoneColumn and colorize(zoneText, zoneColor)
|
|
or nil,
|
|
status,
|
|
Rarity.db.profile.showTSMColumn and marketPrice or nil
|
|
)
|
|
tooltip:SetLineScript(line, "OnMouseUp", onClickItem, v)
|
|
tooltip:SetLineScript(line, "OnEnter", showSubTooltip, v)
|
|
tooltip:SetLineScript(line, "OnLeave", hideSubTooltip)
|
|
added = true
|
|
|
|
-- "Should display the item" endif section:
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- End "should display the item" endif section
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for k, v in ipairs(sortedGroup) do
|
|
AddItem(k, v)
|
|
end
|
|
|
|
local addGroupIterationEnd = debugprofilestop()
|
|
|
|
-- Collapsed Header
|
|
if
|
|
not headerAdded
|
|
and itemsExistInThisGroup
|
|
and ((not requiresGroup and group.collapsed == true) or (requiresGroup and group.collapsedGroup == true))
|
|
then
|
|
-- headerAdded = true -- Why?
|
|
local groupName = group.name
|
|
if requiresGroup then
|
|
groupName = groupName .. L[" (Group)"]
|
|
end
|
|
if not headers[groupName] then
|
|
headers[groupName] = true
|
|
local collapsed = group.collapsed or false
|
|
if (not requiresGroup and group.collapsed == true) or (requiresGroup and group.collapsedGroup == true) then
|
|
line = tooltip:AddLine("|TInterface\\Buttons\\UI-PlusButton-Up:16|t", colorize(groupName, yellow))
|
|
else
|
|
line = tooltip:AddLine(
|
|
"|TInterface\\Buttons\\UI-MinusButton-Up:16|t",
|
|
colorize(groupName, yellow),
|
|
colorize(L["Attempts"], yellow),
|
|
colorize(L["Likelihood"], yellow),
|
|
Rarity.db.profile.showTimeColumn and colorize(L["Time"], yellow) or nil,
|
|
Rarity.db.profile.showLuckinessColumn and colorize(L["Luckiness"], yellow) or nil,
|
|
Rarity.db.profile.showZoneColumn and colorize(L["Zone"], yellow) or nil,
|
|
colorize(L["Defeated"], yellow)
|
|
)
|
|
end
|
|
tooltip:SetLineScript(line, "OnMouseUp", requiresGroup and onClickGroup2 or onClickGroup, group)
|
|
end
|
|
end
|
|
|
|
local addGroupEnd = debugprofilestop()
|
|
|
|
R:ProfileStop2(
|
|
"addGroup("
|
|
.. group.name
|
|
.. ", "
|
|
.. tostring(requiresGroup)
|
|
.. ") took %fms"
|
|
.. format(
|
|
" (Total: %f, Sort: %f, Iteration: %f, Tooltip: %f",
|
|
(addGroupEnd - addGroupStart),
|
|
(addGroupSortEnd - addGroupSortStart),
|
|
(addGroupIterationEnd - addGroupSortEnd),
|
|
(addGroupEnd - addGroupIterationEnd)
|
|
)
|
|
)
|
|
|
|
return added, itemsExistInThisGroup
|
|
end
|
|
|
|
-- Module-level functions
|
|
-- Change sort order based on the current one (awkward, but alas... this should probably be improved later)
|
|
function GUI:SelectNextSortOrder()
|
|
if R.db.profile.sortMode == SORT_NAME then
|
|
R.db.profile.sortMode = SORT_CATEGORY
|
|
elseif R.db.profile.sortMode == SORT_CATEGORY then
|
|
R.db.profile.sortMode = SORT_DIFFICULTY
|
|
elseif R.db.profile.sortMode == SORT_DIFFICULTY then
|
|
R.db.profile.sortMode = SORT_PROGRESS
|
|
elseif R.db.profile.sortMode == SORT_PROGRESS then
|
|
R.db.profile.sortMode = SORT_ZONE
|
|
else
|
|
R.db.profile.sortMode = SORT_NAME
|
|
end
|
|
if tooltip then
|
|
tooltip:Hide()
|
|
end
|
|
if Rarity.Tooltips:IsTooltipAcquired("RarityTooltip") then
|
|
Rarity.Tooltips:ReleaseTooltip("RarityTooltip")
|
|
end
|
|
Rarity:ShowTooltip()
|
|
end
|
|
|
|
function R:ShowTooltip(hidden)
|
|
-- This function needs to be non-reentrant
|
|
if renderingTip then
|
|
return
|
|
end
|
|
renderingTip = true
|
|
|
|
if Rarity.Tooltips:IsTooltipAcquired("RarityTooltip") and tooltip then
|
|
-- Don't show the tooltip if it's already showing
|
|
if tooltip:IsVisible() then
|
|
renderingTip = false
|
|
return
|
|
end
|
|
tooltip:Clear()
|
|
else
|
|
tooltip = Rarity.Tooltips:AcquireTooltip(
|
|
"RarityTooltip",
|
|
9,
|
|
"LEFT",
|
|
"LEFT",
|
|
"RIGHT",
|
|
"RIGHT",
|
|
"RIGHT",
|
|
"CENTER",
|
|
"CENTER",
|
|
"CENTER"
|
|
)
|
|
-- intentionally one column more than we need to avoid text clipping
|
|
tooltip:SetScale(self.db.profile.tooltipScale or 1)
|
|
end
|
|
|
|
table.wipe(headers)
|
|
local addedLast
|
|
local itemsExistInThisGroup
|
|
numHolidayReminders = 0
|
|
showedHolidayReminderOverflow = false
|
|
local delay
|
|
if self.db.profile.tooltipHideDelay <= 0 then
|
|
local hideOnClick = (Rarity.db.profile.tooltipActivation == CONSTANTS.TOOLTIP.ACTIVATION_METHOD_CLICK)
|
|
delay = hideOnClick and 0 or 0.01 -- Hiding manually is only possible when not in hover mode
|
|
else
|
|
delay = self.db.profile.tooltipHideDelay or 0.6
|
|
end
|
|
tooltip:SetAutoHideDelay(delay, Rarity.frame, function()
|
|
tooltip = nil
|
|
Rarity.Tooltips:ReleaseTooltip("RarityTooltip")
|
|
end)
|
|
|
|
-- The tooltip can't be built in combat; it takes too long and the script will receive a "script ran too long" error
|
|
if InCombatLockdown() then
|
|
local line = tooltip:AddLine()
|
|
tooltip:SetCell(line, 1, colorize(L["Tooltip can't be shown in combat"], gray), nil, nil, 3)
|
|
if hidden == true or Rarity.frame == nil then
|
|
renderingTip = false
|
|
return
|
|
end
|
|
tooltip:SmartAnchorTo(Rarity.frame)
|
|
tooltip:UpdateScrolling()
|
|
tooltip:Show()
|
|
renderingTip = false
|
|
return
|
|
end
|
|
|
|
-- No tooltip until we're done initializing
|
|
if not Rarity.Caching:IsReady() then
|
|
local line = tooltip:AddLine()
|
|
tooltip:SetCell(line, 1, colorize(L["Rarity is loading..."], gray), nil, nil, 3)
|
|
if hidden == true or Rarity.frame == nil then
|
|
renderingTip = false
|
|
return
|
|
end
|
|
tooltip:SmartAnchorTo(Rarity.frame)
|
|
tooltip:UpdateScrolling()
|
|
tooltip:Show()
|
|
renderingTip = false
|
|
return
|
|
end
|
|
|
|
-- Sort header
|
|
local sortDesc = L["Sorting by name"]
|
|
if self.db.profile.sortMode == SORT_DIFFICULTY then
|
|
sortDesc = L["Sorting by difficulty"]
|
|
elseif self.db.profile.sortMode == SORT_PROGRESS then
|
|
sortDesc = L["Sorting by percent complete"]
|
|
elseif self.db.profile.sortMode == SORT_CATEGORY then
|
|
sortDesc = L["Sorting by category, then name"]
|
|
elseif self.db.profile.sortMode == SORT_ZONE then
|
|
sortDesc = L["Sorting by zone"]
|
|
elseif self.db.profile.sortMode == SORT_NONE then
|
|
sortDesc = L["Sorting is disabled"]
|
|
end
|
|
sortDesc = sortDesc .. colorize(" (" .. L["Ctrl-Click to change sort order"] .. ")", gray)
|
|
local line = tooltip:AddLine()
|
|
tooltip:SetCell(line, 1, colorize(sortDesc, green), nil, nil, 3)
|
|
|
|
local function OnHeaderClicked()
|
|
if not IsControlKeyDown() then
|
|
return
|
|
end -- Unlike the LDB icon, this also works with right-click...
|
|
-- I have no idea how to get the button from LDB. The tooltip says "click" and not "left-click", so both should be fine
|
|
Rarity.GUI:SelectNextSortOrder()
|
|
end
|
|
tooltip:SetLineScript(line, "OnMouseUp", OnHeaderClicked)
|
|
|
|
-- Item groups
|
|
R:ProfileStart()
|
|
|
|
local somethingAdded = false
|
|
|
|
local group1start = debugprofilestop()
|
|
if R.db.profile.collectionType[MOUNT] then
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.mounts)
|
|
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
end
|
|
local group1end = debugprofilestop()
|
|
|
|
local group2start = debugprofilestop()
|
|
if R.db.profile.collectionType[PET] then
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.pets)
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
end
|
|
local group2end = debugprofilestop()
|
|
|
|
local group3start = debugprofilestop()
|
|
if R.db.profile.collectionType[ITEM] then
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.items)
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
end
|
|
local group3end = debugprofilestop()
|
|
|
|
local group4start = debugprofilestop()
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.user)
|
|
local group4end = debugprofilestop()
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
|
|
local group5start = debugprofilestop()
|
|
if R.db.profile.collectionType[MOUNT] then
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.mounts, true)
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
end
|
|
local group5end = debugprofilestop()
|
|
|
|
local group6start = debugprofilestop()
|
|
if R.db.profile.collectionType[PET] then
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.pets, true)
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
end
|
|
local group6end = debugprofilestop()
|
|
|
|
local group7start = debugprofilestop()
|
|
if R.db.profile.collectionType[ITEM] then
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.items, true)
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
end
|
|
local group7end = debugprofilestop()
|
|
|
|
local group8start = debugprofilestop()
|
|
addedLast, itemsExistInThisGroup = addGroup(self.db.profile.groups.user, true)
|
|
local group8end = debugprofilestop()
|
|
if addedLast then
|
|
tooltip:AddSeparator(1, 1, 1, 1, 1.0)
|
|
end
|
|
if itemsExistInThisGroup then
|
|
somethingAdded = true
|
|
end
|
|
|
|
if not somethingAdded then
|
|
line = tooltip:AddLine()
|
|
tooltip:SetCell(
|
|
line,
|
|
1,
|
|
colorize(
|
|
L["No items to display! Either you've obtained every item, or you have\n" .. "one or more options turned on which hide things from the tooltip."],
|
|
red
|
|
),
|
|
nil,
|
|
nil,
|
|
3
|
|
)
|
|
end
|
|
|
|
R:ProfileStop(
|
|
"Tooltip rendering took %fms"
|
|
.. format(
|
|
" (%f, %f, %f, %f, %f, %f, %f, %f)",
|
|
(group1end - group1start),
|
|
(group2end - group2start),
|
|
(group3end - group3start),
|
|
(group4end - group4start),
|
|
(group5end - group5start),
|
|
(group6end - group6start),
|
|
(group7end - group7start),
|
|
(group8end - group8start)
|
|
)
|
|
)
|
|
|
|
-- Footer
|
|
line = tooltip:AddLine()
|
|
tooltip:SetCell(line, 1, colorize(L["Click to toggle the progress bar"], gray), nil, nil, 3)
|
|
line = tooltip:AddLine()
|
|
tooltip:SetCell(line, 1, colorize(L["Shift-Click to open options"], gray), nil, nil, 3)
|
|
line = tooltip:AddLine()
|
|
tooltip:SetCell(line, 1, colorize(L["Ctrl-Click to change sort order"], gray), nil, nil, 3)
|
|
|
|
if Rarity.anyReminderDone and not Rarity.allRemindersDone then
|
|
Rarity.allRemindersDone = true
|
|
if Rarity.db.profile.holidayReminder then
|
|
Rarity:Print(
|
|
colorize(
|
|
L["You can turn off holiday reminders as a whole or on an item-by-item basis by visiting the Rarity Options screen."],
|
|
gray
|
|
)
|
|
)
|
|
end
|
|
end
|
|
if hidden == true or Rarity.frame == nil then
|
|
renderingTip = false
|
|
return
|
|
end
|
|
|
|
tooltip:SmartAnchorTo(Rarity.frame)
|
|
tooltip:UpdateScrolling()
|
|
tooltip:Show()
|
|
|
|
renderingTip = false
|
|
end
|
|
|
|
-- Groups, sort order etc
|
|
|