7ce0cdcf99
Real bug fixes (no behavior additions that risk regressions): - LearnNPC: require both spawnX/spawnY AND x/y before accepting a spawn entry. Previously quest-giver/finisher dialog polluted spawn lists with the player's current position. - _MergeSpawnEvidence: respect IsAscensionProtected ownership gate unconditionally. The 'test mode' comment-out is removed; AscensionDB curated spawn data is now protected from learner overwrite (fixes the Sunstrider Mana Wyrm pin regression). - _PruneSpawnOutliers and PruneLearnedSpawnOutliers: fix broken next() iteration. The old code used 'coord = next(spawnTable); while coord do ... coord = next(spawnTable, coord)' which treated the KEY as the value. For numeric spawn arrays this returned indices (1, 2, ...) but the code did coord[1] and coord[2] on those indices, which are nil. The outlier pruning was effectively dead code. Now iterates with 'coordKey, coord = next(spawnTable)' correctly, sorts toRemove keys descending for safe table.remove, and compacts numeric arrays. - InjectLearnedData: early-exit when learner disabled, strip [7] on initial npcDataOverrides creation (only _MergeSpawnEvidence should populate spawns), versioned cleanup that retroactively clears singleton-position spawn entries (≤1 unique position) from pollution caused by the prior LearnNPC bug. Supporting utilities added: CopyWithoutField, CountUniqueSpawnPositions, NormalizeCoordPair reuse (replaces inline floor(x*100+0.5)/100).