779 lines
66 KiB
HTML
779 lines
66 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Questie-X - Developer Documentation</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--bg-primary: #0d1117;
|
||
--bg-secondary: #161b22;
|
||
--bg-tertiary: #21262d;
|
||
--text-primary: #c9d1d9;
|
||
--text-secondary: #8b949e;
|
||
--accent-green: #3fb950;
|
||
--accent-blue: #58a6ff;
|
||
--accent-purple: #a371f7;
|
||
--accent-orange: #d29922;
|
||
--border-color: #30363d;
|
||
--code-bg: #1b1f23;
|
||
}
|
||
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||
background: var(--bg-primary);
|
||
color: var(--text-primary);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.hero {
|
||
background: linear-gradient(135deg, #1c2128 0%, #0d1117 100%);
|
||
padding: 80px 20px;
|
||
text-align: center;
|
||
border-bottom: 1px solid var(--border-color);
|
||
position: relative;
|
||
}
|
||
|
||
.hero h1 {
|
||
font-size: 3rem;
|
||
font-weight: 700;
|
||
margin-bottom: 15px;
|
||
background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple));
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
|
||
.hero .subtitle {
|
||
font-size: 1.2rem;
|
||
color: var(--text-secondary);
|
||
max-width: 800px;
|
||
margin: 0 auto 30px;
|
||
}
|
||
|
||
.container {
|
||
max-width: 1000px;
|
||
margin: 0 auto;
|
||
padding: 60px 20px;
|
||
}
|
||
|
||
section {
|
||
margin-bottom: 80px;
|
||
}
|
||
|
||
h2 {
|
||
font-size: 1.8rem;
|
||
margin-bottom: 30px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
color: var(--accent-blue);
|
||
}
|
||
|
||
h3 {
|
||
font-size: 1.3rem;
|
||
margin: 30px 0 15px;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
p {
|
||
margin-bottom: 15px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
code {
|
||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||
background: var(--bg-tertiary);
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
pre {
|
||
background: var(--code-bg);
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--border-color);
|
||
overflow-x: auto;
|
||
margin: 20px 0;
|
||
}
|
||
|
||
pre code {
|
||
background: none;
|
||
padding: 0;
|
||
color: #e6edf3;
|
||
}
|
||
|
||
.grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 30px;
|
||
margin: 30px 0;
|
||
}
|
||
|
||
.card {
|
||
background: var(--bg-secondary);
|
||
padding: 30px;
|
||
border-radius: 12px;
|
||
border: 1px solid var(--border-color);
|
||
}
|
||
|
||
.card h4 {
|
||
color: var(--accent-green);
|
||
margin-bottom: 10px;
|
||
font-size: 1.1rem;
|
||
}
|
||
|
||
.important {
|
||
background: rgba(210, 153, 34, 0.1);
|
||
border-left: 4px solid var(--accent-orange);
|
||
padding: 15px 20px;
|
||
margin: 20px 0;
|
||
border-radius: 0 4px 4px 0;
|
||
}
|
||
|
||
footer {
|
||
text-align: center;
|
||
padding: 40px;
|
||
border-top: 1px solid var(--border-color);
|
||
color: var(--text-secondary);
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.file-path {
|
||
color: var(--accent-purple);
|
||
font-weight: 600;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.hero h1 {
|
||
font-size: 2.2rem;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="hero">
|
||
<img src="QuestieXlogo.png" alt="Questie-X Logo" width="400" />
|
||
<p class="subtitle">Complete history of changes, fixes, and additions.</p>
|
||
<div style="display: flex; justify-content: center; gap: 10px;">
|
||
<a href="index.html"
|
||
style="color: var(--accent-blue); text-decoration: none; border: 1px solid var(--border-color); padding: 5px 10px; border-radius: 4px;">←
|
||
Back to Documentation</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container">
|
||
<h2 id="v130">v1.3.0 — QuestieLearner Confidence & Tiered Pruning Engine</h2>
|
||
<p><em>Implements a robust verification model for learned data, introducing a tiered confidence system (Verified vs Unconfirmed), automated stale data cleanup with protection for high-confidence entries, and a critical correction to coordinate scaling logic for 3.3.5a combat log events. Refactors global data sharing to utilize hidden chat channels for community-wide confidence calculation.</em></p>
|
||
|
||
<h3>QuestieLearner.lua — Confidence & Coordinate Scaling</h3>
|
||
<ul>
|
||
<li><strong>[Coordinate Scaling Fix — 0-100 normalization]</strong> <code>OnCombatLogEvent</code> now explicitly scales player position coordinates by 100 before recording. Previously, <code>C_Map.GetPlayerMapPosition</code> returned values on a 0-1 range, while Questie's internal modules and map pins expect 0-100. This fix resolves the "pins in the top-left corner" bug for all learned data.</li>
|
||
<li><strong>[Tiered Data Model — Verified vs Unconfirmed]</strong> Introduced the <code>mc</code> (Match Count) field as a primary confidence metric. Data is promoted to "Verified" status once <code>mc >= minConfidencePins</code> (default: 2). Verified data is exempt from automatic time-based pruning.</li>
|
||
<li><strong>[Last Seen (ls) Timestamping]</strong> Added a <code>ls</code> key to the learned data schema for NPCs, Objects, Quests, and Items. Updated on every kill, interaction, or network confirmation. This provides the temporal baseline for the new stale data cleanup engine.</li>
|
||
<li><strong>[Confidence-based Map Pin Gating]</strong> Modified the map pin generation logic to honor the <code>minConfidencePins</code> setting. Pins only appear on the map/minimap if the learned data has been confirmed by multiple kills (either local or received via network).</li>
|
||
<li><strong>[Global Data Sharing — QuestieComms Refactor]</strong> Switched from <code>PARTY</code>/<code>RAID</code> channels to a hidden global channel for learned data broadcast. This allows kills by any Questie-X user in the vicinity to contribute to local data confidence, effectively crowd-sourcing verification in real-time.</li>
|
||
<li><strong>[Tooltip Confidence Display]</strong> The tooltip handler now pulls the <code>mc</code> count for learned entries and displays it alongside the "Learned" label (e.g., <code>(Learned - Confidence: 3)</code>), providing immediate visual feedback on data reliability.</li>
|
||
</ul>
|
||
|
||
<h3>QuestieLearnerExport.lua — Tiered Pruning Engine</h3>
|
||
<ul>
|
||
<li><strong>[RunPrune — Stale threshold logic]</strong> Implemented automated time-based pruning in the <code>Cleanup</code> function. Only entries marked as "Unconfirmed" (low confidence) are subject to expiration. The expiration logic uses <code>(time() - entry.ls) > staleThreshold</code> (default: 90 days).</li>
|
||
<li><strong>[Verified Protection]</strong> Verified entries are explicitly protected from the time-based cleanup loop unless the <code>pruneVerified</code> setting is manually enabled by the user.</li>
|
||
</ul>
|
||
|
||
<h3>QuestieOptionsDatabase.lua — Verification Controls</h3>
|
||
<ul>
|
||
<li><strong>[Stale Threshold Slider]</strong> Added a configuration slider in the Database tab allowing users to set the cleanup window (1 to 180 days).</li>
|
||
<li><strong>[Prune Verified Toggle]</strong> Added a checkbox to allow manual purging of verified data if desired.</li>
|
||
<li><strong>[Prioritize My Data]</strong> Implemented a "Prioritize My Data" toggle that dynamically hides static database pins when high-confidence learned data exists for the same NPC in a zone.</li>
|
||
</ul>
|
||
|
||
<h2 id="v129">v1.2.9 — QuestieLearner Cross-Link Engine + Tracker Zone Fix + Untrack Fix</h2>
|
||
<p><em>Introduces a universal bidirectional cross-link engine in QuestieLearner that automatically stitches relationships between all four entity types (NPCs, Quests, Objects, Items) as data is learned — no manual wiring needed. Fixes the tracker's persistent "Unknown Zone" header for custom/unknown quests by replacing unreliable map API calls with the canonical 3.3.5a quest log header walk. Fixes a logic inversion in UntrackQuestId that prevented shift-click untacking from working.</em></p>
|
||
|
||
<h3>QuestieLearner.lua — Universal Cross-Link Engine</h3>
|
||
<ul>
|
||
<li><strong>[Cross-link engine — full rewrite]</strong> Replaced the narrow NPC↔Quest cross-link stubs with a comprehensive bidirectional relationship engine covering all four entity types. Three shared primitives underpin the whole system: <code>_AddToArray(tbl, key, value, ovrTable, ovrId)</code> adds a value to an array field and mirrors it to the live <code>*DataOverrides</code> table in the same call; <code>_AddToNestedArray</code> does the same for two-level nested arrays (used for quest starters/finishers sub-slots <code>quest[2][1]</code>, <code>quest[2][2]</code>, etc.); <code>_AddToQuestObjective</code> inserts <code>{entityId, text}</code> pairs into <code>quest[10][slot]</code> with the same dual-write pattern. Every write is idempotent — a no-op if the value is already present. All three primitives write to both <code>learnedData</code> (SavedVariables, persistent) and the live <code>*DataOverrides</code> tables (in-memory, immediate effect on map pins and tooltips).</li>
|
||
<li><strong>[CrossLinkAfterNPC]</strong> Called whenever a new NPC ID is first committed to <code>learnedData.npcs</code>. Performs three scans across all learned quests: (a) if <code>quest[2][1]</code> contains this npcId → adds questId to <code>npc[10]</code> (questStarts); (b) if <code>quest[3][1]</code> contains this npcId → adds questId to <code>npc[11]</code> (questEnds); (c) walks <code>quest[10][3]</code> (item objectives) — for each item whose <code>item[2]</code> (npcDrops) already references this NPC, the NPC is injected into <code>quest[10][1]</code> as a creature objective so it receives map pins and tooltip kill-count text.</li>
|
||
<li><strong>[CrossLinkAfterQuest]</strong> Called when a new quest is first committed to <code>learnedData.quests</code>. Links all referenced entities in one pass: starter NPCs (<code>quest[2][1]</code>) → each known NPC's <code>npc[10]</code>; starter objects (<code>quest[2][2]</code>) → each known object's <code>obj[2]</code>; finisher NPCs (<code>quest[3][1]</code>) → <code>npc[11]</code>; finisher objects (<code>quest[3][2]</code>) → <code>obj[3]</code>; source item (<code>quest[11]</code>) → <code>item[5]</code> (startQuest key per itemDB schema); item drop chain: for each item in <code>quest[10][3]</code> whose <code>item[2]</code> lists known NPCs, those NPCs are injected into <code>quest[10][1]</code> as creature objectives.</li>
|
||
<li><strong>[CrossLinkAfterObject]</strong> Called when a new object is first committed to <code>learnedData.objects</code>. Scans all learned quests: if <code>quest[2][2]</code> references this objectId → adds questId to <code>obj[2]</code> (questStarts); if <code>quest[3][2]</code> references it → adds questId to <code>obj[3]</code> (questEnds).</li>
|
||
<li><strong>[CrossLinkAfterItem]</strong> Called when a new item is first committed to <code>learnedData.items</code> AND whenever a new drop-NPC relationship is added via <code>LearnItemDrop</code>. Two passes: (1) scan all learned quests for <code>quest[11] == itemId</code> → set <code>item[5] = questId</code> (this item starts that quest); (2) scan all learned quests for <code>quest[10][3]</code> entries matching itemId — for each such quest, every NPC in <code>item[2]</code> (drop sources) is injected into <code>quest[10][1]</code> as a creature objective. Practical example: accept a quest needing "Wolf Pelt" → wolf is killed and the pelt drops → <code>LearnItemDrop</code> fires → <code>CrossLinkAfterItem</code> runs → the wolf NPC is immediately added as a creature objective for the pelt quest with active map pins, no reload.</li>
|
||
<li><strong>[CrossLinkAfterQuestGiver]</strong> Now handles all three entity type slots (1=NPC, 2=Object, 3=Item) instead of only NPCs. For typeSlot=1: stitches <code>npc[10/11]</code> ↔ <code>quest[2/3][1]</code> bidirectionally. For typeSlot=2: stitches <code>obj[2/3]</code> ↔ <code>quest[2/3][2]</code>. For typeSlot=3: adds itemId to <code>quest[2][3]</code> (item starters sub-slot). Called by <code>LearnQuestGiver</code> for all typeSlots, replacing the previous NPC-only check.</li>
|
||
<li><strong>[LearnItemDrop hook]</strong> Now calls <code>CrossLinkAfterItem(itemId)</code> every time a new NPC is added to an item's drop list, not only on initial item creation. This retroactively propagates the drop→quest objective chain for previously learned items.</li>
|
||
<li><strong>[LearnQuest / LearnObject / LearnItem hooks]</strong> Each now calls its respective <code>CrossLinkAfterX</code> function on first creation of the entity record. Subsequent updates to an existing record skip the cross-link scan (already linked on creation).</li>
|
||
<li><strong>[Item schema correction]</strong> Fixed an incorrect use of key <code>[9]</code> (which maps to <code>itemLevel</code> in <code>QuestieDB.itemKeys</code>) for quest-source storage. The correct key is <code>[5]</code> (<code>startQuest</code>). Affects <code>CrossLinkAfterQuest</code> and <code>CrossLinkAfterItem</code>.</li>
|
||
<li><strong>[Mouseover — all NPCs now learned]</strong> Removed the <code>UnitReaction < 4</code> early-return guard that blocked learning hostile or neutral NPCs via mouseover. The existing <code>QUESTGIVER</code> NPC-flag bitmask check (<code>0x02</code>) remains as the primary filter, ensuring only NPCs with a quest-giver relationship are stored. Hostile quest objective NPCs are now captured on any hover, target, or kill and are correctly cross-linked to their quests.</li>
|
||
</ul>
|
||
|
||
<h3>TrackerUtils.lua — Zone Resolution Rewrite</h3>
|
||
<ul>
|
||
<li><strong>[GetQuestLogZoneName — canonical 3.3.5a zone lookup]</strong> Added new local function <code>GetQuestLogZoneName(questId)</code>. Implements the only fully reliable zone resolution method in 3.3.5a: iterates the quest log from index 1 to <code>GetNumQuestLogEntries()</code> to locate the target quest's log index, then walks backwards from that index until an entry where <code>isHeader=true</code> is found. That header's <code>title</code> string is the zone name (e.g. <code>"Shadowmoon Valley"</code>). <code>GetRealZoneText()</code> and <code>GetCurrentMapAreaID()</code> were previously used but are unreliable because they reflect the currently viewed map, not the quest's zone. The 3.3.5a client places zone header entries directly above their child quests in the flat quest log list — this is guaranteed by the client and is the same method Blizzard's own UI uses to render the zone groups.</li>
|
||
<li><strong>[BuildFallbackQuest — zone via log walk]</strong> Replaced the <code>GetRealZoneText()</code> call with the inline header walk. The loop that already iterates the quest log to find the fallback quest's entry now continues backwards from that same index to find the header. <code>GetAreaIdByZoneName()</code> converts the string to an area ID for <code>zoneOrSort</code>; the raw string is stored as <code>quest.zoneName</code> for display. If no header is found (e.g. "Special" category with no zone header), <code>zoneName</code> remains nil and the tracker falls back to the <code>_GetZoneName(zoneOrSort)</code> path.</li>
|
||
<li><strong>[_isLogFallback patch block — zone fix]</strong> The block that patches <code>QuestLogCache</code> fallback objects (identified by <code>_isLogFallback=true</code> and absence of an <code>IsComplete</code> method) now calls <code>GetQuestLogZoneName(capturedId)</code> immediately after patching <code>Objectives</code>, <code>SpecialObjectives</code>, and <code>ExtraObjectives</code>. If a zone name is returned, both <code>quest.zoneName</code> and <code>quest.zoneOrSort</code> are set on the object in-place. Previously this block left both values at their <code>QuestLogCache</code> defaults (<code>zoneOrSort=0</code>, <code>zoneName=nil</code>), which caused every fallback quest to group under "Unknown Zone" in the tracker regardless of where the quest was accepted.</li>
|
||
<li><strong>[Fallback cache invalidation]</strong> <code>_fallbackQuests[qid]</code> is now evicted and unconditionally rebuilt if the cached entry has no <code>zoneName</code>. This handles the race condition where <code>BuildFallbackQuest</code> was called during addon initialization before the quest log entries were populated, caching a zoneless entry that would persist for the entire session.</li>
|
||
</ul>
|
||
|
||
<h3>QuestieTracker.lua — Untrack Fix</h3>
|
||
<ul>
|
||
<li><strong>[UntrackQuestId — inverted logic fixed]</strong> <code>UntrackQuestId</code> previously set <code>AutoUntrackedQuests[questId] = nil</code> when the player untracks a quest. The tracker filter expression is <code>not Questie.db.char.AutoUntrackedQuests[questId]</code> — when the value is <code>nil</code>, <code>not nil</code> is <code>true</code>, meaning "show this quest". Clearing the entry on untrack therefore immediately re-showed the quest on the very next tracker update tick, making untacking appear completely broken. Fix: in <code>autoTrackQuests</code> mode, <code>UntrackQuestId</code> now sets <code>AutoUntrackedQuests[questId] = true</code> (evaluated as "hide"). In manual-track mode, it clears <code>TrackedQuests[questId]</code> as before, and <code>AutoUntrackedQuests</code> is cleared instead of being incorrectly toggled. The two tracking modes are now cleanly separated within the function.</li>
|
||
<li><strong>[AQW_Insert — QuestLogFrame gate removed]</strong> The condition <code>IsShiftKeyDown() and QuestLogFrame:IsShown()</code> inside <code>AQW_Insert</code> was blocking the re-tracking path (clearing <code>AutoUntrackedQuests[questId]</code>) whenever the quest log frame was not open. Since untacking fires <code>RemoveQuestWatch</code> → <code>UntrackQuestId</code> directly, this <code>AQW_Insert</code> branch was only ever reached for re-tracking — yet the gate required the quest log to be open. The gate has been removed; re-tracking now works from any UI context.</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="container">
|
||
<h2 id="v126">v1.2.6 — QuestieLearner Comprehensive Overhaul</h2>
|
||
<p><em>Rewrote QuestieLearner from scratch to fix all known data-capture deficiencies. Adds full quest field coverage, grid-based coordinate clustering, quest-giver-only mouseover filtering, async item-info retry, object loot detection, and live inject-on-import so imported data takes effect without a reload.</em></p>
|
||
|
||
<h3>QuestieLearner.lua — Full Rewrite</h3>
|
||
<ul>
|
||
<li><strong>[Quest capture completeness]</strong> <code>LearnQuest</code> now accepts a generic <code>data</code> table keyed by Questie wiki array indices rather than individual positional arguments. <code>OnQuestDetail</code> captures title, objectives text block, quest description body, and current zone as <code>zoneOrSort[8]</code>. <code>OnQuestAccepted</code> fills quest level from <code>GetQuestLogTitle</code>, per-objective text from <code>GetQuestLogLeaderBoard</code>, and required money from <code>GetQuestLogRequiredMoney</code>. <code>OnQuestComplete</code> captures finish/reward text via <code>GetRewardText</code>.</li>
|
||
<li><strong>[Mouseover filter]</strong> <code>OnMouseoverUnit</code> now only learns an NPC if its <code>UnitNPCFlags</code> bitmask includes the <code>QUESTGIVER</code> bit (<code>0x02</code>), OR if the NPC already exists in <code>QuestieDB</code> as a known quest starter/finisher. All other NPCs are silently ignored — this eliminates the flood of irrelevant NPC entries the learner previously accumulated.</li>
|
||
<li><strong>[Target changed]</strong> <code>OnTargetChanged</code> no longer calls <code>LearnNPC</code> on every target switch. It now only populates the <code>guidNpcCache</code> for kill-tracking purposes, avoiding recording non-quest NPCs.</li>
|
||
<li><strong>[Coordinate clustering — grid bucketing]</strong> Replaced the naive "within 1 unit radius" deduplication with a 2×2 grid bucket scheme (<code>COORD_GRID = 2.0</code>). A new point is inserted only when no existing point shares the same grid cell. This prevents coordinate scatter across a kill area while still preserving distinct spawn clusters. The <code>InsertIfNewBucket</code> helper is shared across NPC, Object, and all merge paths (including <code>InjectLearnedData</code> and <code>HandleNetworkData</code>).</li>
|
||
<li><strong>[Object recording]</strong> <code>OnLootOpened</code> now checks whether the loot source GUID is a <code>GameObject</code>. If so, <code>LearnObject</code> is called with the object's ID and name. <code>OnGossipShow</code> records both objects and NPCs via <code>GetIdAndTypeFromGUID</code>. <code>OnQuestDetail</code> and <code>OnQuestComplete</code> also record the interacting object when the quest giver/finisher is a <code>GameObject</code>.</li>
|
||
<li><strong>[Item loot — async GetItemInfo retry]</strong> <code>OnLootOpened</code> queues unresolved item links (where <code>GetItemInfo</code> returns nil because the item is not yet in the client cache) into <code>_Learner.pendingItemLinks</code>. A new <code>OnGetItemInfoReceived(itemId)</code> handler fires on the <code>GET_ITEM_INFO_RECEIVED</code> event, resolves queued links for that item ID, and calls <code>LearnItem</code>/<code>LearnItemDrop</code> once the data is available. This fixes silent data loss on first-encounter loots.</li>
|
||
<li><strong>[Quest giver entity type]</strong> <code>LearnQuestGiver</code> now accepts an <code>entityType</code> argument (1=NPC, 2=GameObject, 3=item) and stores starters/finishers in the correct sub-array slot matching the Questie wiki spec <code>{ [1]={npcIds}, [2]={objIds}, [3]={itemIds} }</code>.</li>
|
||
<li><strong>[Kill tracking]</strong> <code>OnCombatLogEvent</code> retains all three GUID-resolution paths (dash-split, GUID cache, hex-prefix) with a 10-minute TTL cache cleanup. Uses <code>CombatLogGetCurrentEventInfo()</code> with fallback to varargs for cross-client compatibility.</li>
|
||
<li><strong>[InjectLearnedData — grid clustering]</strong> All coordinate merge loops now use <code>InsertIfNewBucket</code> instead of the old radius check.</li>
|
||
</ul>
|
||
|
||
<h3>QuestieLearnerExport.lua — Import Live-Inject Fix</h3>
|
||
<ul>
|
||
<li><strong>[MergeImport → InjectLearnedData]</strong> After merging all four data categories, <code>MergeImport</code> immediately calls <code>QuestieLearner:InjectLearnedData()</code>. Imported data is pushed into <code>QuestieDB.*DataOverrides</code> in the same frame — override-driven map pins update without a <code>/reload</code>. A full reload is still needed to pick up newly imported quest starters/finishers for quests already in the player's quest log.</li>
|
||
</ul>
|
||
|
||
<h3>README — Import Clarification</h3>
|
||
<ul>
|
||
<li>Corrected the "no reload required" claim. The import flow now accurately describes when an immediate effect is visible versus when a <code>/reload</code> is beneficial.</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="container">
|
||
<h2 id="v125">v1.2.5 — Ebonhold & Ascension DB Plugin Load Fix</h2>
|
||
<p><em>Fixed a fatal load-time crash in all four Ebonhold DB files (and identically in the Ascension DB files) caused by calling <code>GetRealmName()</code> and <code>QuestieLoader:CreateModule()</code> at file scope — before WoW's API is fully available. Switched to plain global table population; realm-gating and injection remain safely deferred to the loader's <code>PLAYER_LOGIN</code> handler.</em></p>
|
||
|
||
<h3>Root Cause</h3>
|
||
<ul>
|
||
<li><strong>[File-scope execution]</strong> <code>EbonholdNpcDB.lua</code>, <code>EbonholdObjectDB.lua</code>, <code>EbonholdItemDB.lua</code>, and <code>EbonholdQuestDB.lua</code> each began with <code>if GetRealmName() ~= "Rogue-Lite (Live)" then return end</code> followed immediately by <code>QuestieLoader:CreateModule("EbonholdDB")</code>. Both calls execute at file-load time (during <code>LoadAddOn()</code>), before <code>PLAYER_LOGIN</code> has fired and before <code>QuestieLoader</code> is guaranteed to be populated. This produced <code>attempt to index global 'QuestieLoader' (a nil value)</code> on every load.</li>
|
||
<li><strong>[Same issue in Ascension DB]</strong> All four <code>Bronzebeard/AscensionXxxDB.lua</code> files had the same pattern with a different realm guard. Same crash, same fix applied.</li>
|
||
</ul>
|
||
|
||
<h3>Questie-X-EbonholdDB</h3>
|
||
<ul>
|
||
<li><strong>[Ebonhold/EbonholdNpcDB.lua]</strong> Removed file-level realm guard and <code>QuestieLoader:CreateModule</code> call. Replaced with <code>_G.EbonholdDB = _G.EbonholdDB or {}</code> and a local alias. Data is now populated unconditionally into the global at load time.</li>
|
||
<li><strong>[Ebonhold/EbonholdObjectDB.lua]</strong> Same fix.</li>
|
||
<li><strong>[Ebonhold/EbonholdItemDB.lua]</strong> Same fix.</li>
|
||
<li><strong>[Ebonhold/EbonholdQuestDB.lua]</strong> Same fix.</li>
|
||
<li><strong>[EbonholdLoader.lua]</strong> Replaced <code>QuestieLoader:ImportModule("EbonholdDB")</code> with <code>_G.EbonholdDB or {}</code>. The loader's existing <code>PLAYER_LOGIN</code> handler with realm check remains intact as the sole gate for injection into Questie-X.</li>
|
||
</ul>
|
||
|
||
<h3>Questie-X-AscensionDB</h3>
|
||
<ul>
|
||
<li><strong>[Bronzebeard/AscensionNpcDB.lua]</strong> Removed file-level realm guard and <code>QuestieLoader:CreateModule</code> call. Replaced with <code>_G.AscensionDB = _G.AscensionDB or {}</code>.</li>
|
||
<li><strong>[Bronzebeard/AscensionObjectDB.lua]</strong> Same fix.</li>
|
||
<li><strong>[Bronzebeard/AscensionItemDB.lua]</strong> Same fix.</li>
|
||
<li><strong>[Bronzebeard/AscensionQuestDB.lua]</strong> Same fix.</li>
|
||
<li><strong>[AscensionLoader.lua]</strong> Replaced <code>QuestieLoader:ImportModule("AscensionDB")</code> with <code>_G.AscensionDB or {}</code>.</li>
|
||
<li><strong>[Questie-X-AscensionDB.toc]</strong> TOC title corrected from <code>Questie-Ascension</code> to <code>Questie-X-AscensionDB</code> to match the folder name and plugin naming convention.</li>
|
||
</ul>
|
||
|
||
<h3>XXH_Lua_Lib Universal Compatibility Fix</h3>
|
||
<ul>
|
||
<li><strong>[Libs/XXH_Lua_Lib/XXH_Lua_Lib.lua]</strong> All string-length calls were incorrectly using <code>table.getn(str)</code>, which expects a table — passing a string (e.g. a player name like <code>"MooeshaLC@Asc.BB25"</code>) caused a crash: <code>bad argument #1 to 'getn' (table expected, got string)</code>. Fixed by replacing all string-length calls with <code>string.len(str)</code> (universal across Lua 5.0 and 5.1). Table-length calls restored to <code>table.getn(t)</code> for the same universal coverage — the <code>#</code> length operator is only available in Lua 5.1+ and would break on WoW 1.12 vanilla clients.</li>
|
||
</ul>
|
||
|
||
<h3>Repository & Releases</h3>
|
||
<ul>
|
||
<li>Published initial GitHub releases for all four database plugins: <a href="https://github.com/Xurkon/Questie-X-WotLKDB" style="color: var(--accent-blue)">Questie-X-WotLKDB</a>, <a href="https://github.com/Xurkon/Questie-X-TBCDB" style="color: var(--accent-blue)">Questie-X-TBCDB</a>, <a href="https://github.com/Xurkon/Questie-X-EbonholdDB" style="color: var(--accent-blue)">Questie-X-EbonholdDB</a>, <a href="https://github.com/Xurkon/Questie-X-AscensionDB" style="color: var(--accent-blue)">Questie-X-AscensionDB</a>.</li>
|
||
<li>Added <code>.gitattributes</code> to all five repos with <code>export-ignore</code> for dev-only files (<code>.gitattributes</code>, <code>.gitignore</code>, <code>Tools/</code>, <code>docs/</code>, <code>.git_disabled/</code>). Release archives are now generated from tags — named <code>RepoName-vX.Y.Z.zip</code> rather than <code>RepoName-main.zip</code>.</li>
|
||
<li>README plugin table updated to link all four available repos.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v124">v1.2.4 — Retail/SoD Corrections Removed</h2>
|
||
<p><em>Deleted all Season of Discovery, Season of Mastery, and Hardcore correction files. These were retail-specific and never referenced by the TOC. Cleaned up all dead imports, constants, and code branches they left behind in <code>QuestieCorrections.lua</code>.</em></p>
|
||
|
||
<h3>Files Deleted</h3>
|
||
<ul>
|
||
<li><strong><code>Database/Corrections/SeasonOfDiscovery.lua</code></strong> — SoD base quest/NPC/object/item overrides</li>
|
||
<li><strong><code>Database/Corrections/sodQuestFixes.lua</code></strong> — SoD quest corrections</li>
|
||
<li><strong><code>Database/Corrections/sodNPCFixes.lua</code></strong> — SoD NPC corrections</li>
|
||
<li><strong><code>Database/Corrections/sodItemFixes.lua</code></strong> — SoD item corrections</li>
|
||
<li><strong><code>Database/Corrections/sodObjectFixes.lua</code></strong> — SoD object corrections</li>
|
||
<li><strong><code>Database/Corrections/Automatic/sodBaseQuests.lua</code></strong> — SoD auto-generated base quests</li>
|
||
<li><strong><code>Database/Corrections/Automatic/sodBaseNPCs.lua</code></strong> — SoD auto-generated base NPCs</li>
|
||
<li><strong><code>Database/Corrections/Automatic/sodBaseItems.lua</code></strong> — SoD auto-generated base items</li>
|
||
<li><strong><code>Database/Corrections/Automatic/sodBaseObjects.lua</code></strong> — SoD auto-generated base objects</li>
|
||
<li><strong><code>Database/Corrections/HardcoreBlacklist.lua</code></strong> — Hardcore mode quest blacklist</li>
|
||
<li><strong><code>Database/Corrections/SoMPhases.lua</code></strong> — Season of Mastery phase data (was already commented out in TOC)</li>
|
||
</ul>
|
||
|
||
<h3>QuestieCorrections.lua Cleanup</h3>
|
||
<ul>
|
||
<li><strong>Imports removed:</strong> <code>HardcoreBlacklist</code> and <code>SeasonOfDiscovery</code> <code>ImportModule</code> calls deleted.</li>
|
||
<li><strong>Constants removed:</strong> <code>SOD_ONLY = 5</code> and <code>HIDE_SOD = 6</code> deleted from the expansion filter enum. Remaining constants (<code>TBC_ONLY</code>, <code>CLASSIC_ONLY</code>, <code>WOTLK_ONLY</code>, <code>TBC_AND_WOTLK</code>, <code>CLASSIC_AND_TBC</code>) are unchanged.</li>
|
||
<li><strong><code>filterExpansion</code>:</strong> Removed the <code>isSoD</code> local and the two <code>SOD_ONLY</code> / <code>HIDE_SOD</code> branches.</li>
|
||
<li><strong><code>MinimalInit</code>:</strong> Removed the <code>if Questie.IsSoD then addOverride(...SeasonOfDiscovery...) end</code> block and the <code>if Questie.IsHardcore then HardcoreBlacklist:Load() end</code> block.</li>
|
||
<li><strong><code>Initialize</code>:</strong> Removed the 8-call <code>if Questie.IsSoD then SeasonOfDiscovery:LoadBase*/Load*() end</code> block covering quest/NPC/item/object base data and fixes.</li>
|
||
<li><strong>TOC:</strong> Removed the commented-out <code>#Database\Corrections\SoMPhases.lua</code> line.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v123">v1.2.3 — Diagnostics Refactor & Monolithic DB Removal</h2>
|
||
<p><em>Moved all DB init diagnostics out of chat and into the Develop debug level. Replaced hardcoded quest-ID spot-checks with generic per-table stats. Removed the stale monolithic database folders fully superseded by the DB plugin architecture (~30 MB removed).</em></p>
|
||
|
||
<h3>DB Init Diagnostics — DEVELOP Level</h3>
|
||
<ul>
|
||
<li><strong>[QuestieInit — <code>_dbStats</code> helper]</strong> Added a local <code>_dbStats(t)</code> function returning <code>count=N minID=X maxID=Y</code> for any table. Used at every checkpoint so diagnostic output is meaningful for any server's dataset without hardcoding expansion-specific IDs.</li>
|
||
<li><strong>[QuestieInit — <code>_dbDiag</code> removed]</strong> Eliminated the <code>local _dbDiag = {}</code> accumulator and the deferred <code>C_Timer.After(6, ...)</code> print block. Diagnostics are now emitted inline as <code>Questie:Debug(Questie.DEBUG_DEVELOP, "[DBDiag] ...")</code> calls at the exact point each stage completes — visible in real time when Develop logging is enabled, not as a delayed flood 6 seconds post-load.</li>
|
||
<li><strong>[QuestieInit:LoadBaseDB]</strong> Pull result line converted to <code>DEBUG_DEVELOP</code>.</li>
|
||
<li><strong>[QuestieInit:loadFullDatabase]</strong> Four diagnostic checkpoints converted to <code>DEBUG_DEVELOP</code> with generic <code>_dbStats</code> output: After LoadBaseDB, After Corrections, Before Compile, After Compile.</li>
|
||
<li><strong>[QuestieInit:LoadDatabase — error paths]</strong> <code>loadstring</code> parse errors and <code>pcall</code> execution errors converted to <code>DEBUG_DEVELOP</code>.</li>
|
||
<li><strong>[QuestieInit.Stages[1] — cached path]</strong> <code>DB was CACHED (no recompile)</code> line converted to <code>DEBUG_DEVELOP</code>.</li>
|
||
</ul>
|
||
|
||
<h3>DB Plugin — Loader.lua Premature Count Check Removed</h3>
|
||
<ul>
|
||
<li><strong>[Questie-X-WotLKDB/Loader.lua]</strong> Removed the <code>countTable</code> / quest+npc+obj+item count block and the <code>DEBUG_CRITICAL</code> "questData is empty" warning that fired at <code>PLAYER_LOGIN</code>. This check always reported zero counts because it ran before <code>QuestieInit</code>'s loading coroutine had started. Loader.lua is now a minimal registration stub.</li>
|
||
</ul>
|
||
|
||
<h3>Monolithic Database Folders Removed</h3>
|
||
<ul>
|
||
<li><strong>[Database/Classic/]</strong> Deleted <code>classicQuestDB.lua</code> (1.0 MB), <code>classicNpcDB.lua</code> (2.0 MB), <code>classicObjectDB.lua</code> (1.0 MB), <code>classicItemDB.lua</code> (2.1 MB). Never listed in <code>Questie-X.toc</code>. Classic data is now provided exclusively by the ClassicDB plugin.</li>
|
||
<li><strong>[Database/TBC/]</strong> Deleted <code>tbcQuestDB.lua</code> (1.6 MB), <code>tbcNpcDB.lua</code> (3.5 MB), <code>tbcObjectDB.lua</code> (1.6 MB), <code>tbcItemDB.lua</code> (3.3 MB). TBC data is now provided exclusively by the TBCDB plugin.</li>
|
||
<li><strong>[Database/Wotlk/]</strong> Deleted <code>wotlkQuestDB.lua</code> (2.3 MB), <code>wotlkNpcDB.lua</code> (5.2 MB), <code>wotlkObjectDB.lua</code> (2.0 MB), <code>wotlkItemDB.lua</code> (4.4 MB). WotLK data is now provided exclusively by the WotLKDB plugin. <strong>Combined removal: ~30 MB of dead weight from the core repository.</strong></li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v122">v1.2.2 — DB Plugin Pull Architecture & Compiler Hardening</h2>
|
||
<p><em>Overhauled the DB plugin loading pipeline from a fragile push/bridge pattern to a direct pull at init time. Fixed a long-standing compiler bug that silently dropped <code>extraobjective</code> condition data. Removed all <code>DevTools_Dump</code> calls that were printing raw Lua table syntax to chat during validation.</em></p>
|
||
|
||
<h3>DB Plugin Architecture — Pull Pattern</h3>
|
||
<ul>
|
||
<li><strong>[QuestieInit:LoadBaseDB]</strong> Replaced the broken <code>QuestieX_CoreDB</code> bridge mechanism with a direct pull of DB plugin globals at init time. <code>LoadBaseDB()</code> now checks for <code>QuestieX_WotLKDB_quest</code>, <code>QuestieX_WotLKDB_npc</code>, <code>QuestieX_WotLKDB_object</code>, and <code>QuestieX_WotLKDB_item</code> globals and assigns them directly to <code>QuestieDB.*Data</code>. Globals are cleared (<code>= nil</code>) after transfer to free memory. This runs inside Questie-X's own init coroutine at a known point in the load sequence, with no dependency on cross-addon module references.</li>
|
||
<li><strong>[QuestieDB.lua]</strong> Removed <code>_G.QuestieX_CoreDB = QuestieDB</code> export. The CoreDB bridge global is no longer needed and was never reliably accessible from DB plugin Loader.lua files due to module-registry timing.</li>
|
||
</ul>
|
||
|
||
<h3>DB Plugin — Loader.lua Simplification</h3>
|
||
<ul>
|
||
<li><strong>[Questie-X-WotLKDB/Loader.lua]</strong> Stripped the entire data-transfer block (the <code>if not QuestieX_CoreDB then return end</code> guard and subsequent <code>QuestieX_CoreDB.*Data = ...</code> assignments). The file is now a <code>PLAYER_LOGIN</code> handler that registers the plugin with <code>QuestiePluginAPI</code>, logs absorbed table sizes, and emits a <code>DEBUG_CRITICAL</code> warning if <code>questData</code> is still empty after init.</li>
|
||
</ul>
|
||
|
||
<h3>Compiler — extraobjectives Conditions Field</h3>
|
||
<ul>
|
||
<li><strong>[compiler.lua — writer]</strong> Added serialization of <code>data[6]</code> (conditions table). After writing the 5 existing fields per entry, the writer now writes a <code>WriteByte(n)</code> count followed by <code>WriteShortString(key)</code> + <code>WriteInt24(value)</code> for each condition entry. If <code>data[6]</code> is nil, writes <code>0</code>.</li>
|
||
<li><strong>[compiler.lua — reader]</strong> Added deserialization of the conditions field. Reads a <code>ReadByte()</code> condition count; if non-zero, reconstructs the conditions table as <code>{[key]=value}</code> and assigns it to <code>entry[6]</code>.</li>
|
||
<li><strong>[compiler.lua — skipper]</strong> Updated to skip condition bytes: reads condition count, then skips a <code>ShortString</code> + <code>Int24</code> per condition.</li>
|
||
<li><strong>[Root cause]</strong> <code>QuestieDB.lua:1443</code> reads <code>HideCondition = o[6]</code> from each extraobjective. Before this fix, compiled data always produced <code>o[6] = nil</code>, so <code>ShouldHideObjective()</code> never activated. The <code>hideIfQuestActive</code> / <code>hideIfQuestComplete</code> conditions were silently ignored post-compilation. Validation also flagged the mismatch every load, which triggered <code>DevTools_Dump</code> to flood chat with raw Lua table syntax.</li>
|
||
</ul>
|
||
|
||
<h3>Compiler — DevTools_Dump Removal</h3>
|
||
<ul>
|
||
<li><strong>[compiler.lua — ValidateNPCs / ValidateObjects / ValidateItems / ValidateQuests]</strong> Removed all four <code>DevTools_Dump({["Compiled Table:"]=a, ["Base Table:"]=b})</code> calls from table-mismatch branches. These calls serialized full Lua tables to the chat frame as raw source code, appearing to users as a syntax error or data corruption. The preceding <code>Questie:Warning(...)</code> line already captures the mismatch identity. <code>DevTools_Dump</code> is a retail WoW debugging API unavailable or unreliable on private/custom servers and should never be called in production validation paths.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v117">v1.1.7 – v1.2.1 — DB Loading Diagnostics & Fallback Tracker</h2>
|
||
<p><em>Ongoing stability pass. Hardened the entire database loading pipeline, wired up the live quest-log fallback for quests missing from the DB, and fixed a chain of nil-guard crashes across corrections, map, and tracker modules.</em></p>
|
||
|
||
<h3>Database Loading</h3>
|
||
<ul>
|
||
<li><strong>[LoadDatabase]</strong> Replaced bare <code>loadstring()</code> / <code>fn()</code> calls with proper error capture (<code>local fn, err = loadstring(...)</code> + <code>pcall(fn)</code>). Errors now print to chat with the failing key and string length instead of silently falling back to <code>{}</code>.</li>
|
||
<li><strong>[Compiler]</strong> Fixed <code>hasData</code> guard in <code>QuestieDBCompiler:Compile()</code> — now accepts <code>type == "table"</code> in addition to <code>"string"</code>, preventing the compiler from silently aborting when <code>LoadDatabase</code> has already decoded the string to a table before compilation.</li>
|
||
<li><strong>[DB Architecture]</strong> Identified and documented that loading multiple DB plugins simultaneously (e.g. WotLKDB + ClassicDB) causes <code>questData</code> overwrites. On WotLK servers only <code>Questie-X-WotLKDB</code> should be enabled alongside the server-specific plugin.</li>
|
||
</ul>
|
||
|
||
<h3>Live Fallback for Missing Quests</h3>
|
||
<ul>
|
||
<li><strong>[QuestieDB.GetQuest]</strong> When <code>rawdata</code> is nil, a minimal quest object is now built from <code>QuestLogCache</code> instead of returning nil. The fallback populates <code>name</code>, <code>level</code>, <code>isComplete</code>, and an empty <code>Objectives</code> table with <code>_isLogFallback = true</code>.</li>
|
||
<li><strong>[QuestieQuest.PopulateQuestLogInfo]</strong> Fallback quests now seed their <code>Objectives</code> table from <code>QuestLogCache.GetQuestObjectives</code> on first call, then call <code>obj:Update()</code> on each to refresh progress from the live quest log.</li>
|
||
<li><strong>[QuestieQuest.UpdateObjectiveNotes]</strong> Fallback quests now early-return to skip the static DB spawn-list path (<code>objectiveSpawnListCallTable</code>), preventing "Corrupted objective data" errors caused by nil NPC IDs.</li>
|
||
</ul>
|
||
|
||
<h3>Crash Fixes</h3>
|
||
<ul>
|
||
<li><strong>[QuestieLib.GetQuestString]</strong> Guard against nil <code>name</code> — returns quest ID string as fallback.</li>
|
||
<li><strong>[QuestieDB spawn loop]</strong> Nil-guard on <code>objectData[id]</code> before clearing spawn keys in prune loop (<code>attempt to index nil</code> at QuestieDB:1715).</li>
|
||
<li><strong>[QuestieDB.GetSpawnList]</strong> Wrapped <code>objectiveSpawnListCallTable</code> result in nil-guard before iterating — prevents <code>pairs(nil)</code> when a referenced NPC/object is missing from the loaded DB.</li>
|
||
<li><strong>[QuestieQuestPrivates killcredit]</strong> <code>monster(killCreditNpcId)</code> result nil-guarded before indexing — prevents crash for kill-credit NPCs absent from <code>npcData</code>.</li>
|
||
<li><strong>[Townsfolk]</strong> <code>flags</code> nil-guard added before <code>bitband(flags, VENDOR)</code> call.</li>
|
||
<li><strong>[QuestieQuest.UpdateObjectiveNotes]</strong> <code>quest.SpecialObjectives</code> nil-guard before <code>next()</code> call.</li>
|
||
<li><strong>[QuestieQuest.PopulateQuestLogInfo]</strong> <code>quest.SpecialObjectives</code> nil-guard before <code>next()</code> call.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v116">v1.1.6 — Minimap Icon & P2 Stability</h2>
|
||
<p><em>Minimap button overhaul and second pass of P2 bug fixes.</em></p>
|
||
|
||
<h3>Minimap</h3>
|
||
<ul>
|
||
<li><strong>[MinimapIcon]</strong> Replaced default minimap icon with custom <code>mmapIcon.tga</code>. Applied <code>SetMask</code> for circular clip on WotLK+ clients with <code>SetTexCoord</code> fallback for 1.12 vanilla clients.</li>
|
||
</ul>
|
||
|
||
<h3>Bug Fixes</h3>
|
||
<ul>
|
||
<li><strong>[QuestieServer]</strong> Restored plugin status UI, <code>C_QuestLog</code>/<code>C_Map</code> shims, and <code>QuestieServer</code> init sequence.</li>
|
||
<li><strong>[QuestieLoader]</strong> Corrected <code>select()</code> polyfill to not use <code>arg</code> table.</li>
|
||
<li><strong>[TOC]</strong> Added XXH load to TBC toc and guarded <code>plugin.stats</code> nil access.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v115">v1.1.5 — QuestieLearner Expansion & Database Options</h2>
|
||
<p><em>Major expansion of the data-learning system and a new Database options tab.</em></p>
|
||
|
||
<h3>QuestieLearner</h3>
|
||
<ul>
|
||
<li><strong>[QuestieLearner]</strong> Expanded hook coverage: quest accept, objective kill, object interaction, and item loot all feed learned data back to the appropriate DB table.</li>
|
||
<li><strong>[QuestieLearnerComms]</strong> Broadcast/receive learned entries to nearby Questie-X users via addon messages.</li>
|
||
<li><strong>[Custom Server Detection]</strong> Learned data for unrecognised quest IDs is stored under a per-realm key in <code>QuestieLearnerDB</code> to separate retail/private/custom content.</li>
|
||
<li><strong>[DEVELOP logging]</strong> Debug messages emitted on every successful learn and every failed-to-learn event.</li>
|
||
</ul>
|
||
|
||
<h3>Options — Database Tab</h3>
|
||
<ul>
|
||
<li><strong>[QuestieOptionsDatabase]</strong> New "Database" tab with Import / Export (LibDeflate base64 encoded strings) and Cleanup (prune stale learned entries) functionality.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v114">v1.1.4 — Questie-X: Plugin Architecture & Maintenance Update</h2>
|
||
<p><em>This release marks the official rebranding from <strong>Questie-335</strong> / <strong>PE-Questie</strong> to <strong>Questie-X</strong> and introduces the new plugin architecture. Additionally, this version includes significant UI enhancements, core compatibility refinements for legacy clients, and critical database corrections.</em></p>
|
||
|
||
<h3>Architecture Changes</h3>
|
||
<ul>
|
||
<li><strong>[Repo]</strong> Repository renamed and re-homed to <code>Xurkon/Questie-X</code>. Remote updated from <code>PE-Questie</code> to <code>Questie-X</code>.</li>
|
||
<li><strong>[Plugin API]</strong> Introduced <code>QuestiePluginAPI</code> (<code>Modules/Libs/QuestiePluginAPI.lua</code>). Plugins register themselves and inject quest, NPC, object, item, and zone data without modifying core files.</li>
|
||
<li><strong>[Server Detection]</strong> Added <code>QuestieServer</code> module (<code>Modules/QuestieServer.lua</code>) for improved runtime server environment detection.</li>
|
||
<li><strong>[Network]</strong> Added <code>QuestieLearnerComms</code> module (<code>Modules/Network/QuestieLearnerComms.lua</code>) for cross-client quest data sharing.</li>
|
||
<li><strong>[Database]</strong> Removed embedded <code>Database/Ascension/</code> and <code>Database/Ebonhold/</code> folders. All custom server data is now distributed via separate plugin addons.</li>
|
||
</ul>
|
||
|
||
<h3>UI Enhancements</h3>
|
||
<ul>
|
||
<li><strong>[Options]</strong> Resizable Options window! The Questie options UI can now be resized with corner drag functionality. Size and position persist between sessions.</li>
|
||
<li><strong>[Options]</strong> New <strong>Credits Tab</strong>! A dedicated tab in the options menu to acknowledge contributors and community partners.</li>
|
||
<li><strong>[Tutorial]</strong> Improved tutorial flows for objective type selection.</li>
|
||
</ul>
|
||
|
||
<h3>Core & Compatibility</h3>
|
||
<ul>
|
||
<li><strong>[Lua 5.0]</strong> Globally polyfilled <code>string.match</code> and <code>string.gmatch</code> using <code>string.find</code> and <code>string.gfind</code> to ensure universal compatibility with legacy WoW clients (e.g., Turtle WoW).</li>
|
||
<li><strong>[AceTimer]</strong> Patched embedded <code>AceTimer-3.0</code> instances in ElvUI and OG-RaidHelper to resolve <code>math.mod</code> errors on Lua 5.0 clients.</li>
|
||
<li><strong>[Colors]</strong> Updated <code>CreateColor</code> polyfill with <code>SetRGB</code>, <code>SetRGBA</code>, <code>SetColor</code>, and <code>GetColor</code> methods.</li>
|
||
<li><strong>[Comm]</strong> Improved cross-client data sharing stability.</li>
|
||
</ul>
|
||
|
||
<h3>Map & Tooltips</h3>
|
||
<ul>
|
||
<li><strong>[Tooltips]</strong> NPC names and objective text now populate reliably on map pins and world unit tooltips.</li>
|
||
<li><strong>[Tooltips]</strong> Resolved <code>[QuestieTooltips:GetTooltip] m_20509</code> debug log spam.</li>
|
||
</ul>
|
||
|
||
<h3>Quest Data</h3>
|
||
<ul>
|
||
<li><strong>[Database]</strong> Scraped and injected missing spawn coordinates for Bonechewer Mutant, Raider, Evoker, and Scavenger (NPC IDs 16876, 16925, 19701, 18952) from Wowhead.</li>
|
||
<li><strong>[Quest 10482]</strong> Correctly mapped Bonechewer NPCs to quest objectives in both WotLK and TBC database correction files.</li>
|
||
</ul>
|
||
|
||
<h3>New Plugins</h3>
|
||
<ul>
|
||
<li><strong>Questie-Ascension</strong> — Project Ascension server database.</li>
|
||
<li><strong>Questie-Ebonhold</strong> — Ebonhold server database.</li>
|
||
</ul>
|
||
|
||
<h3>TOC / Addon Identity</h3>
|
||
<ul>
|
||
<li><strong>[TOC]</strong> Core addon <code>.toc</code> files updated to <code>Questie-X</code> title and <code>v1.1.4</code> version.</li>
|
||
<li><strong>[Libs]</strong> Added <code>LibDeflate</code>, <code>XXH_Lua_Lib</code>, <code>LibDBIcon-1.0</code>, and <code>LibDataBroker-1.1</code> to the Libs directory.</li>
|
||
</ul>
|
||
|
||
<h3>Bug Fixes</h3>
|
||
<ul>
|
||
<li><strong>[QuestieDB]</strong> Overhauled <code>QuestieDB.IsComplete</code> to accurately verify all objectives are finished using <code>numFulfilled == numRequired</code> instead of the unreliable server-side <code>finished</code> flag.</li>
|
||
<li><strong>[QuestieQuest]</strong> Implemented <code>HideCondition</code> mechanism for objectives, allowing specific spawns to be hidden based on quest log status (<code>hideIfQuestActive</code> / <code>hideIfQuestComplete</code>).</li>
|
||
<li><strong>[Cache]</strong> Demoted Cache Validation "0/15 Error" to Debug level to reduce user confusion during login.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v992">v9.9.2 — Final Pre-Refactor Release</h2>
|
||
<p><em>⚠️ This is the final stable release before a major architectural refactoring. All active features and quest data from previous releases are preserved.</em></p>
|
||
|
||
<h3>Fixes</h3>
|
||
<ul>
|
||
<li><strong>[Map]</strong> Resolved an issue where NPC names and objective text were inconsistently missing from map tooltips.</li>
|
||
</ul>
|
||
|
||
<h3>New Ebonhold Quests</h3>
|
||
<ul>
|
||
<li><strong>Western Plaguelands Trophy</strong> (ID 50187) - Kill 1 Rare in Western Plaguelands.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v991">v9.9.1</h2>
|
||
<h3>New Ebonhold Quests</h3>
|
||
<ul>
|
||
<li><strong>Brood of the Black Flight</strong> (ID 50057) - Kill 30 Dragonkin in Burning Steppes.</li>
|
||
</ul>
|
||
|
||
<hr>
|
||
|
||
<h2 id="v990">v9.9.0</h2>
|
||
<h3>New Ebonhold Quests</h3>
|
||
<ul>
|
||
<li><strong>Azeroth</strong>: Southern Jungle (Complete 6 quests in Stranglethorn Vale).</li>
|
||
<li><strong>Kalimdor</strong>: Sandstone Giants (Kill Sandstone Giants in Tanaris). Felwood Restoration
|
||
(Complete 6 quests in Felwood).</li>
|
||
</ul>
|
||
<h3>Fixes</h3>
|
||
<ul>
|
||
<li><strong>[Quest]</strong> Fixed QuestieDB initialization error caused by missing table depth for custom
|
||
creature objectives in EbonholdQuestDB.</li>
|
||
<li><strong>[System]</strong> Adjusted Questie:Error output logic so that critical addon-breaking errors
|
||
always print regardless of the Enable Debug-PRINT setting.</li>
|
||
<li><strong>[Map]</strong> Fixed missing map pins for the "Sandstone Giants" quest by switching from
|
||
<code>creatureObjective</code> to <code>killCreditObjective</code>, allowing Questie to correctly
|
||
resolve Dune Smasher spawn locations from the NPC database.
|
||
</li>
|
||
<li><strong>[Tracking]</strong> Fixed collection quest counters showing stale counts when the Ebonhold scav
|
||
bot loots items — implemented a 3-stage <code>BAG_UPDATE_DELAYED</code> strategy: immediate scan, 0.3s
|
||
debounce scan, and a 2s follow-up scan to allow the server's quest-objective cache to flush batch loot
|
||
counts.</li>
|
||
</ul>
|
||
<h2 id="v975">v9.7.5</h2>
|
||
<h3>Fixes</h3>
|
||
<ul>
|
||
<li><strong>[Quest]</strong> Fixed an issue where re-accepted quests (e.g., repeatable custom quests) would
|
||
not show objective pins/icons on the map.</li>
|
||
</ul>
|
||
<h3>New Quests</h3>
|
||
<ul>
|
||
<li><strong>[Database]</strong> Added <strong>Storm Peak Orders</strong> (ID 50150) - <em>The Storm
|
||
Peaks</em></li>
|
||
<ul>
|
||
<li>Objective: Complete any 6 quests in The Storm Peaks.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Wild Basin</strong> (ID 50094) - <em>Sholazar Basin</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 29 Beast NPC types with full spawn coordinates.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>NPCs: King Krush, Shardhorn Rhino, Aotona, Pitch, Serfex the Reaver, Dreadsaber, Hardknuckle
|
||
Matriarch, Shango, Venomtip, Bushwhacker, Hardknuckle Charger, Ravenous Mangal Crocolisk, Farunn,
|
||
Zeptek the Destroyer, Goretalon Matriarch, Sapphire Hive Wasp, Emperor Cobra, Sapphire Hive Drone,
|
||
Shattertusk Bull, Siltslither Eel, Spirit of Atha, Stranded Thresher, Mangal Crocolisk, Spirit of
|
||
Koosu, Longneck Grazer, Goretalon Roc, Sapphire Hive Queen, Spirit of Ha-Khalan, Bittertide Hydra
|
||
</li>
|
||
</ul>
|
||
</ul>
|
||
<h2 id="v974">v9.7.4</h2>
|
||
<h3>Fixes</h3>
|
||
<ul>
|
||
<li><strong>[Tooltips]</strong> Fixed "attempt to concatenate local 'name' (a nil value)" error when quest
|
||
starters/finishers have missing names in the database.</li>
|
||
<li><strong>[Database]</strong> Added missing spawn coordinates for Quest 50031 "Stormbound" elementals in
|
||
Storm Peaks (zone 67).</li>
|
||
<li><strong>[Database]</strong> Fixed "Unknown Zone" issue for custom quests by correcting Zone ID index
|
||
usage (swapped `[6]` RequiredRaces for `[17]` ZoneID).</li>
|
||
<li><strong>[Database]</strong> Corrected Dragonblight Zone ID in custom quest definitions.</li>
|
||
</ul>
|
||
<h3>New Quests</h3>
|
||
<ul>
|
||
<li><strong>[Database]</strong> Added <strong>Morogh Missions</strong> (ID 50098) - <em>Dun Morogh</em></li>
|
||
<ul>
|
||
<li>Objective: Complete any 6 quests in Dun Morogh. Auto-completes upon reaching the objective.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Azuremyst Aid</strong> (ID 50100) - <em>Azuremyst Isle</em>
|
||
</li>
|
||
<ul>
|
||
<li>Objective: Complete any 6 quests in Azuremyst Isle. Auto-completes upon reaching the objective.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Stormforged Scales</strong> (ID 50066) - <em>The Storm
|
||
Peaks</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 30 Dragonkin. Includes 8 Dragonkin NPC types with full spawn coordinates.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Peak Predators</strong> (ID 50095) - <em>The Storm Peaks</em>
|
||
</li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 24 Beast NPC types with full spawn coordinates.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Peak Predators</strong> (ID 50096) - <em>Icecrown</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 12 Beast NPC types with full spawn coordinates.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Icecrown Advance</strong> (ID 50151) - <em>Icecrown</em></li>
|
||
<ul>
|
||
<li>Objective: Complete any 6 quests in Icecrown. Auto-completes upon reaching the objective.</li>
|
||
</ul>
|
||
<li><strong>[Database]</strong> Added <strong>Storm Peaks Trophy</strong> (ID 50205) - <em>The Storm
|
||
Peaks</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 1 Rare in The Storm Peaks. Includes 4 Rare NPC types (Skoll, Time-Lost Proto-Drake,
|
||
Vyragosa, Dirkee) with full spawn coordinates.</li>
|
||
</ul>
|
||
</ul>
|
||
<h2 id="v973">v9.7.3</h2>
|
||
<h3>New Features</h3>
|
||
<ul>
|
||
<li><strong>[Database]</strong> Implemented <strong>Ebonhold Database Module</strong>.</li>
|
||
<ul>
|
||
<li>Created dedicated `Database/Ebonhold/` structure for custom server data.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Added `EbonholdLoader` to inject custom Quests, NPCs, Objects, and Items as overrides.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>**Note:** This structure preserves custom data during upstream Questie updates.</li>
|
||
</ul>
|
||
<li><strong>[Objectives]</strong> Implemented <strong>Automated Text Retrieval</strong>.</li>
|
||
<ul>
|
||
<li>Questie now attempts to fetch quest text from the server at runtime for custom quests that are
|
||
missing from the database.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Added "Objectives Board" (ID 600600) as a global quest starter.</li>
|
||
</ul>
|
||
</ul>
|
||
<h3>Quests (Custom Content)</h3>
|
||
<ul>
|
||
<li><strong>[New]</strong> Added <strong>Heart of the Dragonflights</strong> (ID 50064) -
|
||
<em>Dragonblight</em>
|
||
</li>
|
||
<ul>
|
||
<li>Objective: Kill 30 Dragonkin. Includes 49 Dragonkin NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Skies of Blade's Edge</strong> (ID 50060) - <em>Blade's Edge
|
||
Mountains</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Dragonkin. Includes 17 Dragonkin NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Shadowed Beasts</strong> (ID 50087) - <em>Shadowmoon Valley</em>
|
||
</li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 25 Beast NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Forest Stalkers</strong> (ID 50083) - <em>Terokkar Forest</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 53 Beast NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Savage Heights</strong> (ID 50085) - <em>Blade's Edge
|
||
Mountains</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 47 Beast NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Unstable Fauna</strong> (ID 50086) - <em>Netherstorm</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 75 Beasts. Includes 18 Beast NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Elemental Balance</strong> (ID 50026) - <em>Nagrand</em></li>
|
||
<ul>
|
||
<li>Objective: Kill 30 Elementals. Includes 12 Elemental NPC types.</li>
|
||
</ul>
|
||
<li><strong>[New]</strong> Added <strong>Redridge Trophy</strong> (ID 50160) and <strong>Zangarmarsh
|
||
Trophy</strong> (ID 50192).</li>
|
||
</ul>
|
||
<h3>New Ascension Quests</h3>
|
||
<ul>
|
||
<li><strong>Westfall</strong>: Agria's Medicine, Seven Years of Bad Luck, Worm-Eaten Apple, Goldshire's
|
||
Generosity, Bookworm, Knowledge Corrupts, The Ruins of Northshire, Accursed Sisterhood, Words That
|
||
Shepherd Madness, Oracular Idol, A Betrayal Within, The Maid I Left Behind, The Saddest Among Us, The
|
||
Threat Swept Downstream, Stay a While, Defias Disruption.</li>
|
||
<li><strong>Dun Morogh</strong>: A Small Mistake, We Found Her!, The Scout's Favor, Old Mirsinth, Smoke on
|
||
the Wind, A Promising Path, A Fitting Disguise, His Radiant Majesty, Deciphering Radiation, Soaking the
|
||
Masses, Sever the Right Hand, A Growing Business, Thunderbrew's Hop, Stay a While, Live-Fire Demo, Bots
|
||
on Strike, A Brother's Betrayal, The True Story, Timber for the Coldhewn, Icehide the Unbroken.</li>
|
||
<li><strong>Teldrassil</strong>: The Carrion Road, The Sister Who Never Returned, Finding the Good Meat,
|
||
Transsubstantiating the Flesh, Communion Banquet, A Trail of Petals, Restless entrails, A Dark Warning,
|
||
The Aid of Theren-Dion, No Place for Scavengers, Termites in Teldrassil, Stay a While, Elydna's
|
||
Heirloom.</li>
|
||
<li><strong>Durotar</strong>: To Find a Cure, A Dangerous Sample, Knowledge of the Centaurs, Those Who Fell,
|
||
The Way is Shut, The Sinister Triad, So That He May Hear Again, A Sinister Ritual, Innocents for
|
||
Sinners, Unease Makes Tongues Wag, A Door Left Ajar, Esgramor's Master, Shinies!, Echoes of Hirsutta,
|
||
Auction the Past, Stay a While, Durotar's Dire Drought, The Queen's Decree, Avianna's Rose, The Last
|
||
Piece, Reversion.</li>
|
||
<li><strong>Tirisfal Glades</strong>: Rude Awakening, Marla's Last Wish, Monsters With Noble Intentions,
|
||
Restless Family Members, An Unspeakable Secret, A Noble Heritage, The True Heir of the Cains, The
|
||
Friends We Make Along the Way, I'm Home, Apothecary Flemer, The Nature of Freedom, Spotless Standing,
|
||
Stay a While, More Than the Sum of its Parts, Scarlet Correspondence, A Humble Duty, The Balnirs' Rest,
|
||
Brewing Disarray, This Is Justice.</li>
|
||
<li><strong>Mulgore</strong>: Death and Tribute, Death and Exile, Death and Dishonor, Death and Justice,
|
||
Death by Laughter, To Whom I Devote, Fighting Over Carrion, Smoke on the Horizon, Amphora of Sacred
|
||
Water, Stay a While, Exile of Embers, The Smoke that Remembers, The Circle’s Rite.</li>
|
||
</ul>
|
||
<h3>New Ebonhold Quests</h3>
|
||
<ul>
|
||
<li><strong>Outland</strong>: Elemental Balance, Savage Heights, Unstable Fauna, Forest Stalkers, Marsh
|
||
Predators, Skies of Blade's Edge, Shadowed Beasts, Zangarmarsh Trophy.</li>
|
||
<li><strong>Northrend</strong>: Tundra Turbulence, Stormbound, Dragonblight Trophy, Heart of the
|
||
Dragonflights, Peak Predators, Icecrown Advance, Storm Peaks Trophy, Stormforged Scales, Fjord Front,
|
||
Wild Basin, Grizzly Trophy, Zul'Drak Trophy, Basin Expeditions.</li>
|
||
<li><strong>Azeroth</strong>: Redridge Trophy, Morogh Missions, Azuremyst Aid, Shadow of Teldrassil, Trials
|
||
of Durotar, Song of the Woods, Morogh Trophy, Tirisfal Trophy.</li>
|
||
</ul>
|
||
<h3>Fixes</h3>
|
||
<ul>
|
||
<li><strong>[Tracker]</strong> <strong>Combat Update Fix</strong>: Tracker now updates objectives
|
||
immediately during combat without causing Lua errors or taint.</li>
|
||
<li><strong>[Tracker]</strong> <strong>Bag Update Fix</strong>: Quest progress now updates immediately when
|
||
looting items (fixes delay with loot bots).</li>
|
||
<li><strong>[Arrow]</strong> <strong>Refined Visibility Logic</strong>:</li>
|
||
<ul>
|
||
<li>**Auto Nearby**: Arrow correctly defaults to showing the nearest quest when no quests are tracked.
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>**Zone Filter**: In "Auto Mode", the arrow hides if the nearest quest is in a different zone.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>**Instance Filter**: Arrow explicitly hides if the target is in a different instance.</li>
|
||
</ul>
|
||
<li><strong>[Map]</strong> Fixed an issue where completed quest icons would persist on the map
|
||
(`RequestMapUpdate` logic).</li>
|
||
<li><strong>[Database]</strong> Updated `wotlkNpcDB.lua` with scraped spawn data for 12 key beast NPCs in
|
||
Terokkar Forest to ensure accuracy.</li>
|
||
<li><strong>[Arrow]</strong> Fixed a nil function error for `_CollectObjective` when processing incomplete
|
||
quests.</li>
|
||
<li><strong>[Arrow]</strong> Fixed syntax issues that prevented `QuestieArrow` module from initializing
|
||
correctly.</li>
|
||
<li><strong>[Database]</strong> Fixed a runtime crash in `ZoneDB` when encountering maps with no AreaId
|
||
mapping (e.g., Kalimdor).</li>
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
<footer>
|
||
<p>Maintained by Xurkon</p>
|
||
<div style="margin-top: 15px; display: flex; justify-content: center; gap: 10px;">
|
||
<a href="https://www.patreon.com/Xurkon" target="_blank">
|
||
<img src="https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white" alt="Patreon" height="28">
|
||
</a>
|
||
<a href="https://www.paypal.me/Xurkon" target="_blank">
|
||
<img src="https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white" alt="PayPal" height="28">
|
||
</a>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
|
||
</html> |