view ObjectiveCore.lua @ 7:5301c68f28d8

TrackerBlock - use IsModifiedClick function to determine appropriate OnClick actions - handle 'CHATLINK' modifier - handle 'TOGGLEQUESTWATCH' modifier TrackerBlockObjectives - use a generic framework to manage frame creation for various criteria tracker types: - ProgressBar when Blizzard flag data indicates so - skip when Blizzard flag data indicates so - DynamicText otherwise - events related to the criteria are registered in the criteria frame, and unregistered when the frame is hidden, either by destruction of its parent or completion
author Nenue
date Fri, 01 Apr 2016 12:27:05 -0400
parents 589de8ea05b9
children 7923243ae972
line wrap: on
line source
--- ${PACKAGE_NAME}
-- @file-author@
-- @project-revision@ @project-hash@
-- @file-revision@ @file-hash@
-- Created: 3/26/2016 1:51 AM
local B = select(2,...).frame
local wipe, pairs, ipairs, min, max, unpack = table.wipe, pairs, ipairs, min, max, unpack
local setmetatable, type = setmetatable, type
local GetNumQuestLeaderBoards, GetAchievementNumCriteria, GetQuestLogLeaderBoard, GetAchievementCriteriaInfo = GetNumQuestLeaderBoards, GetAchievementNumCriteria, GetQuestLogLeaderBoard, GetAchievementCriteriaInfo
local GetQuestLogIndexByID, GetSuperTrackedQuestID, SetSuperTrackedQuestID, GetQuestWatchInfo = GetQuestLogIndexByID, GetSuperTrackedQuestID, SetSuperTrackedQuestID, GetQuestWatchInfo
local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
local print = B.print('Objectives')
local ObjectiveTrackerFrame = ObjectiveTrackerFrame

--[[
  Full quest info is available if:
    - It's in the player quest log, or is available from the Gossip interface
    - It's being shared from another player and is acceptible
    - It's an auto-quest that is available in the current location
  Partial quest info is availabe if:
    - It's already completed (i.e. it appears in CompletedQuestInfo()).
    - It's an scheduled interval quest (daily, weekly, etc.)
    - It's contained in a quest link received from chat
  Under any other circumstances, only minimal info can be pulled:
    - Its availability to the player
    - Its relation with the currently engaged NPC
    - Its binary completion status

]]
--- Global Frames
local Wrapper = _G.VeneerObjectiveWrapper
local Scroller = Wrapper.scrollArea
local Scroll = _G.VeneerObjectiveScroll

--- list used to make things happen
mod.orderedNames = {[1] = 'AutoQuest',  [2] = 'Quest', [3] = 'Cheevs'}

--- ipairs() list of handlers for wrapper update
mod.orderedHandlers = {}
mod.orderedTrackers = {}
mod.indexedTrackers = {}
--- pairs() list of handler frames for tracker updates
mod.namedTrackers = {}

--- Handler stubs
mod.AutoQuest = {
  name = "AutoQuest"
}
mod.Quest = {
  name = "Quest"
}
mod.Cheevs = {
  name = "Cheevs"
}


--- Temp values set during updates
local wrapperWidth, wrapperHeight
local scrollWidth, scrollHeight
local previousBlock
local currentBlock

local frame_guide_init = function(self)
  self.testU = self.testU or self:CreateTexture('TestU', 'OVERLAY', 'VnTestLine')
  self.testB = self.testB or self:CreateTexture('TestB', 'OVERLAY', 'VnTestLine')
  self.testL = self.testL or self:CreateTexture('TestL', 'OVERLAY', 'VnTestLine')
  self.testR = self.testR or self:CreateTexture('TestR', 'OVERLAY', 'VnTestLine')
end
local frame_guide = function(self, target)
  if not target then return end
  if target:IsDragging() then return end
  local thickness = 1
  local midX, midY = target:GetCenter()
  local width, height = target:GetWidth() * 1.5, target:GetHeight() * 1.5
  --print('frame', target:GetLeft(), target:GetTop(), target:GetRight(), target:GetBottom())
  self.testB:ClearAllPoints()
  self.testB:SetPoint('TOP', UIParent, 'BOTTOMLEFT', midX, target:GetBottom())
  self.testB:SetSize(width,thickness)

  self.testU:ClearAllPoints()
  self.testU:SetPoint('BOTTOM', UIParent, 'BOTTOMLEFT', midX, target:GetTop())
  self.testU:SetSize(width,thickness)

  self.testL:ClearAllPoints()
  self.testL:SetPoint('RIGHT', UIParent, 'BOTTOMLEFT', target:GetLeft(), midY)
  self.testL:SetSize(thickness,height)

  self.testR:ClearAllPoints()
  self.testR:SetPoint('LEFT', UIParent, 'BOTTOMLEFT', target:GetRight(), midY)
  self.testR:SetSize(thickness,height)
end

