From cccfa1e81b9aead2338e4515fc04e778f771fcb7 Mon Sep 17 00:00:00 2001 From: Xurkon Date: Sat, 6 Jun 2026 07:44:17 -0500 Subject: [PATCH] fix: preserve explicit learner spawn data --- Modules/QuestieLearner.lua | 15 +++++++++++---- Tests/QuestieLearner_performance_spec.lua | 13 +++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Modules/QuestieLearner.lua b/Modules/QuestieLearner.lua index 0480e03..6de8b6a 100644 --- a/Modules/QuestieLearner.lua +++ b/Modules/QuestieLearner.lua @@ -1400,6 +1400,12 @@ function QuestieLearner:LearnNPC(npcId, name, level, subName, npcFlags, factionS existing[7] = existing[7] or {} existing[7][zoneId] = existing[7][zoneId] or {} InsertIfNewBucket(existing[7][zoneId], x, y, GetCoordGridForZone(zoneId)) + existing.spawnSource = "explicit" + elseif existing.spawnSource ~= "explicit" and existing.spawnSource ~= "learned" then + -- Quest-giver/turn-in fallback learning uses the player's position as a proxy. + -- Keep that separate from actual learned spawn evidence so we can safely + -- discard it later without deleting real kill/object-driven coordinates. + existing.spawnSource = "fallback" end existing.ls = time() -- Update last seen @@ -1543,6 +1549,8 @@ function QuestieLearner:_StoreGuidSpawnEvidence(npcId, dstGUID, zoneId, x, y) count = 1, } end + + learnedNpc.spawnSource = "learned" end ------------------------------------------------------------------------ @@ -2476,16 +2484,15 @@ function QuestieLearner:InjectLearnedData() end -- Versioned cleanup: strip spawns from NPCs learned via quest giver/finisher - -- fallback (player position stored as spawn by LearnNPC). These have only - -- a single spawn position regardless of confidence — real kill NPCs - -- accumulate spawns at multiple distinct locations. + -- fallback (player position stored as spawn by LearnNPC). Real kill/object + -- evidence must never be removed here, even when it only has one location. local fallbackSpawnCleanupVersion = 2 if (learned._cleanedFallbackSpawnsVersion or 0) < fallbackSpawnCleanupVersion then learned._cleanedFallbackSpawns = true learned._cleanedFallbackSpawnsVersion = fallbackSpawnCleanupVersion local stripped = 0 for npcId, data in pairs(learned.npcs) do - if data[7] and CountUniqueSpawnPositions(data[7]) <= 1 then + if data.spawnSource == "fallback" and data[7] and CountUniqueSpawnPositions(data[7]) <= 1 then data[7] = nil stripped = stripped + 1 end diff --git a/Tests/QuestieLearner_performance_spec.lua b/Tests/QuestieLearner_performance_spec.lua index 39f0feb..55a6810 100644 --- a/Tests/QuestieLearner_performance_spec.lua +++ b/Tests/QuestieLearner_performance_spec.lua @@ -117,6 +117,19 @@ describe("QuestieLearner kill-path batching", function() assert.is_true(math.abs(spawns[1][2] - 40.20) < 0.001) end) + it("keeps explicit learned npc spawns available for learner arrows", function() + Questie.dbLearner.global.settings.dataSourceMode = "learner" + QuestieLearner:LearnNPC(3001, "Arrow Boar", nil, nil, nil, nil, 22.10, 33.20, 44) + QuestieLearner:InjectLearnedData() + + assert.equals("explicit", Questie.dbLearner.global.npcs[3001].spawnSource) + assert.is_table(Questie.dbLearner.global.npcs[3001][7]) + assert.is_table(Questie.dbLearner.global.npcs[3001][7][44]) + assert.equals(1, table.getn(Questie.dbLearner.global.npcs[3001][7][44])) + assert.equals(22.10, Questie.dbLearner.global.npcs[3001][7][44][1][1]) + assert.equals(33.20, Questie.dbLearner.global.npcs[3001][7][44][1][2]) + end) + it("force-flushes active quest pins within the NPC live-update flush (no second debounce)", function() local updateCount = 0 local originalUpdateQuest = QuestieQuest.UpdateQuest