diff --git a/Core.lua b/Core.lua index 9a92a93..bc243a5 100644 --- a/Core.lua +++ b/Core.lua @@ -177,6 +177,7 @@ function Core:OnEnable() function() Data:ClearProgressCache() Data:ScanCurrencies() + Data:ScanShardOfDundun() self:Render() end ) diff --git a/Data.lua b/Data.lua index 0bfba7a..4ffeb81 100644 --- a/Data.lua +++ b/Data.lua @@ -27,7 +27,7 @@ Data.cache = { tradeSkillRecipes = {}, } -Data.DBVersion = 19 +Data.DBVersion = 21 Data.defaultDB = { ---@type WK_DefaultGlobal global = { @@ -89,6 +89,10 @@ Data.defaultCharacter = { factions = {}, currencies = {}, items = {}, + shardOfDundunWeeklyObtained = 0, + shardOfDundunWeeklySpent = 0, + shardOfDundunLastQuantity = 0, + shardOfDundunQuestPickedUp = false, } ---@type WK_Objective[] @@ -356,6 +360,20 @@ function Data:MigrateDB() end end end + -- Initialize Shard of Dundun tracking fields + if self.db.global.DBVersion == 19 then + for _, character in pairs(self.db.global.characters) do + if type(character.shardOfDundunWeeklyObtained) ~= "number" then character.shardOfDundunWeeklyObtained = 0 end + if type(character.shardOfDundunLastQuantity) ~= "number" then character.shardOfDundunLastQuantity = 0 end + end + end + -- Initialize Shard of Dundun spent tracking and quest pickup fields + if self.db.global.DBVersion == 20 then + for _, character in pairs(self.db.global.characters) do + if type(character.shardOfDundunWeeklySpent) ~= "number" then character.shardOfDundunWeeklySpent = 0 end + if type(character.shardOfDundunQuestPickedUp) ~= "boolean" then character.shardOfDundunQuestPickedUp = false end + end + end self.db.global.DBVersion = self.db.global.DBVersion + 1 self:MigrateDB() end @@ -383,6 +401,14 @@ function Data:TaskWeeklyReset() end end end + -- Reset Shard of Dundun weekly tracking + if type(character.shardOfDundunWeeklyObtained) == "number" then + character.shardOfDundunWeeklyObtained = 0 + end + if type(character.shardOfDundunWeeklySpent) == "number" then + character.shardOfDundunWeeklySpent = 0 + end + character.shardOfDundunQuestPickedUp = false end end self.db.global.weeklyReset = GetServerTime() + C_DateAndTime.GetSecondsUntilWeeklyReset() @@ -442,6 +468,7 @@ function Data:ScanAll() self:ScanQuests() self:ScanProfessions() self:ScanCalendar() + self:ScanShardOfDundun() end --- Scan currencies for a character. @@ -472,6 +499,9 @@ function Data:ScanCurrencies() end end) + -- Track Shard of Dundun currency + currencyIDs[self.SHARD_OF_DUNDUN_CURRENCY_ID] = true + -- Track currency IDs from skill line variants Utils:TableForEach(skillLineVariants, function(skillLineVariant) if skillLineVariant.catchUpCurrencyID and skillLineVariant.catchUpCurrencyID > 0 then @@ -494,6 +524,7 @@ function Data:ScanCurrencies() quality = currencyInfo.quality, quantity = currencyInfo.quantity, maxQuantity = currencyInfo.maxQuantity, + quantityEarnedThisWeek = currencyInfo.quantityEarnedThisWeek, rechargingCycleDurationMS = currencyInfo.rechargingCycleDurationMS, rechargingAmountPerCycle = currencyInfo.rechargingAmountPerCycle, lastUpdated = GetServerTime(), @@ -898,6 +929,47 @@ function Data:ScanItems() Utils:Debug("└ Finshed") end +--- Shard of Dundun currency ID: 3376, 8 obtainable per week, only 6 needed (2 given from quest). +Data.SHARD_OF_DUNDUN_CURRENCY_ID = 3376 +Data.SHARD_OF_DUNDUN_PER_WEEK = 8 +Data.SHARD_OF_DUNDUN_QUEST_ID = 89507 -- Abundant Offerings: awards 2 shards on pickup + +--- Scan Shard of Dundun for the current character. +--- Uses the API's quantityEarnedThisWeek for obtained count; tracks spent via delta detection. +function Data:ScanShardOfDundun() + Utils:Debug("┌ ScanShardOfDundun()") + if self:IsInChatMessagingLockdown() then return end + if InCombatLockdown and InCombatLockdown() then return end + local character = self:GetCharacter() + if not character then return end + + local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(self.SHARD_OF_DUNDUN_CURRENCY_ID) + if not currencyInfo then return end + + local currentQuantity = currencyInfo.quantity or 0 + + -- Weekly obtained comes directly from the API + character.shardOfDundunWeeklyObtained = currencyInfo.quantityEarnedThisWeek or 0 + + -- Track spent via delta detection (API doesn't provide this) + if type(character.shardOfDundunWeeklySpent) ~= "number" then character.shardOfDundunWeeklySpent = 0 end + if type(character.shardOfDundunLastQuantity) ~= "number" then character.shardOfDundunLastQuantity = 0 end + + local lastQuantity = character.shardOfDundunLastQuantity + if currentQuantity < lastQuantity then + character.shardOfDundunWeeklySpent = character.shardOfDundunWeeklySpent + (lastQuantity - currentQuantity) + end + + -- Check if the Abundant Offerings quest has been picked up or completed + character.shardOfDundunQuestPickedUp = C_QuestLog.IsOnQuest(self.SHARD_OF_DUNDUN_QUEST_ID) or C_QuestLog.IsQuestFlaggedCompleted(self.SHARD_OF_DUNDUN_QUEST_ID) + + character.shardOfDundunLastQuantity = currentQuantity + character.lastUpdate = GetServerTime() + + Utils:Debug("├ Shard of Dundun: current=" .. currentQuantity .. " weeklyObtained=" .. character.shardOfDundunWeeklyObtained .. " weeklySpent=" .. character.shardOfDundunWeeklySpent .. " questPickedUp=" .. tostring(character.shardOfDundunQuestPickedUp)) + Utils:Debug("└ Finshed") +end + ---@return table function Data:GetCharacters() local characters = Utils:TableFilter(self.db.global.characters or {}, function(character) @@ -1037,6 +1109,18 @@ function Data:GetObjectiveProgress(character, objective) objectiveProgress.items[objective.itemID] = false end + -- Shard of Dundun + if objective.categoryID == Enum.WK_ObjectiveCategory.ShardOfDundun then + local weeklyObtained = character.shardOfDundunWeeklyObtained or 0 + local weeklySpent = character.shardOfDundunWeeklySpent or 0 + objectiveProgress.pointsEarned = weeklyObtained + objectiveProgress.pointsTotal = self.SHARD_OF_DUNDUN_PER_WEEK + objectiveProgress.questsCompleted = weeklySpent + objectiveProgress.questsTotal = self.SHARD_OF_DUNDUN_PER_WEEK + objectiveProgress.isCompleted = weeklySpent >= self.SHARD_OF_DUNDUN_PER_WEEK + return objectiveProgress + end + -- Catch Up if objective.categoryID == Enum.WK_ObjectiveCategory.CatchUp then local characterCurrency = self:GetCharacterCurrency(character, skillLineVariant.catchUpCurrencyID) diff --git a/Data/ObjectiveCategories.lua b/Data/ObjectiveCategories.lua index e7cbb1b..22fd10d 100644 --- a/Data/ObjectiveCategories.lua +++ b/Data/ObjectiveCategories.lua @@ -16,4 +16,5 @@ Data.ObjectiveCategories = { {id = Enum.WK_ObjectiveCategory.Gathering, name = "Gathering", description = "These are randomly looted from gathering nodes around the world.\n\nFor Enchanting these are looted from Disenchanting.\n\nRepeatable: " .. WHITE_FONT_COLOR:WrapTextInColorCode("Weekly"), type = "item", repeatable = "Weekly",}, {id = Enum.WK_ObjectiveCategory.DarkmoonQuest, name = "Darkmoon", description = "Complete a quest at the Darkmoon Faire.\n\nRepeatable: " .. WHITE_FONT_COLOR:WrapTextInColorCode("Monthly"), type = "quest", repeatable = "Monthly",}, {id = Enum.WK_ObjectiveCategory.CatchUp, name = "Catch-Up", description = "Keep track of your catch-up points.\n\nYou will be able to gain these points once you've completed some of the other objectives.\n\nRepeatable: " .. WHITE_FONT_COLOR:WrapTextInColorCode("Yes"), type = "item", repeatable = "Yes",}, + {id = Enum.WK_ObjectiveCategory.ShardOfDundun, name = "Dundun", description = "Weekly Shard of Dundun progress.\n\n8 shards obtainable per week with 6 found throughout the world.\nYou get 2 for free when starting the Abundant Offerings quest.\n\nRepeatable: " .. WHITE_FONT_COLOR:WrapTextInColorCode("Weekly"), type = "item", repeatable = "Weekly",}, } diff --git a/Data/Objectives/ShardOfDundun.lua b/Data/Objectives/ShardOfDundun.lua new file mode 100644 index 0000000..3c0479f --- /dev/null +++ b/Data/Objectives/ShardOfDundun.lua @@ -0,0 +1,37 @@ +---@type string +local addonName = select(1, ...) +---@class WK_Addon +local addon = select(2, ...) + +---@class WK_Data +local Data = addon.Data +local Utils = addon.Utils +local category = Enum.WK_ObjectiveCategory.ShardOfDundun + +---@type WK_Objective[] +local objectives = { + -- Midnight: Alchemy + {skillLineVariantID = 2906, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Blacksmithing + {skillLineVariantID = 2907, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Enchanting + {skillLineVariantID = 2909, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Engineering + {skillLineVariantID = 2910, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Herbalism + {skillLineVariantID = 2912, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Inscription + {skillLineVariantID = 2913, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Jewelcrafting + {skillLineVariantID = 2914, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Leatherworking + {skillLineVariantID = 2915, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Mining + {skillLineVariantID = 2916, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Skinning + {skillLineVariantID = 2917, categoryID = category, quests = {89507}, points = 8}, + -- Midnight: Tailoring + {skillLineVariantID = 2918, categoryID = category, quests = {89507}, points = 8}, +} + +Data.Objectives = Utils:TableMerge(Data.Objectives, objectives) diff --git a/Main.lua b/Main.lua index 9b07ecb..74f00b1 100644 --- a/Main.lua +++ b/Main.lua @@ -902,6 +902,8 @@ function Main:GetTableColumns(unfiltered) return end + local dundunSeenCharacters = {} + ---@type WK_DataColumn local dataColumn = { name = objectiveCategory.name, @@ -914,7 +916,7 @@ function Main:GetTableColumns(unfiltered) onLeave = function() GameTooltip:Hide() end, - width = 90, + width = objectiveCategory.id == Enum.WK_ObjectiveCategory.ShardOfDundun and 110 or 90, toggleHidden = true, align = "CENTER", cell = function(character, characterProfession, skillLineVariantID) @@ -926,7 +928,38 @@ function Main:GetTableColumns(unfiltered) local text = format("%d / %d", categoryProfessionProgress.objectivesCompleted, categoryProfessionProgress.objectivesTotal) - if objectiveCategory.id == Enum.WK_ObjectiveCategory.CatchUp then + if objectiveCategory.id == Enum.WK_ObjectiveCategory.ShardOfDundun then + -- Only show once per character since the data is identical across professions + if dundunSeenCharacters[character.GUID] then + return {text = ""} + end + dundunSeenCharacters[character.GUID] = true + + local weeklyObtained = categoryProfessionProgress.pointsEarned + local weeklySpent = categoryProfessionProgress.objectivesCompleted -- questsCompleted mapped to spent + local weeklyMax = categoryProfessionProgress.pointsTotal + local hasData = (type(character.shardOfDundunLastQuantity) == "number" and character.shardOfDundunLastQuantity > 0) or weeklyObtained > 0 + local questPickedUp = character.shardOfDundunQuestPickedUp or false + local obtainedThreshold = questPickedUp and 8 or 6 + + if not hasData and weeklyObtained == 0 then + text = GRAY_FONT_COLOR:WrapTextInColorCode(format("%d / %d / %d", weeklyObtained, weeklySpent, weeklyMax)) + elseif weeklySpent >= weeklyMax and weeklyObtained >= weeklyMax then + -- All done: everything green + text = GREEN_FONT_COLOR:WrapTextInColorCode(format("%d / %d / %d", weeklyObtained, weeklySpent, weeklyMax)) + elseif weeklySpent >= weeklyMax then + -- Spent all 8 but obtained < 8: only spent is green + local obtainedStr = tostring(weeklyObtained) + local spentStr = GREEN_FONT_COLOR:WrapTextInColorCode(tostring(weeklySpent)) + text = format("%s / %s / %d", obtainedStr, spentStr, weeklyMax) + elseif weeklyObtained >= obtainedThreshold then + -- Obtained enough but not spent all: obtained is green, rest white + local obtainedStr = GREEN_FONT_COLOR:WrapTextInColorCode(tostring(weeklyObtained)) + text = format("%s / %d / %d", obtainedStr, weeklySpent, weeklyMax) + else + text = format("%d / %d / %d", weeklyObtained, weeklySpent, weeklyMax) + end + elseif objectiveCategory.id == Enum.WK_ObjectiveCategory.CatchUp then text = format("%d / %d", categoryProfessionProgress.pointsEarned, categoryProfessionProgress.pointsTotal) -- if categoryProfessionProgress.objectivesTotal == 0 then -- text = "-" @@ -935,7 +968,7 @@ function Main:GetTableColumns(unfiltered) return {text = ""} end - if categoryProfessionProgress.pointsEarned > 0 and categoryProfessionProgress.pointsEarned >= categoryProfessionProgress.pointsTotal then + if objectiveCategory.id ~= Enum.WK_ObjectiveCategory.ShardOfDundun and categoryProfessionProgress.pointsEarned > 0 and categoryProfessionProgress.pointsEarned >= categoryProfessionProgress.pointsTotal then text = GREEN_FONT_COLOR:WrapTextInColorCode(text) end @@ -948,7 +981,20 @@ function Main:GetTableColumns(unfiltered) local requirementsHeading = "Requirements:" - if objectiveCategory.id == Enum.WK_ObjectiveCategory.CatchUp then + if objectiveCategory.id == Enum.WK_ObjectiveCategory.ShardOfDundun then + local weeklyObtained = categoryProfessionProgress.pointsEarned + local weeklySpent = categoryProfessionProgress.objectivesCompleted + local weeklyMax = categoryProfessionProgress.pointsTotal + GameTooltip:AddDoubleLine("Obtained This Week:", format("%d / %d", weeklyObtained, weeklyMax), nil, nil, nil, 1, 1, 1) + GameTooltip:AddDoubleLine("Spent This Week:", format("%d / %d", weeklySpent, weeklyMax), nil, nil, nil, 1, 1, 1) + GameTooltip:AddLine(" ") + GameTooltip:AddLine("|cff00ff00Note:|r You need to collect 6 shards weekly as 2 are given to you when you pick up the Abundant Offerings quest.", nil, nil, nil, true) + local currencyInfo = Data:GetCharacterCurrency(character, Data.SHARD_OF_DUNDUN_CURRENCY_ID) + if currencyInfo then + GameTooltip:AddLine(" ") + GameTooltip:AddDoubleLine("Current Total:", format("%d", currencyInfo.quantity), nil, nil, nil, 1, 1, 1) + end + elseif objectiveCategory.id == Enum.WK_ObjectiveCategory.CatchUp then GameTooltip:AddDoubleLine("Points Earned:", format("%d", categoryProfessionProgress.pointsEarned), nil, nil, nil, 1, 1, 1) GameTooltip:AddDoubleLine("Points Available:", format("%d", categoryProfessionProgress.pointsTotal - categoryProfessionProgress.pointsEarned), nil, nil, nil, 1, 1, 1) GameTooltip:AddDoubleLine("Max Points:", format("%d", categoryProfessionProgress.pointsTotal), nil, nil, nil, 1, 1, 1) diff --git a/Types.lua b/Types.lua index 36ad38b..cbb3155 100644 --- a/Types.lua +++ b/Types.lua @@ -69,6 +69,10 @@ ---@field factions table factionID -> WK_CharacterFaction ---@field currencies table currencyID -> WK_CharacterCurrency ---@field items table itemID -> quantity +---@field shardOfDundunWeeklyObtained integer Shard of Dundun obtained this week +---@field shardOfDundunWeeklySpent integer Shard of Dundun spent this week +---@field shardOfDundunLastQuantity integer Last known Shard of Dundun currency quantity +---@field shardOfDundunQuestPickedUp boolean Whether the Abundant Offerings quest has been picked up this week ---@class WK_CharacterCurrency ---@field id integer Currency ID @@ -77,6 +81,7 @@ ---@field quality integer Quality ---@field quantity integer Current quantity ---@field maxQuantity integer Max quantity +---@field quantityEarnedThisWeek integer Quantity earned this week ---@field rechargingCycleDurationMS integer Recharging cycle duration in milliseconds (e.g. 10000) ---@field rechargingAmountPerCycle integer Recharging amount per cycle (e.g. 1) ---@field lastUpdated number Last update time @@ -284,6 +289,7 @@ Enum.WK_ObjectiveCategory = { DarkmoonQuest = "DarkmoonQuest", CatchUp = "CatchUp", WeeklyQuest = "WeeklyQuest", + ShardOfDundun = "ShardOfDundun", } ---@enum Enum.WK_Factions diff --git a/WeeklyKnowledge.toc b/WeeklyKnowledge.toc index 967f94d..799484c 100644 --- a/WeeklyKnowledge.toc +++ b/WeeklyKnowledge.toc @@ -50,6 +50,7 @@ Data\Objectives\FirstCraft.lua Data\Objectives\Gathering.lua Data\Objectives\Treasure.lua Data\Objectives\Treatise.lua +Data\Objectives\ShardOfDundun.lua Data\Objectives\Unique.lua Data\Objectives\WeeklyQuest.lua