diff WorldQuests.lua @ 93:98b5e08b75ed v1.4.9

- Fixed quest completion checking and handling - Changed animation method to hopefully stop weird flickering. - Pins are now visible before full reward data is loaded - Filter bar redesigned: - aligned horizontally along the top of the map display - filter buttons display a '+' when there are matches in both current and other zones, and '*' when there only matches in other zones - button tooltips separate local and global quests - button categories are highlighted and labeled when the cursor is over them - Fixed invalid POI targets appearing when the spell targeting cursor is active
author Nenue
date Sat, 15 Apr 2017 11:04:54 -0400
parents 77013bd72adb
children b29b35cb8539
line wrap: on
line diff
--- a/WorldQuests.lua	Tue Apr 11 00:44:22 2017 -0400
+++ b/WorldQuests.lua	Sat Apr 15 11:04:54 2017 -0400
@@ -26,10 +26,10 @@
 local GetQuestLogRewardInfo = GetQuestLogRewardInfo
 local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID
 local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete
-local IsQuestCriteriaForBounty = IsQuestCriteriaForBounty
+local HaveQuestRewardData = HaveQuestRewardData
+local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
 
 local ToggleButton = {}
-local callbacks = {}
 local BROKEN_ISLES_ID, DALARAN_ID, AZSUNA_ID, VALSHARAH_ID, HIGHMOUNTAIN_ID, STORMHEIM_ID, SURAMAR_ID, EOA_ID = 1007, 1014, 1015,1018, 1024, 1017, 1033, 1096
 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70',  [AZSUNA_ID] = 'Azsuna',  [VALSHARAH_ID] = "Val'sharah",
   [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim',  [SURAMAR_ID] = 'Suramar',  [EOA_ID] = 'EyeOfAszhara', }
@@ -43,19 +43,60 @@
 
 local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard
 local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton
+local defaults = {}
 
+local continentScanned
+local layoutDirty = true
+local bountiesDirty = true
+local artifactPowerDirty = true
+local currentScale = WorldMapDetailFrame:GetScale()
+local canTargetQuests
+local isDataLoaded = true
+local artifactKnowledgeLevel
+local superTrackedQuestID
+local lastRefresh
+local refreshReason
+
+local bountyQuests = {}
+local bountyInfo = {}
+local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID
+
+local totalPins = 0
+local numShown = 0
+local numLoaded = 0
+local numOverlays = 1
+local scaleConstant = 1
 local pinBaseIndex = 1500
 local overlayBaseIndex = 1580
-local layoutDirty = true
-local bountiesDirty = true
-local currentScale = WorldMapDetailFrame:GetScale()
-local canTargetQuests
-local numShown = 0
-local numLoaded = 0
-local isDataLoaded = true
-local numOverlays = 1
-local scaleConstant = 1
-Module.TasksByID = {}
+
+local artifactKnowldegeSpells = {
+  [207856] = true,
+  [209203] = true,
+  [209204] = true,
+  [209205] = true,
+  [209206] = true,
+  [209207] = true,
+  [209208] = true,
+  [209209] = true,
+  [209210] = true,
+  [209211] = true,
+  [209212] = true,
+  [219978] = true,
+  [227852] = true,
+  [236477] = true,
+  [236489] = true,
+  [236302] = true,
+  [236488] = true,
+  [236490] = true,
+  [240475] = true,
+  [243176] = true,
+  [243177] = true,
+  [243178] = true,
+  [243182] = true,
+  [243183] = true,
+  [243187] = true,
+  [245133] = true,
+}
 
 --%debug%
 local SetTimedCallbackForAllPins = function(seconds, callback)
@@ -66,61 +107,86 @@
   end)
 end
 
+function Module:OnLoad()
+  --print('|cFFFF4400'..self:GetName()..':OnLoad()')
 
