Commit Graph

33 Commits

Author SHA1 Message Date
Xurkon 011cdb58a9 fix(learner): defer to AscensionDB curated spawns for owned NPCs
Mana Wyrm 15274 (quest 8325) pins rendered in the NE corner because the
learner's Sunstrider spawns leaked into the curated AscensionDB coords.
Root causes:
- In learner mode GetNPC uses rawdata = learner record, and _MergeOverride
  deep-merges spawn tables, so the learner's bad zone (1445 @ 54,12)
  survived since AscensionDB had no entry to displace it.
- The injection guards used IsAscensionProtected(), which returns false in
  learner mode, so the learner overrode AscensionDB-owned spawns. Commit
  0f20ea8 had also added a (not learnerLiveMode) bypass to the
  _MergeSpawnEvidence Sunstrider guard, re-enabling the e80a008 regression.

Fixes:
- QuestieDB.GetNPC: for AscensionDB-owned NPC spawns (direct
  ascensionOverrideKeys check), use ONLY the curated override spawns and
  discard the merged learner zones.
- New mode-independent AscensionOwnsNpcSpawns() helper; used by the
  InjectLearnedData spawn restore and the _MergeSpawnEvidence guard
  (removed the (not learnerLiveMode) bypass).

Regression test asserts GetNPC returns only the curated 1241 coords and
drops the learner 1445 zone.
2026-06-08 17:53:16 -05:00
Xurkon bb0edacec0 fix(db): enrich auto-mode static quests with learner objective payload
In 'auto' data-source mode, QuestieDB.GetQuest now overlays the
SavedVariables learner record on top of the static DB quest, filling only
nil fields and deep-merging objectives/objIndex. Fixes quests like 8325
where the shipped DB has only a stub record but QuestieLearner holds the
real objective mapping that the stub was blocking. Learner data never
overwrites a present static value, so it strictly enriches.
2026-06-08 07:59:54 -05:00
Xurkon 31bd1e7d9b fix: dedupe missing quest lookup logs 2026-06-06 13:33:11 -05:00
Xurkon 00567c833f fix: guard quest source items without objectives 2026-06-06 13:23:47 -05:00
Xurkon c76650b70c fix: merge learner overrides in learner mode 2026-06-06 11:56:46 -05:00
Xurkon 6597d20b7d feat: refine learner data source and pin rendering 2026-06-06 00:04:50 -05:00
Xurkon 6f4bd69d00 fix: draw pins from immediate learner kill evidence 2026-06-05 22:27:27 -05:00
Xurkon 94707e1b93 fix: make learner db reads self-sustaining 2026-06-05 21:46:16 -05:00
Xurkon 3eda8d01ed fix: force learner on when base db is missing 2026-06-05 20:23:29 -05:00
Xurkon a0409eef8c feat: add learner/static data source mode 2026-06-05 20:15:26 -05:00
Xurkon aa973188ce fix: guard item name lookup against invalid ids 2026-06-05 17:55:52 -05:00
Xurkon 31864a467e fix: harden learner spawn suppression 2026-06-03 06:41:23 -05:00
Xurkon c59b4dc9de fix(db): deep-merge spawn tables on override; respect learner enabled flag
- Add CopySpawnTable and MergeSpawnTables helpers to deep-merge spawn
  coordinate lists (zoneId -> {{x,y}, ...}) instead of replacing them
  wholesale. Previously an override containing spawns would clobber the
  base list, reducing visible pins for any NPC with partial overrides
  (Sunstrider Isle calibration, Ascension area-specific fixes, etc.).
- _MergeOverride now special-cases the 'spawns' key to call the merger
  with the base spawn table as a fallback when override is empty.
- GetSuppressedNPCs/Objects now check ld.settings.enabled alongside
  prioritizeMyData. When the learner is fully disabled, the suppression
  pass is skipped entirely (additive and AND-only).
2026-06-01 18:35:39 -05:00
Xurkon 164584ca87 fix: Sunstrider pin regression, ghost pins, and learner zone normalization
- Fix: isSunstrider block in _MergeSpawnEvidence now checks IsAscensionProtected
  before writing learner data to npcDataOverrides. Without this guard, each Mana
  Wyrm kill overwrote AscensionDB's z1241=5 data with learner z3431 coords.

- Fix: Clustering disabled for zone 1241 (Sunstrider Isle) in _DrawObjectiveIcons
  so all 5 AscensionDB spawn pins display individually instead of collapsing to 2.

