fix(quest/learner): draw turn-in '?' for in-log quests; learn turn-in NPC
Reverts the previous approach of stripping char.complete (which mutated completed-quest data). Correct rule: a quest in the player's log is active and should show its turn-in location regardless of the completed flag. - AddFinisher now trusts the live quest log: if the quest is in currentQuestlog and not failed, the '?' finisher draws regardless of the (possibly stale, e.g. prior-prestige) char.complete flag. No completion data is modified. Reverts the AcceptQuest and QUEST_QUERY_COMPLETE strips. - Learner: OnTargetChanged now learns quest-giver/turn-in NPC spawns (it previously only cached the GUID), so targeting a turn-in NPC records its location. OnQuestComplete/OnQuestTurnedIn fall back to the 'target' unit when the 'npc' gossip unit is already cleared, so the finisher NPC is reliably learned on turn-in. selene 0 errors; busted 145 successes / same 7 pre-existing failures.
This commit is contained in:
+34
-11
@@ -3417,6 +3417,23 @@ function QuestieLearner:OnTargetChanged()
|
||||
|
||||
_Learner.guidNpcCache = _Learner.guidNpcCache or {}
|
||||
_Learner.guidNpcCache[guid] = { npcId = entityId, name = name, ts = time() }
|
||||
|
||||
-- Learn this NPC's spawn if it is a quest giver/turn-in NPC (mirrors OnMouseoverUnit).
|
||||
-- Targeting a turn-in NPC should record its location so the finisher '?' can draw, even
|
||||
-- when UPDATE_MOUSEOVER_UNIT didn't fire for it (e.g. it was click- or tab-targeted).
|
||||
local npcFlags = UnitNPCFlags and UnitNPCFlags("target") or 0
|
||||
local isQuestGiver = NpcFlagsHasQuestGiver(npcFlags)
|
||||
if not isQuestGiver then
|
||||
local rawNpc = QuestieDB and QuestieDB.npcData and QuestieDB.npcData[entityId]
|
||||
if rawNpc and (rawNpc[10] or rawNpc[11]) then -- known quest starter (10) or ender (11)
|
||||
isQuestGiver = true
|
||||
end
|
||||
end
|
||||
if isQuestGiver then
|
||||
local subName = UnitCreatureFamily and UnitCreatureFamily("target") or nil
|
||||
-- nil coords -> LearnNPC falls back to the player's position (we're at the NPC).
|
||||
self:LearnNPC(entityId, name, level, subName, npcFlags, nil, nil, nil, nil)
|
||||
end
|
||||
end
|
||||
|
||||
-- Collects all available quest data from the quest detail/offer screen (before accepting)
|
||||
@@ -3479,19 +3496,22 @@ function QuestieLearner:OnQuestComplete()
|
||||
end
|
||||
self:LearnQuest(questId, data)
|
||||
|
||||
-- Identify the quest turn-in NPC or object
|
||||
local npcGuid = UnitGUID("npc")
|
||||
-- Identify the quest turn-in NPC or object. Prefer the "npc" gossip unit, but fall back
|
||||
-- to "target" since the player is targeting the turn-in NPC and the gossip unit isn't
|
||||
-- always populated on this client.
|
||||
local unit = (UnitGUID("npc") and "npc") or (UnitGUID("target") and "target") or nil
|
||||
local npcGuid = unit and UnitGUID(unit)
|
||||
if npcGuid then
|
||||
local entityId, unitType = self:ResolveNpcIdFromGuidAndName(npcGuid, UnitName("npc"))
|
||||
TraceLearnerEntity("quest_complete", npcGuid, unitType, entityId, UnitName("npc"))
|
||||
local entityId, unitType = self:ResolveNpcIdFromGuidAndName(npcGuid, UnitName(unit))
|
||||
TraceLearnerEntity("quest_complete", npcGuid, unitType, entityId, UnitName(unit))
|
||||
if entityId and entityId > 0 then
|
||||
local entityName = UnitName("npc")
|
||||
local entityName = UnitName(unit)
|
||||
if unitType == "GameObject" then
|
||||
self:LearnQuestGiver(questId, entityId, 2, false)
|
||||
self:LearnObject(entityId, entityName, nil, nil, zoneId, true)
|
||||
elseif unitType == "Creature" or unitType == "Vehicle" then
|
||||
self:LearnQuestGiver(questId, entityId, 1, false)
|
||||
local npcFlags = UnitNPCFlags and UnitNPCFlags("npc") or 2
|
||||
local npcFlags = UnitNPCFlags and UnitNPCFlags(unit) or 2
|
||||
self:LearnNPC(entityId, entityName, nil, nil, npcFlags, nil, nil, nil, zoneId)
|
||||
end
|
||||
end
|
||||
@@ -3800,18 +3820,21 @@ function QuestieLearner:OnQuestTurnedIn(questId, xpReward, moneyReward)
|
||||
if not questId or questId <= 0 then return end
|
||||
|
||||
local data = {}
|
||||
-- Capture turn-in NPC/object while the gossip unit is still set
|
||||
local npcGuid = UnitGUID("npc")
|
||||
-- Capture the turn-in NPC/object. The "npc" gossip unit can already be cleared by the
|
||||
-- time QUEST_TURNED_IN fires, so fall back to "target" (the player almost always still
|
||||
-- has the turn-in NPC targeted). This is what records the finisher's spawn location.
|
||||
local unit = (UnitGUID("npc") and "npc") or (UnitGUID("target") and "target") or nil
|
||||
local npcGuid = unit and UnitGUID(unit)
|
||||
if npcGuid then
|
||||
local entityId, unitType = self:ResolveNpcIdFromGuidAndName(npcGuid, UnitName("npc"))
|
||||
local entityId, unitType = self:ResolveNpcIdFromGuidAndName(npcGuid, UnitName(unit))
|
||||
if entityId and entityId > 0 then
|
||||
local entityName = UnitName("npc")
|
||||
local entityName = UnitName(unit)
|
||||
if unitType == "GameObject" then
|
||||
self:LearnQuestGiver(questId, entityId, 2, false)
|
||||
self:LearnObject(entityId, entityName, nil, nil, GetZoneId(), true)
|
||||
elseif unitType == "Creature" or unitType == "Vehicle" then
|
||||
self:LearnQuestGiver(questId, entityId, 1, false)
|
||||
local npcFlags = UnitNPCFlags and UnitNPCFlags("npc") or 2
|
||||
local npcFlags = UnitNPCFlags and UnitNPCFlags(unit) or 2
|
||||
self:LearnNPC(entityId, entityName, nil, nil, npcFlags, nil, nil, nil, GetZoneId())
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user