-function Module:Setup()
-  --print('|cFFFF4400'..self:GetName()..':Setup()')
-  for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
-    db.QuestsByZone[mapID] = {}
+  self:SetParent(WorldMapFrame.UIElementsFrame)
+  WorldPlan:AddHandler(self, defaults)
+
+  for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
+    db.QuestsByZone[areaID] = {}
   end
-  for target, arg in pairs(callbacks) do
-    --print(type(target))
-    if type(target) == 'table' then
-      local callerName = target:GetName() or tostring(target)
-      for name, method  in pairs(arg) do
-        --print(callerName, arg)
-        hooksecurefunc(target, name, function(...)
-          self:OnSecureHook(callerName .. '.' .. name, method, ...)
-        end)
+
+  -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
+  self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
+  self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED')
+  self:RegisterEvent('SKILL_LINES_CHANGED')
+  self:RegisterEvent('ARTIFACT_UPDATE')
+  self:RegisterEvent('QUEST_LOG_UPDATE')
+  self:RegisterEvent('UNIT_SPELLCAST_STOP')
+end
+
+function Module:OnEvent (event, ...)
+  print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...)
+  if (event == 'QUEST_LOG_UPDATE') then
+    self:UpdateBounties(event)
+  elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
+    local questID = ...
+    if questID and db.QuestsByID[questID] then
+      db.QuestsByID[questID]:Release()
+    end
+    self:Refresh(event)
+  elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then
+    self:Refresh(event)
+  elseif event == 'ARTIFACT_UPDATE' then
+    self:UpdateArtifactPower()
+  elseif event == 'MODIFIER_STATE_CHANGED' then
+    self:UpdateModifierState()
+  elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then
+    if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then
+      db.QuestsByID[superTrackedQuestID].isStale = true
+    end
+    local newID = GetSuperTrackedQuestID()
+    if newID and db.QuestsByID[newID] then
+      db.QuestsByID[newID].isStale = true
+    end
+  elseif event == 'UNIT_SPELLCAST_STOP' then
+    local name, _, _, _, spellID = ...
+    if artifactKnowldegeSpells[spellID] then
+      db.log('AK spellcast ended ' .. tostring(name) .. ' ('.. tostring(spellID)..')')
+      self:UpdateArtifactPower()
+    end
+  end
+end
+
+function Module:OnUpdate(sinceLast)
+  if WorldPlanData.DebugEnabled then
+    if self.refreshBenchMarkTicker then
+      --print(self.refreshBenchMarkTicker)
+      self.refreshBenchMarkTicker =   self.refreshBenchMarkTicker - 1
+
+      if self.refreshBenchMarkTicker == 0 then
+
+        self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000)
+        self.debugMessage:SetText(self.refreshTime)
+        self.refreshBenchMarkTicker = nil
       end
     else
-      hooksecurefunc(target, function(...)
-        self:OnSecureHook(target, arg, ...)
-      end)
+      self.refreshBenchMark = GetTime()
     end
   end
 
-  self.Status = CreateFrame('Frame', nil, self)
-  self.Status:SetPoint('TOPLEFT', WorldMapFrame.UIElementsFrame, 'TOPLEFT', 0, 0)
-  self.Status:SetPoint('BOTTOMRIGHT', WorldMapFrame.UIElementsFrame, 'TOPRIGHT', 0, -4)
-  self.Status.t = self.Status:CreateTexture(nil, 'OVERLAY')
-  self.Status.b = self.Status:CreateTexture(nil, 'BACKGROUND')
-  self.Status.b:SetColorTexture(0,0,0,.25)
-  self.Status.b:SetAllPoints(self.Status)
-  self.Status.t:SetColorTexture(1,1,1,.5)
-  self.Status.t:SetPoint('TOP')
-  self.Status.t:SetPoint('BOTTOM')
-  self.Status.t:SetPoint('LEFT')
-  local translationEnd, translationStart
-  self.Status:SetScript('OnUpdate', function(status)
-    local translateTo
-    if numLoaded < numShown then
-      translateTo = (numLoaded/numShown) * status:GetWidth()
-      status.t:SetWidth(translateTo)
-    else
-      translateTo = status:GetWidth()
-      status.t:SetWidth(translateTo)
-    end
-  end)
-
-  self:SetAllPoints(WorldMapFrame.UIElementsFrame)
-  for k,v in pairs( ToggleButton) do
-    self.Toggle:SetScript(k,v)
+  if self.filtersDirty or self.isStale then
+    self:Refresh()
   end
 
