Commit Graph

184 Commits

Author SHA1 Message Date
Xurkon 27c1bd6889 fix(minimap): enable floatOnEdge for all 1241 pins
Previously DrawWorldIcon and DrawManualIcon both set floatOnEdge=false
for uiMapId 1241, forcing icons to always show regardless of distance.
This caused pins to render at minimap center when near a spawn, making
them appear to orbit/follow the player as they rotated.

The zone->world coordinate pipeline was verified correct: zoneW matches
dataW exactly for 1241 icons, and playerW is in the same coordinate
space. The problem was purely the floatOnEdge=false behavior combined
with the icon being essentially at the minimap center (1% of radius).

Enabling floatOnEdge=true lets the standard edge-floating path handle
1241 pins like every other zone: icons clamp to the edge when far,
slide along the rim when approaching, and occupy their correct angular
bearing from the player rather than sitting at dead center.
2026-06-01 18:35:39 -05:00
Xurkon 72b924c514 wip: preserve Sunstrider minimap debugging state 2026-06-01 18:35:39 -05:00
Xurkon c6436c486d fix(quest): guard against malformed waypoint data in _DrawObjectiveWaypoints
Error: attempt to index field '?' (a number value) at line 1932.
waypoints[1] was a bare number instead of a coordinate pair {x,y}.
Added type(waypoints[1]) ~= 'table' guard alongside existing type(waypoints)
check. Also simplified firstWaypoint access since the guard ensures it's a table.

The underlying data issue (flat numbers vs coordinate pairs) is in the DB
and should be tracked separately — this fix prevents the crash only.
2026-06-01 18:35:04 -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 7ea4061959 fix(quest): Phase 1 compat — guard quest-log-aware frame unload
Prevent premature frame unloading for completed-but-logged quests:
- AvailableQuests: UnloadUndoable() guard on currentQuestlog
- DailyQuests: HandleDailyQuests() guard on currentQuestlog
- QuestieQuest: IsSafeToUnloadQuestFrames() helper + HideQuest() guard
- TooltipHandler: IsQuestFlaggedCompleted gated by currentQuestlog
- TrackerUtils: fallback IsComplete gated by currentQuestlog

Revert: git revert HEAD --no-edit
2026-05-24 00:43:41 -05:00
Xurkon a0c827f6b1 test(learner): Phase 5 unit tests for comms data validation 2026-05-24 00:37:41 -05:00
Xurkon 598f7d3652 feat(learner): Phase 5 — comms data validation 2026-05-24 00:37:27 -05:00
Xurkon 6eaa67277f test(learner): Phase 4 unit tests for tooltip population 2026-05-24 00:36:40 -05:00
Xurkon c5d8c5ffe5 feat(learner): Phase 4 — real-time tooltip for learned spawns 2026-05-24 00:36:19 -05:00
Xurkon 021d1b942b feat(learner): Phase 3 — weighted spawn merge 2026-05-24 00:33:09 -05:00
Xurkon 6c121e7bc4 feat(learner): Phase 2 — GUID-based spawn evidence and outlier pruning 2026-05-24 00:29:47 -05:00
Xurkon 44244f504f debug(Arrow): show spawnList coords and world coords for target
- PrintTargetCoords: add world coords computed from zone coord + uiMapId
- _CollectObjective debug: show spawnList[id] zone, firstCoord, isLearned per entry
2026-05-22 20:46:29 -05:00
Xurkon 085a49b15e fix(Arrow): correct Felendren arrow coordinates on Sunstrider
- _ResolveArrowUiMapId: stop redirecting 1241→1941. With zoneDB now
  mapping areaId 3431→uiMapId 1241, and player on uiMapId 1241, keeping
  1241 as 1241 ensures both player and target world coords are computed
  through the same ASCENSION_ZONE_BOUNDS[1241] calibration (1600x1066.67,
  -2721, 8433.94). This gives correct ~169yd distance and bearing.
2026-05-22 19:47:06 -05:00
Xurkon 415b924199 fix(Sunstrider): correct map pins, override check, nil guards
- zoneDB: remap areaId 3431 → uiMapId 1241 (Sunstrider Isle) so quest 8335
  pins render on correct map instead of Eversong Woods (1941)
- compat/HBD: remove 1241→1941 redirect (Sunstrider pins now handled by zoneDB)
- compiler: QuerySingle override check skips empty tables (next() guard) so
  spawn data overrides don't fall through to nil base DB values