- Fix: Ghost pin loop in AvailableQuests.lua -- 'while frames[i]' was iterating a
  string-keyed table with a numeric index (never iterated). Changed to pairs().

- Fix: NormalizeSpawnZoneKey now uses ZoneDB.areaIdToUiMapId for all zones so
  learner evidence is stored under map IDs (e.g. 1241) not area IDs (e.g. 3431),
  matching AscensionDB's key space. Applied in LearnNPC and _StoreGuidSpawnEvidence.

- Fix: isSunstrider detection in _MergeSpawnEvidence updated from hardcoded
  zoneId==3431 check to IsSunstriderNativeZone() since zone IDs are now normalized
  to map IDs at storage time.
2026-05-25 19:02:56 -05:00
Xurkon 24ed0f48b3 fix(arrow): Sunstrider zoneId 3431, rotation CW, collection distance, native map pins
- zoneId detection: accept 3430 OR 3431 OR uiMapId 1241 (4 locations)
- SetRotation is CW-positive: rotAngle=relative (was -relative)
- Collection functions: override target->1241 when player on Sunstrider
- NPC 15281: spawn zone 1241 (not 3430) for correct coord space
- _ResolveMapUiMapId: removed 1241->1941 redirect
- zoneDB: added areaIdToUiMapId[1241]=1241
- Updated CHANGELOG, README, docs
2026-05-21 19:22:40 -05:00
Xurkon d3bcb6da49 fix: empty override tables no longer wipe base DB spawns; real-time pin refresh on NPC learn
Two fixes for QuestieLearner real-time pin rendering:

1. _MergeOverride now skips empty tables (IsEmptyTable guard).
   QuestieLearner stores spawns={} before any coords are captured.
   Previously _MergeOverride treated {} as valid data and replaced the
   base DB's real spawn coordinates with an empty table, breaking pins
   for all NPCs that had been seen but not killed (mouseovers, etc.).

2. _InvalidateSpawnListsForNPC triggers after LearnNPC adds new spawn data.
   The quest objective system caches spawnList once per objective.
   When a kill adds new coordinates, the cached list is stale.
   The new helper:
   - Scans all active quest objectives for references to the NPC
   - Clears objective.spawnList and objective.AlreadySpawned
   - Calls QuestieQuest:UpdateQuest to rebuild pins with fresh data
   This makes learned pins appear in real-time without /reload.
2026-05-16 08:36:47 -05:00
Xurkon bf6ecaedbe v1.6.3-unreleased: Sunstrider zone fixes, QuestieLearner icon preservation, migration, and Busted test suite
Code changes (13 files, +916/-171):
- ZoneDB integration: GetZoneId() converts uiMapId→areaId via ZoneDB reverse lookup
- MIN_CONFIDENCE_PINS reduced to 1 for Ascension (incomplete NPC DBs)
- QuestieLearner icon preservation: objective Icon passed to RegisterObjectiveTooltip
- InjectLearnedData zone migration: converts old uiMapId spawn keys to areaId
- areaId passed through all LearnNPC call sites (OnMouseoverUnit, OnQuestDetail,
  OnQuestComplete, OnQuestAccepted, OnQuestTurnedIn, OnGossipShow)
- Compat/Compat.lua: C_Map.GetPlayerMapPosition UiMapData support
- Compat/HBD.lua: Sunstrider mapData aliases and fallback loading
- Sunstrider arrow fix (QuestieArrow.lua), resolved pin rendering (QuestieMap.lua)
- _MergeOverride helper for string/numeric key compatibility
- Northshire Valley UiMapData registration

Testing infrastructure:
- .busted config pointing to tests/ directory
- Tests/wow_api_mock.lua: WoW API mocks (ZoneDB, C_Map, QuestLogCache, etc.)
- Tests/QuestieLearner_spec.lua: 12 tests covering coordinate scaling, spell cast
  learning, zone migration (NPC/objects), icon preservation, settings defaults,
  and LearnNPC spawn zone tracking
- selene.toml + wow_classic.yml: linter configuration