-  self:UpdateBounties('SETUP')
+  if #db.UpdatedPins >= 1 then
+    --print('|cFF00FF88pending update', #db.UpdatedPins)
+    self:UpdateNext()
+  end
+end
 
-  self:Show()
-end
+local callbacks = {}
 callbacks.ClickWorldMapActionButton = function(WorldQuests)
   WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON')
 end
@@ -145,6 +211,43 @@
   WorldQuests:Refresh('CASTING_STATE_CHANGED')
 end
 
+function Module:Setup()
+  --print('|cFFFF4400'..self:GetName()..':Setup()')
+  for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
+    db.QuestsByZone[mapID] = {}
+  end
+  for target, arg in pairs(callbacks) do
+    --print(type(target))
+    if type(target) == 'table' then
+      local callerName = target:GetName() or tostring(target)
+      for name, method  in pairs(arg) do
+        --print(callerName, arg)
+        hooksecurefunc(target, name, function(...)
+          self:OnSecureHook(callerName .. '.' .. name, method, ...)
+        end)
+      end
+    else
+      hooksecurefunc(target, function(...)
+        self:OnSecureHook(target, arg, ...)
+      end)
+    end
+  end
+
+
+  self:SetAllPoints(WorldMapFrame.UIElementsFrame)
+  self:UpdateArtifactPower()
+  self:UpdateBounties('SETUP')
+  self:Show()
+end
+
+function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
+  if isNewMap or self.isStale then
+    print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
+    layoutDirty = true
+    self:Refresh('WORLD_MAP_CHANGED')
+  end
+end
+
 function Module:OnConfigUpdate()
   --print('|cFFFFFF00OnConfigUpdate()|r')
   if db.Config.FadeWhileGrouped then
@@ -158,15 +261,6 @@
       pin:SetShown(false)
     end
   end
-
-  ToggleButton.OnShow(self.Toggle)
-end
-
-local InternalHideButton = function(button, index)
-  button:Hide()
-end
-local InternalShowButton = function(button, index)
-  button:Show()
 end
 
 function Module:OnSecureHook(callbackName, func, ...)
@@ -174,126 +268,43 @@
   func(self, ...)
 end
 
-local defaults = {}
-local REWARD_UNKNOWN = 768
-function Module:OnLoad()
-  --print('|cFFFF4400'..self:GetName()..':OnLoad()')
+function Module:UpdateModifierState()
 
-  self:SetParent(WorldMapFrame.UIElementsFrame)
-  WorldPlan:AddHandler(self, defaults)
-
-  for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
-    db.QuestsByZone[areaID] = {}
-  end
-
-  -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
-  self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
-  self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED')
-  self:RegisterEvent('SKILL_LINES_CHANGED')
-  --self:RegisterEvent('CURRENT_SPELL_CAST_CHANGED')
-  self:RegisterEvent('ARTIFACT_UPDATE')
-  self:RegisterEvent('QUEST_LOG_UPDATE')
 end
 
-local artifactKnowledgeMultiplier
-local superTrackedQuestID
-function Module:OnEvent (event, ...)
+function Module:UpdateTaskPOIs()
+  canTargetQuests = SpellCanTargetQuest()
+  for i = 1, NUM_WORLDMAP_TASK_POIS do
+    local poiFrame = _G['WorldMapFrameTaskPOI'..i]
+    if poiFrame and poiFrame.worldQuest then
+      local pin = db.QuestsByID[poiFrame.questID]
+      if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then
+        poiFrame:Show()
+      else
+        poiFrame:Hide()
+      end
+    end
+  end
+end
+-- re-anchors and scales pins that have had either of these changed due to data loading delays
+function Module:UpdateNext()
+  --print('|cFF00FF88UpdateNext()')
+  local pin = tremove(db.UpdatedPins)
 
-  print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...)
-  if (event == 'QUEST_LOG_UPDATE') then
-    self:UpdateBounties(event)
-  elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
-    local questID = ...
-    if questID and db.QuestsByID[questID] then
-      db.QuestsByID[questID].complete = true
-      self:ReleasePin(db.QuestsByID[questID])
-    end
-    self:Refresh(event)
-  elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then
-    self:Refresh(event)
-  elseif event == 'ARTIFACT_UPDATE' then
-    local akCheck = C_ArtifactUI.GetArtifactKnowledgeMultiplier()
-    if akCheck and (akCheck ~= artifactKnowledgeMultiplier) then
-      if artifactKnowledgeMultiplier then
-        --print('push artifact knowledge update', artifactKnowledgeMultiplier, 'to', akCheck)
-        for index, pin in pairs( db.QuestsByID) do
-          if pin.rewardType == REWARD_ARTIFACT_POWER then
-            db.log(pin.questID .. ' ' .. tostring(pin.title) .. ' Flagged for artifact power.')
-            pin.itemNumber = 0
-            pin.dataLoaded = nil
-          end
-        end
-      else
-
-        print('artifact knowledge multiplier is known', akCheck)
-      end
-      artifactKnowledgeMultiplier = akCheck
-    end
-  elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then
-    if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then
-      db.QuestsByID[superTrackedQuestID].isStale = true
-    end
-    local newID = GetSuperTrackedQuestID()
-    if newID and db.QuestsByID[newID] then
-      db.QuestsByID[newID].isStale = true
+  -- criteria state is asserted independently
+  pin:CheckFilterRules()
+  local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
+  --print(pin.title, pin.dataLoaded  and not pin.filtered, scaleFactor)
+  if pin.used then
+    pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
+    if pin:IsVisible() then
+      pin:Refresh()
+    else
+      pin.isStale = true
     end
   end
 end
 