- MapIconTooltip: nil guards for minLevel/maxLevel to prevent crashes
- Map/QuestieMap: remove stale 1241→1941 redirect comment
2026-05-22 19:31:47 -05:00
Xurkon 8ab14db3a3 fix(quest): map pins disappear after first kill
AlreadySpawned kept stale entries after UnloadQuestFrames ran.
The draw path for incomplete objectives never cleared it — only
completed objectives called _UnloadAlreadySpawnedIcons. Added
clear at the start of the spawnList draw path so _DetermineIconsToDraw
sees an empty AlreadySpawned and recreates icons each update cycle.
2026-05-21 19:46:17 -05:00
Xurkon afb58e1c2f fix(quest): learned spawns suppressed after quest re-accept
The monster handler replaced spawns with learned data when
prioritizeMyData was enabled but didn't set isLearned=true on
monsterData. The prioritizeMyData filter in PopulateObjective
checked 'if not spawnData.isLearned' and suppressed the spawn,
causing pins to not render after quest abandon+re-accept cycle.
2026-05-21 19:41:03 -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 7f99e7228d fix: clear QuestieDB entity caches on live override injection
QuestieDB:GetNPC and GetObject cache results in _QuestieDB.npcCache /
_QuestieDB.objectCache. When LearnNPC / LearnObject injects new spawn
coordinates into npcDataOverrides / objectDataOverrides, the cached
objects still hold stale (empty) spawn data. PopulateObjective rebuilds
spawnList by calling GetNPC/GetObject, but gets the cached empty data.

Fix: clear the relevant cache entry immediately after live injection so
the next GetNPC/GetObject call rebuilds with fresh override data.

This is the root cause of 'pins not showing on kill' — the spawnList
was rebuilt, but from a stale cache that didn't include the new learned
coordinates.
2026-05-16 09:37:38 -05:00
Xurkon 810ea7f802 fix: real-time minimap pins + defensive GetAchievementNumCriteria shim
1. _InvalidateSpawnListsForNPC was setting objective.AlreadySpawned = nil,
   causing _DetermineIconsToDraw to crash on nil-index when trying to draw
   updated pins. The xpcall wrapper in UpdateObjectiveNotes swallowed the
   error silently, so no icons appeared.

   Fix: unload existing map/minimap icons explicitly, then set
   AlreadySpawned = {} (empty table) instead of nil. Also clear
   hasRegisteredTooltips so tooltips refresh.

2. Added GetAchievementNumCriteria defensive shim for Ascension servers
   with incomplete achievement databases. Returns 0 for invalid IDs
   instead of hard-erroring in Blizzard's WorldMapFrame.
2026-05-16 08:54:52 -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 306fb2ac89 Fix learned tooltip quest-start schema in Stormwind 2026-05-13 21:54:09 -05:00
Xurkon b6f4e08880 Revert Tooltip.lua to v1.6.1 (3f8563c) - fixing nameplate icon regression 2026-05-10 10:19:30 -05:00
Xurkon a885faa364 area lookup fixes 2026-05-09 23:53:44 -05:00
Xurkon 01b7f07c41 Fix MapIconTooltip _GetLevelString nil level crash
Root cause: creatureLevels entry for 'Uneasy Citizen' was {} (empty table)
instead of {minLevel, maxLevel, rank}, so creatureLevels[name][1] was nil.
Added early-return guard in _GetLevelString: if creatureLevels[name] is
falsy or has no numeric level at index [1], return name unchanged.

Also updated CHANGELOG.md [Unreleased] section with this fix.
2026-05-09 08:23:54 -05:00
Xurkon 6738027e4d Fix Sunstrider Isle arrow, Tooltip type guard, mapId 946 override
- zoneDB.lua: Add [946] = 3430 to UiMapIdOverrides so GetCurrentZoneId()
  returns 3430 (Sunstrider Isle areaId) even when the game returns uiMapId 946
  (ghost/loading map). Previously 946 had no override, causing zone lookups to
  fall through and return 946 instead of the real zone, breaking arrow distance
  calculation and target filtering.

- QuestieArrow.lua: UpdateNearestTargets uses QuestiePlayer:GetCurrentUiMapId()
  (backed by C_Map.GetBestMapForUnit) for player position. When that returns an
  invalid/ghost map (946/947/0), fall back to ZoneDB lookup via the actual
  zoneId. This ensures the arrow gets real world coordinates regardless of
  whether the world map is open or closed.

  Also includes per-frame debug output when debugArrow profile is enabled.

- Tooltip.lua: Add type guard 'if type(objList) ~= table then break end'
  before iterating learnedNpc[10] and learnedObj[10] in both m_/NPC and o_/object
  paths. Prevents 'attempt to index field questData (a string value)' error
  when the questData field is unexpectedly a string instead of a table.

  The original loop used 'for questId, objList in next, learnedNpc[10]' which
  iterates key-value pairs in insertion order. The _AddToArray helper stores
  values as sequential array elements (tbl[key]=value via table.insert), but
  the iteration was treating it as a questId->objList map. Fixed to use
  ipairs-style iteration with a type check for robustness.