Documentation:
- Makefile with test/lint/ci targets
- sunstrider-coordinate-collection.md: coordinate data reference
- sunstrider-pin-fix.md: root cause analysis and fix documentation
2026-05-16 07:32:47 -05:00
Xurkon 49477da2d0 v1.6.0: Stable Map Search & Blood of Heroes Data Fix 2026-04-08 17:34:15 -05:00
Xurkon 5edb8ddcf8 Fix: Remove debugstack print spam from QuestieDB.GetQuest 2026-03-29 05:58:23 -05:00
Xurkon 59c33e9f9c feat: standardize v1.5.0 and consolidate stability fixes 2026-03-28 11:08:32 -05:00
Xurkon 1fc9727fee v1.4.9: Validation fixes, Profiler fix, Quest link duplicate fix, Ascension fixes 2026-03-26 06:47:54 -05:00
Xurkon 6e34cebead feat: release v1.4.6 - Fix SavedVariables persistence and red textures for MafWow/3.3.5a 2026-03-22 08:30:20 -05:00
Xurkon b0f8ba22e7 feat: release v1.3.0 - QuestieLearner Confidence & Tiered Pruning Engine 2026-03-17 22:33:01 -05:00
Xurkon 4db9737a35 chore: stage all pending changes (DB cleanup, corrections, compiler, init, plugin API) 2026-03-16 19:41:52 -05:00
Xurkon c4d003e58f feat: Questie-X v1.1.4 - plugin architecture, monorepo, rebranding
- Repoint remote to Xurkon/Questie-X
- Add QuestiePluginAPI, QuestieServer, QuestieLearnerComms modules
- Add Questie-X.toc, Questie-X-Classic.toc, Questie-X-TBC.toc, Questie-X-Turtle.toc
- Remove embedded Database/Ascension and Database/Ebonhold (migrated to plugins)
- Add Plugins/ directory with NTFS junctions for Questie-X-AscensionDB and Questie-X-EbonholdDB
- Add LibDeflate, XXH_Lua_Lib, LibDBIcon-1.0, LibDataBroker-1.1
- Update README: Questie-X branding, logo, plugin install guide, plugin API docs
- Update CHANGELOG: v1.1.4 entry documenting all architectural changes
- Update .gitignore: exclude plugin junctions, __pycache__, .agents, debug files
- Various module updates: corrections, map, tracker, tooltips, quest, options
2026-03-14 06:10:17 -05:00
Xurkon 8616765eed Update custom DB quests and bump version to 9.8.5 2026-02-24 20:52:12 -06:00
Xurkon 94ed16d7f0 Release v9.7.11 2026-02-21 23:42:42 -06:00
Xurkon c42945a1f8 Release v9.7.10 2026-02-21 22:52:51 -06:00
Xurkon 7328771932 Add debug print to IsComplete for tricky quest 2026-02-21 12:43:21 -06:00
Xurkon 922fa8e0ff Fix Lua truthiness bug in QuestieDB.IsComplete
In Lua, 0 evaluates as truthy. The check
'if questLogEntry.isComplete then return questLogEntry.isComplete end'
was completely bypassing our fallback completion logic because
GetQuestLogTitle sets isComplete = 0 when a quest is incomplete.

This caused the arrow to still point to requiredSourceItems (like
the Cold Iron Key drops) because the quest was never being flagged
as 'isComplete=true' internally.

Fixed by explicitly checking for isComplete == 1 or isComplete == -1
before returning.
2026-02-21 12:18:45 -06:00
Xurkon 25f2ece139 Fix IsComplete: check numFulfilled==numRequired instead of finished flag
The finished flag in QuestLogCache is only set to true when the server
sends isComplete=1 via GetQuestLogTitle. For quest 12843 ('They Took
Our Men!'), after using all Cold Iron Keys the objectives numerically
complete (5/5) but isComplete=1 may not fire until the player visits
the turn-in NPC.

Use numFulfilled == numRequired as the completion check instead, which
updates from GetQuestLogLeaderBoard immediately when each objective
fills. Added numRequired > 0 guard to avoid trivially matching
zero-required objectives.
2026-02-21 11:44:32 -06:00
Xurkon 9890343616 Fix IsComplete returning 0 when all objectives are finished
The inline ternary short-circuited to 0 as soon as objectives[1]
existed, regardless of whether all objectives were done. This caused
quests using consumable key items (e.g. Cold Iron Key for quest 12843)
to incorrectly return IsComplete=0 after using the key, since the key
is no longer in the bag (CheckQuestSourceItem=false) and
questLogEntry.isComplete is not set by the server until after
explicit turn-in.

Now iterates questLogEntry.objectives and returns 1 if all are
finished, so PopulateObjectiveNotes routes to AddFinisher correctly.
2026-02-21 11:28:14 -06:00
Xurkon 6ef85d4e2d v9.7.2: Ebonhold Database integration and core logic refinements 2026-02-14 21:13:44 -06:00