-
-function Module:OnUpdate(sinceLast)
-
-  if self.refreshBenchMarkTicker then
-    --print(self.refreshBenchMarkTicker)
-    self.refreshBenchMarkTicker =   self.refreshBenchMarkTicker - 1
-
-    if self.refreshBenchMarkTicker == 0 then
-
-      self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000)
-      self.debugMessage:SetText(self.refreshTime)
-      self.refreshBenchMarkTicker = nil
-    end
-  else
-    self.refreshBenchMark = GetTime()
-  end
-
-  if self.filtersDirty or self.isStale then
-    self:Refresh()
-  end
-  if #db.UpdatedPins >= 1 then
-    --print('|cFF00FF88pending update', #db.UpdatedPins)
-    self:UpdateNext()
-  end
-
-end
-
-function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
-  if isNewMap or self.isStale then
-    print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
-    layoutDirty = true
-    self:Refresh('WORLD_MAP_CHANGED')
-  else
-
-    --print('|cFFFFFF00'..self:GetName()..':OnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
-  end
-end
-
-
-function Module:UpdateTaskPOIs()
-  canTargetQuests = SpellCanTargetQuest()
-  local func = canTargetQuests and 'Show' or 'Hide'
-  for i = 1, NUM_WORLDMAP_TASK_POIS do
-    local button = _G['WorldMapFrameTaskPOI'..i]
-    if button and button.worldQuest then
-      button[func](button)
-    end
-  end
-end
-
-local bountyQuests = {}
-local bountyInfo = {}
-
-local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID
 function Module:UpdateBounties(...)
     print('|cFF00FF88BountyInfo()|r', ...)
   wipe(db.BountiesByFactionID)
@@ -320,130 +331,43 @@
   bountiesDirty = nil
 end
 
-
-local totalPins = 0
-local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
-function Module:AcquirePin (info)
-  local questID = info.questId
-  if not questID then
-    return nil
+-- check current artifact knowledge and update pins accordingly
+function Module:UpdateArtifactPower(overrideLevel)
+  if InCombatLockdown() then
+    artifactPowerDirty = true
+    return
   end
 
-  if not QuestUtils_IsQuestWorldQuest(questID) then
-    return nil
+  print('|cFF00FF88UpdateArtifactPower()|r')
+  local _, akLevel = GetCurrencyInfo(1171)
+  if overrideLevel then
+    akLevel = overrideLevel
   end
 
-  -- if we're grabbing a pin, the filters need to be checked
-  local pin = db.QuestsByID[questID]
-  if not pin then
-    local numFree = #db.FreePins
-    if numFree >= 1 then
-      pin = tremove(db.FreePins, numFree)
-      --print('|cFF00FF00Re-using', pin:GetName())
-    else
-      totalPins = totalPins + 1
-      local name = 'WorldPlanQuestMarker' .. numOverlays
-      --print('|cFF00FF00Creating', name)
-      pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
-
-      pin:SetID(totalPins)
-      numOverlays = numOverlays + 1
-      --pin.iconBorder:SetVertexColor(0,0,0,1)
+  --db.print('current AK', akLevel)
+  if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then
+    --print('new ak level', akLevel)
+    db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel))
+    for _, pin in pairs(db.QuestsByID) do
+      if (pin.rewardType == REWARD_ARTIFACT_POWER) then
+        print(pin.title, pin.itemNumber)
+        local newAP = pin:UpdateArtifactPower()
+        if newAP then
+          pin.itemNumber = newAP
+          print(newAP)
+        else
+          pin.dataLoaded = nil
+        end
+        pin.isStale = true
+      end
     end
