# HG changeset patch # User Nenue # Date 1459488642 14400 # Node ID 589de8ea05b9aeecbad7bcdb66d486ebae2e30f2 # Parent e9b61fd5f607935fc0c89b4588adb3f2ad5edf5b - validate tracked objects' existence by use of those handler.Info tables we made - apply collision checking to action buttons when their corresponding entry has scrolled out diff -r e9b61fd5f607 -r 589de8ea05b9 ObjectiveCore.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveCore.lua Fri Apr 01 01:30:42 2016 -0400 @@ -0,0 +1,209 @@ +--- ${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 + ]] \ No newline at end of file diff -r e9b61fd5f607 -r 589de8ea05b9 ObjectiveEvents.lua --- a/ObjectiveEvents.lua Thu Mar 31 15:58:08 2016 -0400 +++ b/ObjectiveEvents.lua Fri Apr 01 01:30:42 2016 -0400 @@ -7,8 +7,78 @@ local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local print = B.print('ObjectiveEvent') +local isHooked +local SmallEvents = { + QUEST_ACCEPTED = 'OnQuestAccepted', + QUEST_REMOVED = 'OnQuestRemoved' +} + +local HandlerEvents = { + QUEST_ACCEPTED = mod.Quest, + QUEST_REMOVED = mod.Quest, + QUEST_WATCH_LIST_CHANGED = mod.Quest, + SUPER_TRACKED_QUEST_CHANGED = mod.Quest, + QUEST_LOG_UPDATE = mod.Quest, + TRACKED_ACHIEVEMENT_LIST_CHANGED = mod.Cheevs, + TRACKED_ACHIEVEMENT_UPDATE = mod.Cheevs +} + +local BlizzHooks = { + ['AddQuestWatch'] = 'AddQuestWatch', + ['RemoveQuestWatch'] = 'RemoveQuestWatch', + ['AbandonQuest'] = 'AbandonQuest', + ['AcknowledgeAutoAcceptQuest'] = 'AcknowledgeAutoAcceptQuest', + ['AddAutoQuestPopUp'] = 'AddAutoQuestPopUp' +} + +mod.SetEvents = function() + + for event, _ in pairs(SmallEvents) do + mod:RegisterEvent(event) + end + + for event, _ in pairs(HandlerEvents) do + mod:RegisterEvent(event) + end + mod:SetScript('OnEvent', mod.OnEvent) + + + if not isHooked then + VeneerData.CallLog = {} + isHooked = true + for blizzFunc, veneerFunc in pairs(BlizzHooks) do + if mod[veneerFunc] then + hooksecurefunc(blizzFunc, mod[veneerFunc]) + else + hooksecurefunc(blizzFunc, function(...) + print('catching', blizzFunc, ...) + tinsert(VeneerData.CallLog, {blizzFunc, ...}) + end) + end + end + + end +end + +function mod:OnEvent (event, ...) + local isHandled + if SmallEvents[event] then + print('|cFF00FF00'..SmallEvents[event]..'(' ..event..'|r', ...) + mod[SmallEvents[event]](event, ...) + isHandled = true + end + if HandlerEvents[event] then + print('|cFF0088FF'..event..'|r wrapper update') + mod.UpdateWrapper() + isHandled = true + end + if not isHandled then + print('|cFFFF4400'..event..'|r', ...) + end +end + -------------------------------------------------------------------- ---- Specialized event handlers +--- Events that are handled by Blizzard_ObjectiveTracker -------------------------------------------------------------------- print(mod:GetName()) mod.OnQuestAccepted = function(_, questLogIndex, questID) @@ -25,11 +95,31 @@ RemoveQuestWatch(questLogIndex) end + mod.OnQuestRemoved = function(_, questLogIndex, questID) + + mod.UpdateWrapper() + end mod.OnQuestFromLocation = function(event) end -mod.OnAddQuestWatch = function(questID) - mod.UpdateActionButtons() +------------------------------------------------------------------- +--- Function hooks for BlizzUI compatibility +------------------------------------------------------------------- +mod.AddQuestWatch = function(questID) + mod.UpdateWrapper() end + +mod.RemoveQuestWatch = function(questIndex) + mod.UpdateWrapper() +end + +mod.AcceptQuest = function() +end + +mod.AbandonQuest = function() +end + +mod.TurnInQuest = function() +end \ No newline at end of file diff -r e9b61fd5f607 -r 589de8ea05b9 ObjectiveFrame.lua --- a/ObjectiveFrame.lua Thu Mar 31 15:58:08 2016 -0400 +++ b/ObjectiveFrame.lua Fri Apr 01 01:30:42 2016 -0400 @@ -27,6 +27,7 @@ local previousBlock local currentBlock --- todo: map these into config table when its sorted out +local itemButtonSize, itemButtonSpacing = 36, 1 local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]] local titleSize, textSize = 15, 15 local titleOutline, textOutline = "OUTLINE", "OUTLINE" @@ -46,7 +47,7 @@ ObjectiveWrapperParent = '', WrapperStyle = { Header = { - Background = {Left = [[Objective-Header]], Right = [[Objective-Header]], Tile = [[Objective-Header]]}, + Background = {Left = '', Right = '', Tile = ''}, BackgroundCrop = {Left = {0, 0.4, 0,1}, Right={0.6,1,0,1}, Tile = {0.4,.6,0,1,}}, BackgroundScale = {Left = 100, Right = 100}, Font = {wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline} @@ -54,18 +55,18 @@ }, ObjectiveHeaderStyle = { Normal = { - Gradient = {MinColor = {0,0,0,0.5}, MaxColor = {0,0,0,.25}}, + Gradient = {MinColor = {.05,.15,0.5,0.7}, MaxColor = {.05,.15,0.5,.35}}, Font = {headerFont, headerSize, headerOutline}, Spacing = headerSpacing, } }, ObjectiveTrackerStyle = { Normal = { Title = { - Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, 0}}, + Gradient = { MinColor = {0.2, .4, 1, 0.45}, MaxColor = {.7, 0, 0.9, .19}}, Font = {titleFont, titleSize, titleOutline}, Spacing = titleSpacing, }, Text = { - Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, 0}}, + Gradient = { MinColor = {0.2, .4, 1, 0.25}, MaxColor = {.7, 0, 0.9, .12}}, Font = {textFont, textSize, textOutline}, Spacing = textSpacing, }, }, @@ -146,7 +147,7 @@ self:SetVerticalScroll(s) print(s, r, self:GetVerticalScroll()) - mod.UpdateActionButtons() + mod.UpdateActionButtons('SCROLLING') end local WrapperCloseButton_OnClick = function(self) @@ -205,52 +206,76 @@ end --- xp bar - XPBar:Show() - XPBar.rested:SetTexture(2,.6,1,1) - XPBar.fg:SetTexture(.3,.1,.95,1) - XPBar.bg:SetTexture(0,0,0,.25) - XPBar:RegisterEvent('PLAYER_XP_UPDATE') - XPBar:RegisterEvent('PLAYER_LEVEL_UP') - XPBar:RegisterEvent('PLAYER_UPDATE_RESTING') + XPBar:SetWidth(wrapperWidth - Wrapper.close:GetWidth()) + XPBar.bg:SetAllPoints(XPBar) + XPBar:RegisterEvent('DISABLE_XP_GAIN') + XPBar:RegisterEvent('ENABLE_XP_GAIN') XPBar:SetScript('OnEvent', mod.UpdateXP) - mod.UpdateXP(Wrapper.xpBar) + + if not IsXPUserDisabled() then + mod.EnableXP(XPBar) + else + mod.DisableXP(XPBar) + end + + mod.UpdateXP(XPBar) end -mod.UpdateXP = function() - local XPBar = Wrapper.XPBar - local xp = UnitXP('player') - local xpmax = UnitXPMax('player') - local rest = GetXPExhaustion() +mod.EnableXP = function(self) + self:RegisterEvent('PLAYER_XP_UPDATE') + self:RegisterEvent('PLAYER_LEVEL_UP') + self:RegisterEvent('PLAYER_UPDATE_RESTING') + self.bg:SetTexture(0,0,0,.25) + self:Show() +end - XPBar.bg:SetAllPoints(XPBar) - XPBar.fg:SetWidth((xp/xpmax) * XPBar:GetWidth()) +mod.DisableXP = function(self) + self:UnregisterEvent('PLAYER_XP_UPDATE') + self:UnregisterEvent('PLAYER_LEVEL_UP') + self:UnregisterEvent('PLAYER_UPDATE_RESTING') + self.bg:SetTexture(0.5,0.5,0.5,0.5) + self:Hide() +end - if IsResting() then - XPBar.bg:SetTexture(.2,.8,.2,.5) - else - XPBar.bg:SetTexture(0,0,0,.25) +mod.UpdateXP = function(self, event) + if event == 'DISABLE_XP_GAIN' then + mod.DisableXP(self) + elseif event == 'ENABLE_XP_GAIN' then + mod.EnableXP(self) end - if rest then - XPBar.rested:ClearAllPoints() - if xp == 0 then - XPBar.rested:SetPoint('TOPLEFT', XPBar, 'TOPLEFT', 0, 0) + if not IsXPUserDisabled() then + + local xp = UnitXP('player') + local xpmax = UnitXPMax('player') + local rest = GetXPExhaustion() + self.fg:SetWidth((xp/xpmax) * self:GetWidth()) + if rest then + self.rested:ClearAllPoints() + if xp == 0 then + self.rested:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0) + else + self.rested:SetPoint('TOPLEFT', self.fg, 'TOPRIGHT', 0, 0) + end + + if (xp + rest) > xpmax then + self.rested:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, 0) + else + self.rested:SetWidth((rest/xpmax) * self:GetWidth()) + end + self.rested:SetPoint('BOTTOM', self, 'BOTTOM') + self.rested:Show() else - XPBar.rested:SetPoint('TOPLEFT', XPBar.fg, 'TOPRIGHT', 0, 0) + self.rested:Hide() end - if (xp + rest) > xpmax then - XPBar.rested:SetPoint('BOTTOMRIGHT', XPBar, 'BOTTOMRIGHT', 0, 0) + if IsResting() then + self.bg:SetTexture(.2,.8,.2,.5) else - XPBar.rested:SetWidth((rest/xpmax) * XPBar:GetWidth()) + self.bg:SetTexture(0,0,0,.25) end - XPBar.rested:SetPoint('BOTTOM', XPBar, 'BOTTOM') - XPBar.rested:Show() - else - XPBar.rested:Hide() + self.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or '')) end - - XPBar.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or '')) end mod.UpdateReputation = function(self) @@ -415,6 +440,11 @@ --info.itemButton = nil end + if Devian and Devian.InWorkspace() then + t.debugText:Show() + t.debugText:SetText(tostring(blockIndex) .. '\n' .. tostring(info.itemButton and info.itemButton:GetName())) + end + --- metrics are calculated in SetStyle t:SetStyle(style) t:Show() @@ -598,69 +628,109 @@ Wrapper:SetSize(wrapperWidth, wrapperHeight + headerHeight) -- update action buttons + print('|cFF00FF00'..Scroll:GetName()..'|r:', Scroll:GetWidth(), Scroll:GetHeight(), + '|cFF00FF00'..Scroller:GetName()..'|r:', Scroller:GetWidth(), Scroller:GetHeight(), + '|cFF00FF00'..Wrapper:GetName()..'|r:', Wrapper:GetWidth(), Wrapper:GetHeight(), + '|cFF0088FFvScrollRange|r:', floor(Scroller:GetVerticalScrollRange()+.5) + ) + mod.UpdateActionButtons('FULL_UPDATE') - - print('scroll size:', Scroll:GetSize()) - print('scroller size:',Scroller:GetSize()) - print('wrapper size:', Wrapper:GetSize()) - print('scroll range :', floor(Scroller:GetVerticalScrollRange()+.5)) - - - mod.UpdateActionButtons() + QuestPOIUpdateIcons() end --- Queue any active item buttons for update for that frame -mod.UpdateActionButtons = function() +mod.UpdateActionButtons = function(updateReason) + Scroller.snap_upper = 0 + Scroller.snap_lower = 0 + local print = B.print('ItemButton') + if updateReason then + print = B.print('IB_'..updateReason) + end + local previousItem for questID, itemButton in pairs(usedButtons) do - local questIndex = mod.Quest.Info[questID].questLogIndex + local info= mod.Quest.Info[questID] + print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName()) local block = mod.Quest.QuestBlock[questID] if block then -- Dispatch the probe - if IsQuestWatched(questIndex) then - + if IsQuestWatched(info.questLogIndex) then + itemButton.previousItem = previousItem print(' |cFFFFFF00probing', block:GetName()) block:SetScript('OnUpdate', function() if block:GetBottom() and not InCombatLockdown() then print(' '..block:GetName()..' |cFF00FF00probe hit!') - mod.UpdateBlockAction(block, itemButton, previousItem) + mod.UpdateBlockAction(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope block:SetScript('OnUpdate', nil) end end) + previousItem = itemButton else print('hidden block or unwatched quest') + itemButton.previousItem = nil itemButton:Hide() end else print(' |cFFFF0088missing block data', itemButton:GetName()) + itemButton.previousItem = nil + itemButton:Hide() end end end -mod.UpdateBlockAction = function (block, itemButton, previousItem) +mod.UpdateBlockAction = function (block, itemButton) print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()') if itemButton.questID ~= block.info.questID then print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID) - + -- something happened between this and last frame, go back and set new probes return mod.UpdateActionButtons() end - if block:GetBottom() < Scroller:GetBottom() then - print('** ',block:GetName() ,'|cFFFFFF00bottom not fully visible') + local previousItem = itemButton.previousItem + local upper_bound = Scroller:GetTop() + Scroller.snap_upper + local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize + local point, anchor, relative + + if block:GetBottom() < lower_bound then + print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5)) if previousItem then + print('adjusting', previousItem:GetName()) previousItem:ClearAllPoints() - previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, 4) + previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing) end itemButton:ClearAllPoints() - itemButton:SetPoint('BOTTOMRIGHT', UIParent, 'BOTTOMLEFT', Wrapper:GetLeft(), Wrapper:GetBottom()) + itemButton.x = Wrapper:GetLeft() -4 + itemButton.y = Wrapper:GetBottom() + point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT' + Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing + + elseif block:GetTop() > upper_bound then + print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5)) + itemButton:ClearAllPoints() + if previousItem then + print('latch onto another piece') + point, anchor, relative ='TOP', previousItem, 'BOTTOM' + itemButton.x = 0 + itemButton.y = -itemButtonSpacing + else + print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop()) + point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' + itemButton.x = Scroller:GetLeft() -4 + itemButton.y = Scroller:GetTop() + end itemButton:Show() + Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing) else - print('** ',block:GetName() ,'|cFF00FF00visible positions') + print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5)) itemButton:ClearAllPoints() - itemButton:SetPoint('TOPRIGHT', UIParent, 'BOTTOMLEFT', block:GetLeft(), block:GetTop()) - itemButton:Show() + itemButton.x = block:GetLeft() - itemButtonSpacing + itemButton.y = block:GetTop() + point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' end + + itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y) + itemButton:Show() end mod.UpdateItemButtonCooldown = function(button) diff -r e9b61fd5f607 -r 589de8ea05b9 ObjectiveInfo.lua --- a/ObjectiveInfo.lua Thu Mar 31 15:58:08 2016 -0400 +++ b/ObjectiveInfo.lua Fri Apr 01 01:30:42 2016 -0400 @@ -121,6 +121,11 @@ end end +AutoQuest.GetInfo = function(watchIndex) + return Quest.GetInfo(watchIndex) +end + + Cheevs.GetNumWatched = function(self) Cheevs.trackedCheevs = {GetTrackedAchievements()} return GetNumTrackedAchievements() diff -r e9b61fd5f607 -r 589de8ea05b9 ObjectiveTracker.lua --- a/ObjectiveTracker.lua Thu Mar 31 15:58:08 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,253 +0,0 @@ ---- ${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 -local SmallEvents = { - QUEST_ACCEPTED = 'OnQuestAccepted', - QUEST_REMOVED = 'OnQuestRemoved' -} - -local HandlerEvents = { - QUEST_ACCEPTED = mod.Quest, - QUEST_REMOVED = mod.Quest, - QUEST_WATCH_LIST_CHANGED = mod.Quest, - SUPER_TRACKED_QUEST_CHANGED = mod.Quest, - QUEST_LOG_UPDATE = mod.Quest, - TRACKED_ACHIEVEMENT_LIST_CHANGED = mod.Cheevs, - TRACKED_ACHIEVEMENT_UPDATE = mod.Cheevs -} - -function mod:OnEvent (event, ...) - local isHandled - if SmallEvents[event] then - print('|cFF00FF00'..SmallEvents[event]..'(' ..event..'|r', ...) - mod[SmallEvents[event]](event, ...) - isHandled = true - end - if HandlerEvents[event] then - print('|cFF0088FF'..event..'|r wrapper update') - mod.UpdateWrapper() - isHandled = true - end - if not isHandled then - print('|cFFFF4400'..event..'|r', ...) - end -end - -mod.SetEvents = function() - - for event, _ in pairs(SmallEvents) do - mod:RegisterEvent(event) - end - - for event, _ in pairs(HandlerEvents) do - mod:RegisterEvent(event) - end - mod:SetScript('OnEvent', mod.OnEvent) -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 - ]] \ No newline at end of file diff -r e9b61fd5f607 -r 589de8ea05b9 ObjectiveTracker.xml --- a/ObjectiveTracker.xml Thu Mar 31 15:58:08 2016 -0400 +++ b/ObjectiveTracker.xml Fri Apr 01 01:30:42 2016 -0400 @@ -44,28 +44,9 @@ - - - + + + @@ -299,7 +285,7 @@ -