--- Handler template
local CreateHandler = function (self, name, index)
  print(self, name)
  local handler = setmetatable({}, {
    __tostring = function() return name end,
    __call = function (self) mod.UpdateTracker(self) end
  })
  if type(mod.orderedHandlers[index]) == 'table' then
    return mod.orderedHandlers[index]
  end

  print('take up locals first')
  local preset = {}
  for k,v in pairs(mod[name]) do
    preset[k] = true
    if type(v) == 'table' then
      handler[k] = {}
    else
      handler[k] = v
    end
  end

  print('resulting handler contents')
  for k, v in pairs(self) do
    if not handler[k] then
      if type(v) == 'table' then
        -- assume all tables to be local data; don't inherit or ref
        handler[k] = {}
      else
        handler[k] = mod.Tracker[k]
      end
    else
      print(name, 'has its own', k)
    end
  end
  print('|cFFFF4400'..tostring(name)..'|r:')
  for k, v in pairs(handler) do
    print(string.format("%24s %8s %s", (preset[k] and '|cFFFFFFFF' or '|cFFFFFF00') .. k .. '|r', type(v), tostring(v)))
  end
  mod[name] = handler
  mod.orderedHandlers[index] = handler
  return true
end

mod.Tracker = setmetatable({}, {
  __call = CreateHandler,
  __tostring = function() return 'DEFAULT_TRACKING_HANDLER' end
})
local Tracker = mod.Tracker
Tracker.numWatched = 0   --- number of entries being handled
Tracker.numBlocks = 0    --- number of blocks created
Tracker.actualBlocks = 0 --- number of blocks in use

Tracker.freeBlocks = {}  --- block heap
Tracker.usedBlocks = {}

Tracker.Watched = {}     -- find by watchIndex
Tracker.Info = {}        -- find by data ID
Tracker.BlockInfo = {}   -- find by block ID
Tracker.LogInfo = {}     -- find by log ID (quest log mainly)
Tracker.WatchBlock = {}
Tracker.WatchInfo = {}
Tracker.LogBlock = {}



Tracker.GetBlock = function(handler, blockIndex)
  local block = handler.usedBlocks[blockIndex]
  if not handler.usedBlocks[blockIndex] then
    if #handler.freeBlocks >= 1 then
      block = handler.freeBlocks[#handler.freeBlocks]
      handler.freeBlocks[#handler.freeBlocks] = nil
    else
      block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, Scroll, 'VeneerTrackerBlock')
      block.SetStyle = mod.SetBlockStyle
      block:ClearAllPoints() -- making sure the anchors are clear in case they get added for some other template usage
    end

    handler.usedBlocks[blockIndex] = block
  end
  return handler.usedBlocks[blockIndex]
end

function mod:OnInitialize()
  self.InitializeTrackers()
  self.InitializeXPTracker()
  mod.SetEvents()
  ObjectiveTrackerFrame:UnregisterAllEvents()
  ObjectiveTrackerFrame:Hide()
end

--[[
QUESTLINE_UPDATE	This event is not yet documented
QUESTTASK_UPDATE	This event is not yet documented
QUEST_ACCEPTED	Fires when a new quest is added to the player's quest log (which is what happens after a player accepts a quest).
QUEST_ACCEPT_CONFIRM	Fires when certain kinds of quests (e.g. NPC escort quests) are started by another member of the player's group
QUEST_AUTOCOMPLETE	Fires when a quest is automatically completed (remote handin available)
QUEST_BOSS_EMOTE	This event is not yet documented
QUEST_CHOICE_CLOSE	This event is not yet documented
QUEST_CHOICE_UPDATE	This event is not yet documented
QUEST_COMPLETE	Fires when the player is looking at the "Complete" page for a quest, at a questgiver.
QUEST_DETAIL	Fires when details of an available quest are presented by a questgiver
QUEST_FINISHED	Fires when the player ends interaction with a questgiver or ends a stage of the questgiver dialog
QUEST_GREETING	Fires when a questgiver presents a greeting along with a list of active or available quests
QUEST_ITEM_UPDATE	Fires when information about items in a questgiver dialog is updated
QUEST_LOG_UPDATE	Fires when the game client receives updates relating to the player's quest log (this event is not just related to the quests inside it)
QUEST_POI_UPDATE	This event is not yet documented
QUEST_PROGRESS	Fires when interacting with a questgiver about an active quest
QUEST_REMOVED	This event is not yet documented
QUEST_TURNED_IN	Fired when a quest is turned in
QUEST_WATCH_LIST_CHANGED	This event is not yet documented
QUEST_WATCH_OBJECTIVES_CHANGED	This event is not yet documented
QUEST_WATCH_UPDATE	Fires when the player's status regarding a quest's objectives changes, for instance picking up a required object or killing a mob for that quest. All forms of (quest objective) progress changes will trigger this event.]

TRACKED_ACHIEVEMENT_LIST_CHANGED	This event is not yet documented
TRACKED_ACHIEVEMENT_UPDATE	Fires when the player's progress changes on an achievement marked for watching in the objectives tracker
 ]]