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.
280 lines
10 KiB
280 lines
10 KiB
-- Upvalues
|
|
local R = Rarity
|
|
|
|
-- Lua API
|
|
local table = table
|
|
|
|
-- WOW API
|
|
local C_Calendar = C_Calendar
|
|
local GetContainerNumSlots = _G.C_Container.GetContainerNumSlots
|
|
local GetContainerItemID = _G.C_Container.GetContainerItemID
|
|
local GetContainerItemInfo = _G.C_Container.GetContainerItemInfo
|
|
local GetNumSavedInstances = GetNumSavedInstances
|
|
local GetSavedInstanceInfo = GetSavedInstanceInfo
|
|
local GetNumRandomDungeons = GetNumRandomDungeons
|
|
local GetLFGRandomDungeonInfo = GetLFGRandomDungeonInfo
|
|
local GetLFGDungeonInfo = GetLFGDungeonInfo
|
|
local GetLFGDungeonRewards = GetLFGDungeonRewards
|
|
local GetStatistic = GetStatistic
|
|
local UnitName = UnitName
|
|
local UnitGUID = UnitGUID
|
|
local InCombatLockdown = InCombatLockdown
|
|
local GetAchievementNumCriteria = GetAchievementNumCriteria
|
|
|
|
-- Constants
|
|
local NUM_BAG_SLOTS = _G.NUM_BAG_SLOTS
|
|
local BOSS_DEAD = _G.BOSS_DEAD
|
|
|
|
-- Why is this so inconsistently named? Does it have a special meaning?
|
|
local rarity_stats = {}
|
|
|
|
-------------------------------------------------------------------------------------
|
|
-- Scan your bags to see if you are in possession of any of the items we want. This is used for BOSS and FISHING methods,
|
|
-- and also works as a second line of defense in case other methods fail to notice the item.
|
|
-------------------------------------------------------------------------------------
|
|
function R:ScanBags()
|
|
table.wipe(Rarity.bagitems)
|
|
for i = 0, NUM_BAG_SLOTS do
|
|
local numSlots = GetContainerNumSlots(i)
|
|
if numSlots then
|
|
for ii = 1, numSlots do
|
|
local id = GetContainerItemID(i, ii)
|
|
if id then
|
|
local containerItemInfo = GetContainerItemInfo(i, ii)
|
|
local qty = containerItemInfo.stackCount
|
|
if qty and qty > 0 then
|
|
if not Rarity.bagitems[id] then
|
|
Rarity.bagitems[id] = 0
|
|
end
|
|
Rarity.bagitems[id] = Rarity.bagitems[id] + qty
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function R:ScanCalendar(reason)
|
|
self:Debug("Scanning calendar (" .. reason .. ")")
|
|
|
|
table.wipe(Rarity.holiday_textures)
|
|
local dateInfo = C_DateAndTime.GetCurrentCalendarTime() -- This is the CURRENT date (always "today")
|
|
local month, day, year = dateInfo.month, dateInfo.monthDay, dateInfo.year
|
|
local monthInfo = C_Calendar.GetMonthInfo() -- This is the CALENDAR date (as selected)
|
|
local curMonth, curYear = monthInfo.month, monthInfo.year -- It should be noted that this is the calendar's "current" month... the name may be misleading, but I'll keep it as it was
|
|
local monthOffset = -12 * (curYear - year) + month - curMonth
|
|
local numEvents = C_Calendar.GetNumDayEvents(monthOffset, day)
|
|
local numLoaded = 0
|
|
|
|
for i = 1, numEvents, 1 do
|
|
local CalendarDayEvent = C_Calendar.GetDayEvent(monthOffset, day, i)
|
|
local calendarType, texture = CalendarDayEvent.calendarType, CalendarDayEvent.iconTexture
|
|
|
|
if calendarType == "HOLIDAY" and texture ~= nil then
|
|
Rarity.holiday_textures[texture] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
function R:ScanInstanceLocks(reason)
|
|
self:Debug("Scanning instance locks (" .. reason .. ")")
|
|
|
|
local scanTip = Rarity.GUI.scanTip
|
|
|
|
table.wipe(Rarity.lockouts)
|
|
local savedInstances = GetNumSavedInstances()
|
|
for i = 1, savedInstances do
|
|
local instanceName, instanceID, instanceReset, instanceDifficulty, locked, extended, instanceIDMostSig =
|
|
GetSavedInstanceInfo(i)
|
|
|
|
-- Legacy code (deprecated)
|
|
if instanceReset > 0 then
|
|
scanTip:ClearLines()
|
|
scanTip:SetInstanceLockEncountersComplete(i)
|
|
for line = 2, scanTip:NumLines() do
|
|
local txtRight = _G["__Rarity_ScanTipTextRight" .. line]:GetText()
|
|
if txtRight then
|
|
if txtRight == BOSS_DEAD then
|
|
self.lockouts[_G["__Rarity_ScanTipTextLeft" .. line]:GetText()] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Detailed lockouts saving (stub - I'm leaving the legacy code above untouched, even if it's partly identical)
|
|
if instanceReset > 0 then -- Lockout isn't expired -> Scan it and store the defeated encounter names
|
|
scanTip:ClearLines()
|
|
scanTip:SetInstanceLockEncountersComplete(i)
|
|
for line = 2, scanTip:NumLines() do
|
|
local txtRight = _G["__Rarity_ScanTipTextRight" .. line]:GetText()
|
|
if txtRight then
|
|
if txtRight == BOSS_DEAD then
|
|
local encounterName = _G["__Rarity_ScanTipTextLeft" .. line]:GetText()
|
|
self.lockouts[encounterName] = true
|
|
-- Create containers if this is the first lockout for a given instance
|
|
self.lockouts_detailed[encounterName] = self.lockouts_detailed[encounterName] or {}
|
|
self.lockouts_detailed[encounterName][instanceDifficulty] = self.lockouts_detailed[encounterName][instanceDifficulty]
|
|
or {}
|
|
-- Add this lockout to the container
|
|
self.lockouts_detailed[encounterName][instanceDifficulty] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
table.wipe(Rarity.lockouts_holiday)
|
|
local num = GetNumRandomDungeons()
|
|
for i = 1, num do
|
|
local dungeonID, name = GetLFGRandomDungeonInfo(i)
|
|
local _, _, _, _, _, _, _, _, _, _, _, _, _, desc, isHoliday = GetLFGDungeonInfo(dungeonID)
|
|
if isHoliday and dungeonID ~= 828 then -- 828 = ??
|
|
local doneToday = GetLFGDungeonRewards(dungeonID)
|
|
self.lockouts_holiday[dungeonID] = doneToday
|
|
end
|
|
end
|
|
|
|
-- This code lists every LFG dungeon ID in the game (up through 1000)
|
|
-- for instanceID = 0, 1000 do
|
|
-- local dungeonName, typeId, subtypeId, minLvl, maxLvl, recLvl, minRecLvl, maxRecLvl, expansionId, groupId, textureName, difficulty, maxPlayers, dungeonDesc, isHoliday = GetLFGDungeonInfo(instanceID)
|
|
-- if dungeonName then
|
|
-- self:Print("instanceID = " .. instanceID .. " Name = " .. dungeonName .. " typeID = " .. tostring(typeId) .. " minLvl = " .. minLvl .. " maxLvl = " .. maxLvl .. " recLvl = " .. recLvl .. " groupId = " .. tostring(groupId) .." maxPlayers = " .. tostring(maxPlayers))
|
|
-- end
|
|
-- end
|
|
end
|
|
|
|
-- TODO: Does this really belong here? I don't think so...
|
|
function R:BuildStatistics(reason)
|
|
self:ProfileStart2()
|
|
-- self:Debug("Building statistics table ("..reason..")")
|
|
|
|
local tbl = {}
|
|
Rarity.lastStatCount = 0
|
|
|
|
for k, v in pairs(R.stats_to_scan) do
|
|
local s = GetStatistic(k)
|
|
tbl[k] = (tonumber(s or "0") or 0)
|
|
if not Rarity.db.profile.accountWideStatistics then
|
|
Rarity.db.profile.accountWideStatistics = {}
|
|
end
|
|
local charName = UnitName("player")
|
|
local charGuid = UnitGUID("player")
|
|
if charName and charGuid then
|
|
if not Rarity.db.profile.accountWideStatistics[charGuid] then
|
|
Rarity.db.profile.accountWideStatistics[charGuid] = {}
|
|
end
|
|
Rarity.db.profile.accountWideStatistics[charGuid].playerName = charName
|
|
Rarity.db.profile.accountWideStatistics[charGuid].server = GetRealmName() or ""
|
|
if not Rarity.db.profile.accountWideStatistics[charGuid].statistics then
|
|
Rarity.db.profile.accountWideStatistics[charGuid].statistics = {}
|
|
end
|
|
Rarity.db.profile.accountWideStatistics[charGuid].statistics[k] = (tonumber(s or "0") or 0)
|
|
end
|
|
Rarity.lastStatCount = Rarity.lastStatCount + 1
|
|
end
|
|
|
|
self:ProfileStop2("BuildStatistics: %fms")
|
|
return tbl
|
|
end
|
|
|
|
function R:ScanStatistics(reason)
|
|
if InCombatLockdown() then
|
|
return
|
|
end -- Don't do this during combat as it has a tendency to run too long
|
|
|
|
self:ProfileStart2()
|
|
-- self:Debug("Scanning statistics ("..reason..")")
|
|
|
|
if rarity_stats == nil or (Rarity.lastStatCount or 0) <= 0 then
|
|
self:Debug("Building initial statistics table")
|
|
rarity_stats = self:BuildStatistics(reason)
|
|
end
|
|
|
|
local newStats = self:BuildStatistics(reason)
|
|
|
|
for kk, vv in pairs(Rarity.items_with_stats) do
|
|
if type(vv) == "table" then
|
|
if
|
|
(vv.requiresHorde and R.Caching:IsHorde())
|
|
or (vv.requiresAlliance and not R.Caching:IsHorde())
|
|
or (not vv.requiresHorde and not vv.requiresAlliance)
|
|
then
|
|
if vv.statisticId and type(vv.statisticId) == "table" then
|
|
local count = 0
|
|
local totalCrossAccount = 0
|
|
|
|
for kkk, vvv in pairs(vv.statisticId) do
|
|
local newAmount = newStats[vvv] or 0
|
|
local oldAmount = rarity_stats[vvv] or 0
|
|
count = count + newAmount
|
|
|
|
-- Count up the total for this statistic across the entire account
|
|
if Rarity.db.profile.accountWideStatistics then
|
|
for playerGuid, playerData in pairs(Rarity.db.profile.accountWideStatistics) do
|
|
if playerData.statistics then
|
|
totalCrossAccount = totalCrossAccount
|
|
+ (Rarity.db.profile.accountWideStatistics[playerGuid].statistics[vvv] or 0)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- One of the statistics has gone up; add one attempt for this item
|
|
if newAmount > oldAmount then
|
|
R:Debug("Statistics indicate a new attempt for " .. vv.name)
|
|
vv.attempts = (vv.attempts or 0) + 1
|
|
self:OutputAttempts(vv, true)
|
|
end
|
|
end
|
|
|
|
-- We've never seen any attempts for this yet; update to this player's statistic total
|
|
if count > 0 and (vv.attempts or 0) <= 0 then
|
|
-- We seem to have gathered more attempts on this character than accounted for yet; update to new total
|
|
vv.attempts = count
|
|
self:OutputAttempts(vv, true)
|
|
elseif count > 0 and count > (vv.attempts or 0) and vv.doNotUpdateToHighestStat ~= true then -- Some items don't want us doing this (generally when Blizzard has a statistic overcounting bug)
|
|
R:Debug(
|
|
"Statistics for " .. vv.name .. " are higher than current amount. Updating to " .. count
|
|
)
|
|
vv.attempts = count
|
|
self:OutputAttempts(vv, true)
|
|
end
|
|
|
|
-- Cross-account statistic total is higher than the one we have; update to new total
|
|
if totalCrossAccount > (vv.attempts or 0) and vv.doNotUpdateToHighestStat ~= true then
|
|
R:Debug(
|
|
"Account-wide statistics for "
|
|
.. vv.name
|
|
.. " are higher than current amount. Updating to "
|
|
.. totalCrossAccount
|
|
)
|
|
vv.attempts = totalCrossAccount
|
|
self:OutputAttempts(vv, true)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Done with scan; update our saved table to the current scan
|
|
rarity_stats = newStats
|
|
|
|
if self.db.profile.debugMode then
|
|
R.stats = rarity_stats
|
|
end
|
|
|
|
-- Scan rare NPC achievements
|
|
table.wipe(Rarity.ach_npcs_isKilled)
|
|
table.wipe(Rarity.ach_npcs_achId)
|
|
for k, v in pairs(self.db.profile.achNpcs) do
|
|
local count = GetAchievementNumCriteria(v)
|
|
for i = 1, count do
|
|
local description, type, completed = GetAchievementCriteriaInfo(v, i)
|
|
Rarity.ach_npcs_achId[description] = v
|
|
if completed then
|
|
Rarity.ach_npcs_isKilled[description] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
self:ProfileStop2("ScanStatistics: %fms")
|
|
end
|
|
|