-    pin.questID = questID
-    pin.worldQuest = true
-    pin.throttle = pin.updateRate
-    pin.isNew = true
-    pin.currentWidth = nil
-    db.QuestsByID[questID] = pin
-    tinsert(db.UsedPins, pin)
-
+    artifactKnowledgeLevel = akLevel
   end
-
-  if pin and info then
-    pin.inProgress = info.inProgress
-    pin.floor = info.floor
-    pin.numObjectives = info.numObjectives or 0
-    if info.x and info.y then
-      if (info.x ~= pin.x) or (info.y ~= pin.y) then
-        pin.isStale = true
-        --rprint('|cFFFF4400SetCoords|r', info.x, info.y)
-      end
-
-    end
-  end
-
-  pin.x = info.x or pin.x
-  pin.y = info.y or pin.y
-
-  if not HaveQuestData(questID) then
-    TQ_RequestPreloadRewardData(questID);
-  end
-
-
-  if (not pin.dataLoaded) then
-    local dataLoaded = pin:GetData()
-    if dataLoaded then
-      WorldPlan.dataFlush = true
-    else
-      isDataLoaded = false
-    end
-  end
-
-
-  pin.isActive = TQ_IsActive(questID)
-  pin:GetCriteriaState()
-  pin:CheckFilterRules()
-  --rprint(pin:GetID(), pin.filtered, pin.used)
-
-  return pin
-end
-
--- remove from index and add it to the recycling heap
-function Module:ReleasePin (pin)
-
-  local id = pin.questID
-  if id then
-    db.QuestsByID[id] = nil
-
-    for i, zone in pairs(db.QuestsByZone) do
-      --print('-', i, zone[i])
-      zone[id] = nil
-    end
-    db.TasksByID[id] = nil
-  end
-  pin:Reset()
-  tinsert(db.FreePins, pin)
-
-  WorldPlan.dataFlush = true
-  --print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title)
-end
-
--- re-anchors and scales pins that have had either of these changed due to data loading delays
-function Module:UpdateNext()
-  --print('|cFF00FF88UpdateNext()')
-  local pin = tremove(db.UpdatedPins)
-    pin:CheckFilterRules()
-
-  local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
-  --print(pin.title, pin.dataLoaded  and not pin.filtered, scaleFactor)
-  if pin.used then
-    pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
-    pin:OnShow()
-  end
-
-
-end
-
-function Module:Debug(...)
-  print(...)
+  artifactPowerDirty = nil
 end
 
 local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF'
