fix(learner): seed objective pins on accept; handle monster objectives

OnQuestAccepted now seeds objective pins directly from the SavedVariables
learner payload (objIndex) on accept in learner mode, instead of waiting
for quest-log text sync — so quests like 8325 spawn pins immediately when
the objective mapping already exists. The accept-time ID lookup is widened
from killcredit to also cover monster objectives, and falls back to
objData.Id when no IdList is present.
This commit is contained in:
Xurkon
2026-06-08 08:00:15 -05:00
parent bb0edacec0
commit d92ae93870
2 changed files with 39 additions and 5 deletions
+1
View File
@@ -29,6 +29,7 @@
- **[Tooltip - Item ID Always Shown]** `AddItemDataToTooltip` previously gated the "Item ID" line on the item having a registered quest-objective tooltip — for items that are not part of any quest objective (e.g. trade goods, vendor trash, quest-start items with no other Questie data attached), the option to show IDs had no visible effect. The line is now added for every item hover when the option is enabled, mirroring the NPC/Object tooltip behavior. Also switched the call to `self:AddDoubleLine` so the ID lands on the actual frame that fired `OnTooltipSetItem` (which can be `ItemRefTooltip` for chat links, not just `GameTooltip`).
- **[Tooltip - Item Starts Quest]** Item tooltips now surface a "Drops a quest !" line with the quest title when the item has a non-zero `startQuest` value in the static DB / Ascension override table and the player does not already have the quest (active or turned in). The item→quest relationship is a build-time DB field — we never know it ahead of runtime observation — so it is read directly from `QueryItemSingle` at hover time. The line uses `QuestieLib:GetColoredQuestName` so the quest title respects the same level/complete state formatting the rest of Questie uses.
- **[QuestieDB - Auto Mode Learner Enrichment]** In `auto` data-source mode, `QuestieDB.GetQuest` now overlays the SavedVariables learner payload on top of the static DB record, filling only fields the static record leaves `nil` and deep-merging `objectives`/`objIndex`. This fixes quests like 8325 where the shipped DB carries only a stub record but QuestieLearner holds the real objective mapping — previously the stub blocked the learned objectives from ever surfacing. Learner data never clobbers a present static value, so it strictly enriches and cannot regress shipped data.
- **[QuestieLearner - Accept-Time Objective Pin Seeding]** `OnQuestAccepted` now seeds objective pins directly from the SavedVariables learner payload (`objIndex`) the moment a quest is accepted in learner mode, instead of waiting for quest-log text sync. This makes quests like 8325 spawn pins immediately on accept when the objective mapping already exists. The accept-time ID lookup was also widened from `killcredit` to also cover `monster` objectives, and now falls back to `objData.Id` when no `IdList` is present, catching cases where the quest-log text does not normalize cleanly to the NPC name.
### Tooltip
+38 -5
View File
@@ -3550,13 +3550,19 @@ function QuestieLearner:OnQuestAccepted(firstArg, secondArg)
if targetName and targetName ~= "" then
local npcId = nil
local objectId = nil
-- For killcredit, try ID-based lookup first using quest objectives data
if objType == "killcredit" then
-- For monster/killcredit objectives, try ID-based lookup first using quest objectives data.
-- This catches accept-time pins before the first kill event for quests like 8325,
-- where the quest log text may not normalize cleanly to the NPC name.
if objType == "killcredit" or objType == "monster" then
local quest = QuestieDB and QuestieDB.GetQuest and QuestieDB.GetQuest(questId)
if quest and quest.ObjectiveData and quest.ObjectiveData[j] then
local objData = quest.ObjectiveData[j]
if objData.IdList then
for _, possibleId in ipairs(objData.IdList) do
local candidateIds = objData.IdList
if not candidateIds and objData.Id and objData.Id > 0 then
candidateIds = { objData.Id }
end
if candidateIds then
for _, possibleId in ipairs(candidateIds) do
if possibleId and possibleId > 0 then
local npc = QuestieDB:GetNPC(possibleId)
if npc and npc.name and string.lower(npc.name) == string.lower(targetName) then
@@ -3567,7 +3573,7 @@ function QuestieLearner:OnQuestAccepted(firstArg, secondArg)
end
-- Fallback: try first valid ID in the list even if name doesn't match
if not npcId then
for _, possibleId in ipairs(objData.IdList) do
for _, possibleId in ipairs(candidateIds) do
if possibleId and possibleId > 0 then
local npc = QuestieDB:GetNPC(possibleId)
if npc then
@@ -3615,10 +3621,37 @@ function QuestieLearner:OnQuestAccepted(firstArg, secondArg)
end
end
-- In learner mode, seed objective pins directly from the SavedVariables payload.
-- This bypasses quest-log text sync timing and ensures quests like 8325 spawn pins
-- immediately on accept when the objective mapping already exists in QuestieLearnerDB.
if GetDataSourceMode() == "learner" then
local learnedQuest = Questie and Questie.dbLearner and Questie.dbLearner.global and Questie.dbLearner.global.quests and Questie.dbLearner.global.quests[questId]
if learnedQuest and learnedQuest.objIndex then
local objIndex, entry = next(learnedQuest.objIndex)
while objIndex do
if entry and entry.id then
local entryId = entry.id
if type(entryId) == "table" then
entryId = entryId[1]
end
if entryId and entryId > 0 then
if entry.type == "object" then
self:LearnQuestObjectiveObject(questId, entryId, entry.text or entry.Text or "", objIndex)
else
self:LearnQuestObjectiveNPC(questId, entryId, entry.text or entry.Text or "", objIndex)
end
end
end
objIndex, entry = next(learnedQuest.objIndex, objIndex)
end
end
end
-- Associate the quest giver: prefer live UnitGUID("npc"), fall back to last gossip entity
-- (for Objectives Board quests, GOSSIP_CLOSED fires before QUEST_ACCEPTED so "npc" is nil)
local npcGuid = UnitGUID("npc")
local giverEntity = nil
if npcGuid then
local entityId, unitType = self:ResolveNpcIdFromGuidAndName(npcGuid, UnitName("npc"))
if entityId and entityId > 0 then