2026-05-09 06:48:59 -05:00
Xurkon 98b4010352 fix: silence QuestLogCache error spam in normal chat
Demote GetQuest/GetQuestObjectives 'quest doesn't exist in QuestLogCache'
messages from Questie:Error to Questie:Debug(DEBUG_DEVELOP). These were
firing repeatedly in chat for quest IDs like 595, 959, 254048 during normal
play. Messages are now only visible when developer debug mode is active.
2026-05-04 21:14:22 -05:00
Xurkon a0f3a1e020 v1.6.1: Fix map icon completion persistence after objective fulfillment
- SetObjectivesDirty: Add missing loop to reset isUpdated on SpecialObjectives
- PopulateObjective: Add completion guard for objectives without Update fn
- Bump version to 1.6.1 across TOC and changelogs
2026-05-04 19:57:43 -05:00
Xurkon def947bec1 Fix LSM30:Fetch guards - also check LSM30.Fetch exists before calling
Previous guard only checked LSM30 ~= nil; if Fetch method is absent on
the stub object the call still crashes. Now uses full 3-part check:
  (LSM30 and LSM30.Fetch and LSM30:Fetch(...)) or fallback
Matches the pattern already used in QuestieArrow.lua.
2026-04-24 04:36:25 -05:00
Xurkon a2a325c8ab Guard all LibSharedMedia-3.0 usages against nil LSM - OptionalDep may not load
- Use LibStub(..., true) silent flag on all LSM acquisition sites
- Guard HashTable() calls in Options files (returns nil if no font type registered)
- Guard all Fetch() call sites with inline 'LSM30 and LSM30:Fetch() or fallback'
- Make font values lazy functions in options dropdowns so LSM has time to register
- Affects: QuestieOptionsTracker, QuestieOptionsArrow, QuestieArrow, QuestieTracker,
  TrackerHeaderFrame, TrackerLinePool, TrackerQuestTimers
2026-04-24 04:24:38 -05:00
Xurkon 97c8f60a28 QuestieOptionsArrow: guard LibSharedMedia HashTable call - LSM is OptionalDep, may not be present or have font type registered at load time 2026-04-24 03:59:33 -05:00
Xurkon 08eace3115 fix: Blood of Heroes object rendering and QuestieQuest runtime crash fixes 2026-04-12 00:45:50 -05:00
Xurkon 49477da2d0 v1.6.0: Stable Map Search & Blood of Heroes Data Fix 2026-04-08 17:34:15 -05:00
Xurkon 4ef2b9f661 hotfix: Resolved critical QuestieQuest runtime crash and hardened error handler 2026-04-08 03:48:46 -05:00
Xurkon 199ed47868 Hotfix: Resolve syntax error in ChatFilter.lua and stabilize nil guards 2026-04-08 03:21:05 -05:00
Xurkon 26dd06cf9d Fix critical LUA crash in QuestLinks due to nil concatenation and invalid chat link matching 2026-04-07 17:46:06 -05:00
Xurkon 1e5da24529 fix: Guard against nil IdList in killcredit objective 2026-04-02 20:59:50 -05:00
Xurkon 49ef9b6e55 fix: Use pairs() instead of ipairs() for hash table iteration 2026-04-02 20:51:08 -05:00
Xurkon 03a58e0c28 feat: Add expanded font list with common WoW fonts to Arrow and Tracker options 2026-04-02 20:43:17 -05:00
Xurkon a9f4a97979 cleanup: Remove debug prints and duplicate spacer 2026-04-02 19:45:17 -05:00
Xurkon 2efbc0e799 fix: Use SharedMedia:Fetch to get actual font object 2026-04-02 19:42:15 -05:00
Xurkon 11cc0e9a79 debug: Add print to UpdateFont 2026-04-02 19:36:52 -05:00
Xurkon aa51ea8f2a fix: Import SharedMedia in Arrow options 2026-04-02 19:34:24 -05:00
Xurkon 447ba0513e fix: Guard against QuestieConfigFrame being nil in OpenConfigWindow 2026-04-02 19:30:56 -05:00
Xurkon 57f6cc4471 feat: Add arrow font settings; Add Apply to All font options to Tracker 2026-04-02 19:27:05 -05:00
Xurkon 882cd01628 debug: Add prints to UpdateSettings 2026-04-02 19:17:52 -05:00
Xurkon cf462d9a9f debug: Add print to scale set 2026-04-02 19:16:21 -05:00
Xurkon 1decb399b3 fix: Remove duplicate arrow_alpha and debug prints 2026-04-02 19:14:08 -05:00
Xurkon fb8c4292c9 debug: Add prints to trace scale update 2026-04-02 19:06:56 -05:00
Xurkon a1f273bba5 fix: Add UpdateSettings function to apply scale/alpha without touching visibility 2026-04-02 19:04:20 -05:00