-local lastRefresh
 function Module:Refresh(...)
-  --
-
   if not self:IsVisible() then
     print('|cFFFF4400Refresh()|r', ...)
     --layoutDirty = true
@@ -482,7 +406,9 @@
   end
   --]]
 
-
+  if artifactPowerDirty and not InCombatLockdown() then
+    self:UpdateArtifactPower()
+  end
   -- calculate quests shown
   numShown = 0
   numLoaded = 0
@@ -510,19 +436,16 @@
       pin.hideReason = "Not used in map area " .. (db.currentMapID)
       pin:SetShown(false)
     end
+
   end
-
-
   --print('flags ', layoutDirty, self.isStale)
   --print(' ', numShown, 'shown,', numLoaded, 'with data')
-  if numShown > numLoaded then
-    self.Status:Show()
-  end
+
 
 --
-    self.refreshBenchMark = GetTime()
-    self.refreshBenchMarkTicker = 2
-    print('starting bench', self.refreshBenchMark)
+  self.refreshBenchMark = GetTime()
+  self.refreshBenchMarkTicker = 2
+  print('starting bench', self.refreshBenchMark)
 
 --
 
@@ -531,9 +454,13 @@
   self.sizesDirty = nil
   self.isZoomDirty = nil
 
+  if WorldPlanSummary then
+    WorldPlanSummary.isStale = true
+  end
+
+  WorldPlan.dataFlush = true
 end
 
-local refreshReason
 function Module:RefreshIfChanged(event)
   local scaleCheck = WorldMapDetailFrame:GetScale()
   refreshReason = nil
@@ -548,7 +475,6 @@
     return
   end
 
-
   if self:IsVisible() then
     print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
     self:Refresh(event)
@@ -558,7 +484,7 @@
   end
 end
 
--- update visibility states of all pins
+-- marks a pin set for passive update
 function Module:MarkAllPins(pins)
   --print('  |cFFFFFF00'..self:GetName()..':MarkAllPins()|r', pins)
   pins = pins or db.QuestsByID
@@ -568,44 +494,7 @@
   end
 end
 
--- Updates quest markers in taskInfo while associating them with the given map
-function Module:UpdateQuestsForMap(taskInfo, mapID)
-  print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty)
-  if db.QuestsByZone[mapID] then
-    wipe(db.QuestsByZone[mapID])
-  end
-
-
-  for index, info in pairs(taskInfo) do
-
-    local questID, x, y = info.questId, info.x, info.y
-    local pin = self:AcquirePin(info)
-
-    if pin then
-      pin.used = true
-      print(pin.title, pin.isStale, layoutDirty, (pin.owningFrame ~= WorldMapFrame))
-      if pin:IsShown() and (layoutDirty or pin.isStale or (pin.owningFrame ~= WorldMapFrame)) then
-        local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
-        pin.owningFrame = WorldMapFrame
-        pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
-        if pin.isStale then
-          pin:Refresh('WORLDMAP_REFRESH ' .. GetTime())
-        end
-      else
-        if layoutDirty then
-          pin.isStale = true
-        end
-      end
-
-      if db.QuestsByZone[mapID] and pin.used then
-        db.QuestsByZone[mapID][questID] = pin
-      end
-
-    end
-  end
-end
-
--- Used to refresh the visible quest markers
+-- Walks the current map tree and fires updates as needed
 function Module:UpdateAnchors ()
   wipe(self.UsedPositions)
   print('  |cFF00FF00'..self:GetName()..':UpdateAnchors()')
@@ -616,7 +505,6 @@
     layoutDirty = true
   end
 
