--------------------------------------------------------------------------------------------------- -- Name: QuestieQuest -- Description: Handles all the quest related functions --------------------------------------------------------------------------------------------------- --///////////////////////////////////////////////////////////////////////////////////////////////-- --------------------------------------------------------------------------------------------------- -- Global Vars --------------------------------------------------------------------------------------------------- local QuestieQuestHashCache = {} LastQuestLogHashes = nil; LastQuestLogCount = 0; LastCount = 0; --------------------------------------------------------------------------------------------------- -- WoW Functions --PERFORMANCE CHANGE-- --------------------------------------------------------------------------------------------------- local QGet_QuestLogTitle = GetQuestLogTitle; local QGet_NumQuestLeaderBoards = GetNumQuestLeaderBoards; local QSelect_QuestLogEntry = SelectQuestLogEntry; local QGet_QuestLogLeaderBoard = GetQuestLogLeaderBoard; local QGet_QuestLogQuestText = GetQuestLogQuestText; --------------------------------------------------------------------------------------------------- -- Finishes a quest and performs a recrusive check to make sure all the required quests that come -- before it are also finsihed and recorded in the players QuestieSeenQuests. It will also clear -- any redundant quest tracking data and make sure a quest that is in a players log isn't -- accidently marked finished. --------------------------------------------------------------------------------------------------- function Questie:finishAndRecurse(questhash) if (QuestieSeenQuests[questhash] == 1) then return end if (QuestieSeenQuests[questhash] == 0) and (QuestieTrackedQuests[questhash]) then if ((QuestieTrackedQuests[questhash]["leaderboards"] == 0) or (QuestieTrackedQuests[questhash]["isComplete"] == 1)) then QuestieSeenQuests[questhash] = 1; end elseif ((QuestieSeenQuests[questhash] == nil) or (QuestieTrackedQuests[questhash] == nil)) then QuestieSeenQuests[questhash] = 1; local req = nil; if QuestieHashMap[questhash] then req = QuestieHashMap[questhash]['rq']; end if req then Questie:finishAndRecurse(req); QuestieTrackedQuests[req] = nil; end end end --------------------------------------------------------------------------------------------------- -- Checks the players quest log to make sure the QuestieSeenQuests is accurate and adds or removes -- any quests from the appropiate caches. This also updates quest tracking data. --------------------------------------------------------------------------------------------------- function Questie:CheckQuestLog() local numEntries, numQuests = GetNumQuestLogEntries(); if(LastCount == numEntries) then end LastCount = numEntries; local t = GetTime(); if(not LastQuestLogHashes) then LastQuestLogHashes = Questie:AstroGetAllCurrentQuestHashesAsMeta(); for k, v in pairs(LastQuestLogHashes) do Questie:AddQuestToMap(v["hash"]); if (not QuestieHashMap[v["hash"]]) then return end if(not QuestieSeenQuests[v["hash"]]) then local req = QuestieHashMap[v["hash"]]['rq']; if req then Questie:finishAndRecurse(req) QuestieTrackedQuests[req] = nil end QuestieSeenQuests[v["hash"]] = 0 QuestieTracker:addQuestToTracker(v["hash"]) end end QUESTIE_LAST_UPDATE_FINISHED = GetTime(); return; end local Quests, QuestsCount = Questie:AstroGetAllCurrentQuestHashesAsMeta(); MapChanged = false; delta = {}; if (QuestsCount > LastQuestLogCount) then for k, v in pairs(Quests) do if(Quests[k] and LastQuestLogHashes[k]) then else if(Quests[k]) then v["deltaType"] = 1; table.insert(delta, v); else v["deltaType"] = 0; table.insert(delta, v); end end end else for k, v in pairs(LastQuestLogHashes) do if(Quests[k] and LastQuestLogHashes[k]) then else if(Quests[k]) then v["deltaType"] = 1; table.insert(delta, v); else v["deltaType"] = 0; table.insert(delta, v); end end end end for k, v in pairs(delta) do if(v["deltaType"] == 1) then Questie:AddQuestToMap(v["hash"]); if (not QuestieHashMap[v["hash"]]) then return end if(not QuestieSeenQuests[v["hash"]]) then local req = QuestieHashMap[v["hash"]]['rq']; if req then Questie:finishAndRecurse(req) QuestieTrackedQuests[req] = nil end QuestieSeenQuests[v["hash"]] = 0 QuestieTracker:addQuestToTracker(v["hash"]) end MapChanged = true; elseif not Questie.collapsedThisRun then Questie:RemoveQuestFromMap(v["hash"]); QuestieTracker:removeQuestFromTracker(v["hash"]); if(not QuestieCompletedQuestMessages[v["name"]]) then QuestieCompletedQuestMessages[v["name"]] = 0; end if (not QuestieHashMap[v["hash"]]) then return end if(not QuestieSeenQuests[v["hash"]]) then local req = QuestieHashMap[v["hash"]]['rq']; if req then QuestieTrackedQuests[req] = nil Questie:finishAndRecurse(req) end QuestieSeenQuests[v["hash"]] = 0 QuestieTracker:addQuestToTracker(v["hash"]) end -- This wipes an abandonded quest from both databases if(QuestieSeenQuests[v["hash"]] == -1) then QuestieTrackedQuests[v["hash"]] = nil QuestieSeenQuests[v["hash"]] = nil end if lastObjectives and lastObjectives[v["hash"]] then lastObjectives = nil; end MapChanged = true; end end newcheckArray = nil; checkArray = nil; BiggestTable = nil; delta = nil; if(MapChanged == true) then Questie:SetAvailableQuests(); Questie:RedrawNotes(); end LastQuestLogHashes = Quests; LastQuestLogCount = QuestsCount; if(MapChanged == true) then LastQuestLogHashes = nil; LastCount = 0; Questie:CheckQuestLog(); Questie:SetAvailableQuests() Questie:RedrawNotes(); QUESTIE_LAST_UPDATE_FINISHED = GetTime(); return true; else QUESTIE_LAST_UPDATE_FINISHED = GetTime(); return nil; end end --------------------------------------------------------------------------------------------------- -- Forces an update on a quest --------------------------------------------------------------------------------------------------- lastObjectives = nil; function Questie:UpdateQuests(force) if(lastObjectives == nil) then lastObjectives = {}; Questie:UpdateQuestsInit(); return; end local ZonesChecked = 0; local t = GetTime(); local CurrentZone = GetZoneText(); local numEntries, numQuests = GetNumQuestLogEntries(); local foundChange = false; local ZonesWithQuests = {}; local change = Questie:UpdateQuestInZone(CurrentZone); ZonesChecked = ZonesChecked+1; if(not change) then change = Questie:UpdateQuestInZone(GetMinimapZoneText()); ZonesChecked = ZonesChecked+1; end if(not change or force) then for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if(isHeader and q ~= CurrentZone) then local c = Questie:UpdateQuestInZone(q, force); ZonesChecked = ZonesChecked +1; change = c; if(c and not force)then break; end end end else end return change; end --------------------------------------------------------------------------------------------------- -- Forces an update on a quest in a specific zone --------------------------------------------------------------------------------------------------- function Questie:UpdateQuestInZone(Zone, force) local numEntries, numQuests = GetNumQuestLogEntries(); local foundChange = nil; local ZoneFound = nil; local QuestsChecked = 0; for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if(ZoneFound and isHeader) then break; end if(isHeader and q == Zone) then ZoneFound = true; end if not isHeader and ZoneFound then QuestsChecked = QuestsChecked+1; QSelect_QuestLogEntry(i); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); local hash = Questie:getQuestHash(q, level, objectiveText); if QuestieHashCache[q] == nil then QuestieHashCache[q] = {}; end QuestieHashCache[q][hash] = GetTime(); if not lastObjectives[hash] then lastObjectives[hash] = {}; end local Refresh = nil; for obj = 1, count do if (not lastObjectives[hash][obj]) then lastObjectives[hash][obj] = {}; end local desc, typ, done = QGet_QuestLogLeaderBoard(obj); if(lastObjectives[hash][obj].desc == desc and lastObjectives[hash][obj].typ == typ and lastObjectives[hash][obj].done == done) then elseif(lastObjectives[hash][obj].done ~= done) then Refresh = true; foundChange = true; else foundChange = true; end lastObjectives[hash][obj].desc = desc; lastObjectives[hash][obj].typ = typ; lastObjectives[hash][obj].done = done; end if(Refresh) then Questie:AddQuestToMap(hash, true); if (QuestieTrackedQuests[hash]) then QuestieTracker:updateFrameOnTracker(hash, i, level) end QuestieTracker:fillTrackingFrame() elseif foundChange and QuestieConfig.trackerEnabled == true then if (QuestieTrackedQuests[hash]) then QuestieTracker:updateFrameOnTracker(hash, i, level) end QuestieTracker:fillTrackingFrame() end end if(foundChange and not force) then break; end end return foundChange; end --------------------------------------------------------------------------------------------------- -- Updates all quest objectives upon login or UI reload --------------------------------------------------------------------------------------------------- function Questie:UpdateQuestsInit() local numEntries, numQuests = GetNumQuestLogEntries(); for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if not isHeader then QSelect_QuestLogEntry(i); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); local hash = Questie:getQuestHash(q, level, objectiveText); if not lastObjectives[hash] then lastObjectives[hash] = {}; end for obj = 1, count do if (not lastObjectives[hash][obj]) then lastObjectives[hash][obj] = {}; end lastObjectives[hash][obj].desc = desc; lastObjectives[hash][obj].typ = typ; lastObjectives[hash][obj].done = done; end end end end --------------------------------------------------------------------------------------------------- -- Astrolabe functions --------------------------------------------------------------------------------------------------- function Questie:AstroGetAllCurrentQuestHashes(print) local hashes = {}; local numEntries, numQuests = GetNumQuestLogEntries(); if(print) then Questie:debug_Print("--Listing all current quests--"); end for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if not isHeader then QSelect_QuestLogEntry(i); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); local quest = {}; quest["name"] = q; quest["level"] = level; local hash = Questie:getQuestHash(q, level, objectiveText) quest["hash"] = hash; if(IsAddOnLoaded("URLCopy") and print)then Questie:debug_Print(" "..q,URLCopy_Link(quest["hash"])); elseif(print) then Questie:debug_Print(" "..q,quest["hash"]); end table.insert(hashes, quest); else if(print) then Questie:debug_Print(" Zone:", q); end end end if(print) then Questie:debug_Print("--End of all current quests--"); end return hashes; end --------------------------------------------------------------------------------------------------- Questie.lastCollapsedCount = 0; Questie.collapsedThisRun = false; function Questie:AstroGetAllCurrentQuestHashesAsMeta(print) local startTime = GetTime(); local hashes = {}; local Count = 0; local numEntries, numQuests = GetNumQuestLogEntries(); local collapsedCount = 0; Questie.collapsedThisRun = false; for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if isCollapsed then collapsedCount = collapsedCount + 1; end if not isHeader then QSelect_QuestLogEntry(i); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); local hash = Questie:getQuestHash(q, level, objectiveText) hashes[hash] = {}; hashes[hash]["hash"] = hash; hashes[hash]["name"] = q; hashes[hash]["level"] = level; if(IsAddOnLoaded("URLCopy") and print)then Questie:debug_Print(" "..q,URLCopy_Link(quest["hash"])); elseif(print) then Questie:debug_Print(" "..q,quest["hash"]); end else if(print) then Questie:debug_Print(" Zone:", q); end end end if(print) then Questie:debug_Print("--End of all current quests--"); end if not (collapsedCount == Questie.lastCollapsedCount) then Questie.lastCollapsedCount = collapsedCount; Questie.collapsedThisRun = true; end Questie:debug_Print("[AllCurrentHashes] Getting all hashes took: ",(GetTime()-startTime)*1000, "ms"); return hashes, numQuests; end --------------------------------------------------------------------------------------------------- function Questie:AstroGetFinishedQuests() numEntries, numQuests = GetNumQuestLogEntries(); local FinishedQuests = {}; for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if not isHeader then QSelect_QuestLogEntry(i); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); Done = true; for obj = 1, count do local desc, typ, done = QGet_QuestLogLeaderBoard(obj); if not done then Done = nil; end end if(Done) then local hash = Questie:getQuestHash(q, level, objectiveText); Questie:debug_Print("[AstroGetFinishedQuests] Finished returned:", hash, q ,level); table.insert(FinishedQuests, hash); end end end return FinishedQuests; end --------------------------------------------------------------------------------------------------- function Questie:AstroGetQuestObjectives(questHash) QuestLogID = Questie:GetQuestIdFromHash(questHash); local mapid = GetCurrentMapID(); local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(QuestLogID); QSelect_QuestLogEntry(QuestLogID); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); local AllObjectives = {}; AllObjectives["QuestName"] = q; AllObjectives["objectives"] = {}; for i = 1, count do local desc, typ, done = QGet_QuestLogLeaderBoard(i); local typeFunction = AstroobjectiveProcessors[typ]; if typ == "item" or typ == "monster" or not (typeFunction == nil) then local indx = findLast(desc, ":"); local countless = indx == nil; local countstr = ""; local namestr = desc; if not countless then countstr = string.sub(desc, indx+2); namestr = string.sub(desc, 1, indx-1); end local objectives = typeFunction(q, namestr, countstr, selected, mapid); Objective = {}; local hash = Questie:getQuestHash(q, level, objectiveText); for k, v in pairs(objectives) do if (AllObjectives["objectives"][v["name"]] == nil) then AllObjectives["objectives"][v["name"]] = {}; end if(not QuestieCachedMonstersAndObjects[hash]) then QuestieCachedMonstersAndObjects[hash] = {}; end if(not QuestieCachedMonstersAndObjects[hash][v["name"]]) then QuestieCachedMonstersAndObjects[hash][v["name"]] = {}; end QuestieCachedMonstersAndObjects[hash][v["name"]].name = v["name"]; for monster, info in pairs(v['locations']) do local obj = {}; obj["mapid"] = info[1]; obj["x"] = info[2]; obj["y"] = info[3]; obj["lootname"] = v["lootname"]; obj["type"] = v["type"]; obj["done"] = done; obj['objectiveid'] = i; table.insert(AllObjectives["objectives"][v["name"]], obj); end end else end end return AllObjectives; end --------------------------------------------------------------------------------------------------- AstroobjectiveProcessors = { ['item'] = function(quest, name, amount, selected, mapid) local list = {}; local itemdata = QuestieItems[name]; Questie:debug_Print(name); if itemdata == nil then Questie:debug_Print("[AstroobjectiveProcessors] ERROR1 PROCESSING '" .. quest .. "'' objective:'" .. name .. "'' no itemdata".. " ID:0"); itemdata = QuestieItems[name]; end if itemdata then for k,v in pairs(itemdata) do if k == "locationCount" then local monster = {}; monster["name"] = name; monster["locations"] = {}; monster["type"] = "loot"; for b=1,itemdata['locationCount'] do local loc = itemdata['locations'][b]; table.insert(monster["locations"], loc); end table.insert(list, monster); elseif k == "drop" then for e,r in pairs(v) do local monster = {}; monster["name"] = name; monster["lootname"] = e; monster["locations"] = {}; monster["type"] = "loot"; for k, pos in pairs(QuestieMonsters[e]['locations']) do table.insert(monster["locations"], pos); end table.insert(list, monster) end elseif k =="locations" then else Questie:debug_Print("[AstroobjectiveProcessors] ERROR2 " .. quest .. " objective:" .. name.. " ID:1"); for s, r in pairs(itemdata) do Questie:debug_Print(s,tostring(r)); end end end end return list; end, ['event'] = function(quest, name, amount, selected, mapid) local evtdata = QuestieEvents[name] local list = {}; if evtdata == nil then Questie:debug_Print("[AstroobjectiveProcessors] ERROR3 UNKNOWN EVENT " .. quest .. " objective:" .. name.. " ID:2"); else for b=1,evtdata['locationCount'] do local monster = {}; monster["name"] = name; monster["locations"] = {}; monster["type"] = "event"; for b=1,evtdata['locationCount'] do local loc = evtdata['locations'][b]; table.insert(monster["locations"], loc); end table.insert(list, monster); end end return list; end, ['monster'] = function(quest, name, amount, selected, mapid) local list = {}; local monster = {}; if(string.find(name, " slain")) then monster["name"] = name; else monster["name"] = string.sub(name, string.len(name)-6); end monster["type"] = "slay"; monster["locations"] = {}; if(QuestieMonsters[name] and QuestieMonsters[name]['locations']) then for k, pos in pairs(QuestieMonsters[name]['locations']) do table.insert(monster["locations"], pos); end end table.insert(list, monster); return list; end, ['object'] = function(quest, name, amount, selected, mapid) local list = {}; local objdata = QuestieObjects[name]; if objdata == nil then Questie:debug_Print("[AstroobjectiveProcessors] ERROR4 UNKNOWN OBJECT " .. quest .. " objective:" .. name); else for b=1,objdata['locationCount'] do local monster = {}; monster["name"] = name; monster["locations"] = {}; monster["type"] = "object"; for b=1,objdata['locationCount'] do local loc = objdata['locations'][b]; table.insert(monster["locations"], loc); end table.insert(list, monster); end end return list; end } --------------------------------------------------------------------------------------------------- -- End of Astrolabe functions --------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- -- Get quest ID from quest hash --------------------------------------------------------------------------------------------------- LastNrOfEntries = 0; CachedIds = {}; function Questie:GetQuestIdFromHash(questHash) local numEntries, numQuests = GetNumQuestLogEntries(); if(numEntries ~= LastNrOfEntries or not CachedIds[questHash]) then CachedIds = {}; LastNrOfEntries = numEntries; Questie:UpdateQuestIds(); if CachedIds[questHash] then return CachedIds[questHash]; end else local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(CachedIds[questHash]); QSelect_QuestLogEntry(CachedIds[questHash]); local questText, objectiveText = QGet_QuestLogQuestText(); if(q and level and objectiveText) then if(Questie:getQuestHash(q, level, objectiveText) == questHash) then return CachedIds[questHash]; else Questie:debug_Print("[GetQuestIdFromHash] Something went wrong Error1"); end else Questie:debug_Print("[GetQuestIdFromHash] Something went wrong, Error2", tostring(CachedIds[questHash]), tostring(q), tostring(level)); end end end --------------------------------------------------------------------------------------------------- -- Update quest ID's --------------------------------------------------------------------------------------------------- function Questie:UpdateQuestIds() local startTime = GetTime() local numEntries, numQuests = GetNumQuestLogEntries(); for i = 1, numEntries do local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); if not isHeader then QSelect_QuestLogEntry(i); local questText, objectiveText = QGet_QuestLogQuestText(); local hash = Questie:getQuestHash(q, level, objectiveText); if(not q or not level or not objective) then Questie:debug_Print("[UpdateQuestID] ERROR!!!! Error1",tostring(name), tostring(level), tostring(i), tostring(hash)) end CachedIds[hash] = i; end end Questie:debug_Print("[UpdateQuestID] Had to update UpdateQuestIds",(GetTime() - startTime)*1000,"ms") end QuestieHashCache = {}; --------------------------------------------------------------------------------------------------- -- Get quest hash from quest name --------------------------------------------------------------------------------------------------- function Questie:GetHashFromName(name) if QuestieHashCache[name] then local hashtable = QuestieHashCache[name]; local bestValue = 0; local bestHash = -1; for k,v in pairs(hashtable) do if v > bestValue then bestValue = v; bestHash = k; end end if not (bestHash == -1) then return bestHash; end end return Questie:getQuestHash(name, nil, nil); end --------------------------------------------------------------------------------------------------- -- Lookup quest hash from name, level or objective text --------------------------------------------------------------------------------------------------- function Questie:getQuestHash(name, level, objectiveText) local hashLevel = level or "hashLevel" local hashText = objectiveText or "hashText" if QuestieQuestHashCache[name..hashLevel..hashText] then return QuestieQuestHashCache[name..hashLevel..hashText] end local questLookup = QuestieLevLookup[name]; local hasOthers = false; if questLookup then local count = 0; local retval = 0; local bestDistance = 4294967295; -- some high number (0xFFFFFFFF) local race = UnitRace("Player"); for k,v in pairs(questLookup) do local rr = v[1]; if checkRequirements(null, race, null, rr) or true then if count == 1 then hasOthers = true; end if k == objectiveText then QuestieQuestHashCache[name..hashLevel..hashText] = v[2]; return v[2],hasOthers; -- exact match end local dist = 4294967294; if not (objectiveText == nil) then dist = Questie:Levenshtein(objectiveText, k); end if dist < bestDistance then bestDistance = dist; retval = v[2]; end else end count = count + 1; end if not (retval == 0) then QuestieQuestHashCache[name..hashLevel..hashText] = retval; return retval, hasOthers; -- nearest match end end if name == nil then return -1; end local hash = Questie:MixString(0, name); if not (level == nil) then hash = Questie:MixInt(hash, level); QuestieQuestHashCache[name..hashLevel..hashText] = hash; end if not (objectiveText == nil) then hash = Questie:MixString(hash, objectiveText); QuestieQuestHashCache[name..hashLevel..hashText] = hash; end QuestieQuestHashCache[name..hashLevel..hashText] = hash; return hash, false; end --------------------------------------------------------------------------------------------------- -- Checks to see if a quest is finished by quest hash --------------------------------------------------------------------------------------------------- function Questie:IsQuestFinished(questHash) local i = Questie:GetQuestIdFromHash(questHash); if (not i) then return false; end local FinishedQuests = {}; local q, level, questTag, isHeader, isCollapsed, isComplete = QGet_QuestLogTitle(i); QSelect_QuestLogEntry(i); local count = QGet_NumQuestLeaderBoards(); local questText, objectiveText = QGet_QuestLogQuestText(); Done = true; for obj = 1, count do local desc, typ, done = QGet_QuestLogLeaderBoard(obj); if not done then Done = nil; end end if(Done and Questie:getQuestHash(q, level, objectiveText) == questHash) then local ret = {}; ret["questHash"] = questHash; ret["name"] = q; ret["level"] = level; return ret; end return nil; end --------------------------------------------------------------------------------------------------- -- Race, Class and Profession filter functions --------------------------------------------------------------------------------------------------- RaceBitIndexTable = { ['human'] = 1, ['orc'] = 2, ['dwarf'] = 3, ['nightelf'] = 4, ['night elf'] = 4, ['scourge'] = 5, ['undead'] = 5, ['tauren'] = 6, ['gnome'] = 7, ['troll'] = 8, ['goblin'] = 9 }; ClassBitIndexTable = { ['warrior'] = 1, ['paladin'] = 2, ['hunter'] = 3, ['rogue'] = 4, ['priest'] = 5, ['shaman'] = 7, ['mage'] = 8, ['warlock'] = 9, ['druid'] = 11 } --------------------------------------------------------------------------------------------------- function unpackBinary(val) ret = {}; for q=0,16 do if bit.band(bit.rshift(val,q), 1) == 1 then table.insert(ret, true); else table.insert(ret, false); end end return ret; end --------------------------------------------------------------------------------------------------- function checkRequirements(class, race, dbClass, dbRace) local valid = true; if race and dbRace and not (dbRace == 0) then local racemap = unpackBinary(dbRace); valid = racemap[RaceBitIndexTable[strlower(race)]]; end if class and dbClass and valid and not (dbRace == 0)then local classmap = unpackBinary(dbClass); valid = classmap[ClassBitIndexTable[strlower(class)]]; end return valid; end --------------------------------------------------------------------------------------------------- function Questie:GetAvailableQuestHashes(mapFileName, levelFrom, levelTo) local mapid = -1 if(QuestieZones[mapFileName]) then mapid = QuestieZones[mapFileName][1]; end local class = UnitClass("Player"); local race = UnitRace("Player"); local hashes = {}; for l=levelFrom,levelTo do if QuestieZoneLevelMap[mapid] then local content = QuestieZoneLevelMap[mapid][l]; if content then for k,v in pairs(content) do local qdata = QuestieHashMap[v]; if(qdata) then local requiredQuest = qdata['rq']; local requiredRaces = qdata['rr']; local requiredClasses = qdata['rc']; local requiredSkill = qdata['rs']; local valid = not QuestieSeenQuests[requiredQuest]; if(requiredQuest) then valid = QuestieSeenQuests[requiredQuest]; end valid = valid and (requiredSkill == nil or QuestieConfig.showProfessionQuests); if valid then valid = valid and checkRequirements(class, race, requiredClasses,requiredRaces); end if valid and not QuestieHandledQuests[requiredQuest] and not QuestieSeenQuests[v] then table.insert(hashes, v); end end end end end end return hashes; end --------------------------------------------------------------------------------------------------- -- End of filter functions ---------------------------------------------------------------------------------------------------