feat: heal learned npc coordinates from repeated kills
This commit is contained in:
@@ -352,7 +352,9 @@ local function CoordBucket(x, y)
|
|||||||
return floor(x / COORD_GRID) * COORD_GRID, floor(y / COORD_GRID) * COORD_GRID
|
return floor(x / COORD_GRID) * COORD_GRID, floor(y / COORD_GRID) * COORD_GRID
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Inserts {x, y} into coordList only when no existing point falls in the same grid bucket
|
-- Inserts {x, y} into coordList only when no existing point falls in the same grid bucket.
|
||||||
|
-- If a point already exists in that bucket, gently heal it toward the new evidence
|
||||||
|
-- using a weighted average so repeated kills converge instead of duplicating pins.
|
||||||
local function InsertIfNewBucket(coordList, x, y, customGrid)
|
local function InsertIfNewBucket(coordList, x, y, customGrid)
|
||||||
x, y = NormalizeCoordPair(x, y)
|
x, y = NormalizeCoordPair(x, y)
|
||||||
if not x or not y then return false end
|
if not x or not y then return false end
|
||||||
@@ -365,9 +367,17 @@ local function InsertIfNewBucket(coordList, x, y, customGrid)
|
|||||||
coord[1], coord[2] = existingX, existingY
|
coord[1], coord[2] = existingX, existingY
|
||||||
end
|
end
|
||||||
local cx, cy = floor((existingX or coord[1]) / grid) * grid, floor((existingY or coord[2]) / grid) * grid
|
local cx, cy = floor((existingX or coord[1]) / grid) * grid, floor((existingY or coord[2]) / grid) * grid
|
||||||
if cx == bx and cy == by then return false end
|
if cx == bx and cy == by then
|
||||||
|
local count = tonumber(coord[3]) or 1
|
||||||
|
local healedCount = count + 1
|
||||||
|
local healedX = ((existingX or coord[1]) * count + x) / healedCount
|
||||||
|
local healedY = ((existingY or coord[2]) * count + y) / healedCount
|
||||||
|
coord[1], coord[2] = NormalizeCoordPair(healedX, healedY)
|
||||||
|
coord[3] = healedCount
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
table.insert(coordList, {x, y})
|
table.insert(coordList, {x, y, 1})
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1497,8 +1507,12 @@ function QuestieLearner:_StoreGuidSpawnEvidence(npcId, dstGUID, zoneId, x, y)
|
|||||||
|
|
||||||
if guidSpawns[spawnUID] then
|
if guidSpawns[spawnUID] then
|
||||||
-- Existing spawn UID: update position and timestamp
|
-- Existing spawn UID: update position and timestamp
|
||||||
guidSpawns[spawnUID].x = nx
|
local existingCount = tonumber(guidSpawns[spawnUID].count) or 1
|
||||||
guidSpawns[spawnUID].y = ny
|
local healedCount = existingCount + 1
|
||||||
|
local healedX = ((guidSpawns[spawnUID].x or nx) * existingCount + nx) / healedCount
|
||||||
|
local healedY = ((guidSpawns[spawnUID].y or ny) * existingCount + ny) / healedCount
|
||||||
|
guidSpawns[spawnUID].x, guidSpawns[spawnUID].y = NormalizeCoordPair(healedX, healedY)
|
||||||
|
guidSpawns[spawnUID].count = healedCount
|
||||||
guidSpawns[spawnUID].ts = time()
|
guidSpawns[spawnUID].ts = time()
|
||||||
else
|
else
|
||||||
-- New spawn UID: insert, bounded by npcId+zoneId.
|
-- New spawn UID: insert, bounded by npcId+zoneId.
|
||||||
@@ -1526,6 +1540,7 @@ function QuestieLearner:_StoreGuidSpawnEvidence(npcId, dstGUID, zoneId, x, y)
|
|||||||
ts = time(),
|
ts = time(),
|
||||||
source = "local",
|
source = "local",
|
||||||
confidence = 1,
|
confidence = 1,
|
||||||
|
count = 1,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1584,8 +1599,12 @@ local function _MergeSpawnEvidence(npcId)
|
|||||||
if not evidence[key] then
|
if not evidence[key] then
|
||||||
evidence[key] = { zoneId = entry.zoneId, x = rx, y = ry, count = 0 }
|
evidence[key] = { zoneId = entry.zoneId, x = rx, y = ry, count = 0 }
|
||||||
end
|
end
|
||||||
evidence[key].count = evidence[key].count + 1
|
local evidenceWeight = tonumber(entry.count) or 1
|
||||||
totalEvidence = totalEvidence + 1
|
if evidenceWeight < 1 then
|
||||||
|
evidenceWeight = 1
|
||||||
|
end
|
||||||
|
evidence[key].count = evidence[key].count + evidenceWeight
|
||||||
|
totalEvidence = totalEvidence + evidenceWeight
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -105,6 +105,18 @@ describe("QuestieLearner kill-path batching", function()
|
|||||||
assert.is_true(table.getn(queuedTimers) >= 2)
|
assert.is_true(table.getn(queuedTimers) >= 2)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("heals repeated same-bucket npc coordinates without duplicating the learned spawn", function()
|
||||||
|
QuestieLearner:LearnNPC(2001, "Healing Boar", nil, nil, nil, nil, 40.10, 40.10, 44)
|
||||||
|
QuestieLearner:LearnNPC(2001, "Healing Boar", nil, nil, nil, nil, 40.30, 40.30, 44)
|
||||||
|
|
||||||
|
local spawns = Questie.dbLearner.global.npcs[2001][7][44]
|
||||||
|
assert.is_table(spawns)
|
||||||
|
assert.equals(1, table.getn(spawns))
|
||||||
|
assert.equals(2, spawns[1][3])
|
||||||
|
assert.is_true(math.abs(spawns[1][1] - 40.20) < 0.001)
|
||||||
|
assert.is_true(math.abs(spawns[1][2] - 40.20) < 0.001)
|
||||||
|
end)
|
||||||
|
|
||||||
it("force-flushes active quest pins within the NPC live-update flush (no second debounce)", function()
|
it("force-flushes active quest pins within the NPC live-update flush (no second debounce)", function()
|
||||||
local updateCount = 0
|
local updateCount = 0
|
||||||
local originalUpdateQuest = QuestieQuest.UpdateQuest
|
local originalUpdateQuest = QuestieQuest.UpdateQuest
|
||||||
|
|||||||
Reference in New Issue
Block a user