-
   --rprint('|cFF00FF00'..self:GetName()..':UpdateAnchors()')
   local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
   if isMicroDungeon then
@@ -643,11 +531,112 @@
   end
 end
 
-function ToggleButton:OnShow()
-  self:SetChecked(db.Config.EnablePins and true or false)
+-- Applies map association to the pins corresponding with each TaskInfo item
+function Module:UpdateQuestsForMap(taskInfo, mapID)
+  print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty)
+  if db.QuestsByZone[mapID] then
+    wipe(db.QuestsByZone[mapID])
+  elseif db.isBrokenIsle then
+    continentScanned = true
+  end
+
+  for index, info in pairs(taskInfo) do
+    local questID, x, y = info.questId, info.x, info.y
+    local pin = self:AcquirePin(info)
+
+    if pin then
+      pin.used = true
+      print(pin.title, pin.isStale, layoutDirty, (pin.owningFrame ~= WorldMapFrame))
+      if pin:IsShown() and (layoutDirty or pin.isStale or (pin.owningFrame ~= WorldMapFrame)) then
+        local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1]
+        pin.owningFrame = WorldMapFrame
+        pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
+        if pin.isStale then
+          pin:Refresh('WORLDMAP_REFRESH ' .. GetTime())
+        end
+      else
+        if layoutDirty then
+          pin.isStale = true
+        end
+      end
+
+      if db.QuestsByZone[mapID] and pin.used then
+        db.QuestsByZone[mapID][questID] = pin
+      end
+    end
+  end
 end
-function ToggleButton:OnClick()
-  --print(self:GetChecked())
-  db.Config.EnablePins = self:GetChecked()
-  _G.WorldPlan:OnConfigUpdate()
+
+-- locates or creates a corresponding pin frame for the provided TaskInfo data
+function Module:AcquirePin (info)
+  local questID = info.questId
+  if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then
+    return nil
+  end
+
+  local pin = db.QuestsByID[questID]
+  if not pin then
+    local numFree = #db.FreePins
+    if numFree >= 1 then
+      pin = tremove(db.FreePins, numFree)
+      print('|cFF00FF00Re-using', pin:GetName())
+    else
+      totalPins = totalPins + 1
+      local name = 'WorldPlanQuestMarker' .. numOverlays
+      print('|cFF00FF00Creating', name)
+      pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
+
+      pin:SetID(totalPins)
+      numOverlays = numOverlays + 1
+      --pin.iconBorder:SetVertexColor(0,0,0,1)
+    end
+    pin.questID = questID
+    pin.worldQuest = true
+    pin.throttle = pin.updateRate
+    pin.isNew = true
+    pin.currentWidth = nil
+    db.QuestsByID[questID] = pin
+    tinsert(db.UsedPins, pin)
+  end
+
+  if IsQuestComplete(questID) then
+    pin:Release()
+    return nil
+  elseif info then
+    pin.inProgress = info.inProgress
+    pin.floor = info.floor
+    pin.numObjectives = info.numObjectives or 0
+    if info.x and info.y then
+      if (info.x ~= pin.x) or (info.y ~= pin.y) then
+        pin.isStale = true
+        --rprint('|cFFFF4400SetCoords|r', info.x, info.y)
+      end
+    end
+  end
+
+  pin.x = info.x or pin.x
+  pin.y = info.y or pin.y
+
+  if not HaveQuestRewardData(questID) then
+    TQ_RequestPreloadRewardData(questID);
+  end
+
+  if (not pin.dataLoaded) then
+    local dataLoaded = pin:GetData()
+    if dataLoaded then
+      WorldPlan.dataFlush = true
+    else
+      isDataLoaded = false
+    end
+  end
+
+  pin.isActive = TQ_IsActive(questID)
+  pin:GetCriteriaState()
+  pin:CheckFilterRules()
+  --rprint(pin:GetID(), pin.filtered, pin.used)
+  return pin
+end
+
+function Module:Debug(...)
+  print(...)
 end
\ No newline at end of file