Mercurial > wow > worldplan
changeset 40:589c444d4837
WowAce/Curseforge migration push
author | Nenue |
---|---|
date | Sun, 25 Dec 2016 13:04:57 -0500 |
parents | 89ddef0594bc |
children | 79e5e96e5f18 |
files | ClassPlan.lua ClassPlan.xml ClassPlanFollowers.lua ClassPlanFollowers.xml ClassPlanMissions.lua ClassPlanMissions.xml ClassPlanShipments.lua ClassPlanShipments.xml FilterBar.lua FilterBar.xml FlightMap.lua FlightMap.xml QuestPOI.lua WorldPlan.lua WorldPlan.xml WorldQuests.lua |
diffstat | 16 files changed, 2168 insertions(+), 1336 deletions(-) [+] |
line wrap: on
line diff
--- a/ClassPlan.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlan.lua Sun Dec 25 13:04:57 2016 -0500 @@ -1,3 +1,4 @@ +local _, db = ... local wipe, tinsert, sort = table.wipe, tinsert, table.sort local pairs, ipairs = pairs, ipairs local floor, mod, time = floor, mod, time @@ -6,20 +7,25 @@ local GI_currentTime = time() local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop -local CG_GetBuildings = C_Garrison.GetBuildings -local CG_GetFollowerShipments = C_Garrison.GetFollowerShipments -local CG_GetLooseShipments = C_Garrison.GetLooseShipments -local CG_GetTalentTrees = C_Garrison.GetTalentTrees -local CG_GetCompleteTalent = C_Garrison.GetCompleteTalent -local CG_GetLandingPageShipmentInfo = C_Garrison.GetLandingPageShipmentInfo -local CG_GetLandingPageShipmentInfoByContainerID = C_Garrison.GetLandingPageShipmentInfoByContainerID - local CP_REPLACE_LANDINGPAGE = true local CP_HEADER_SIZE = 24 -local CP_BACKGROUND_COLOR = { - inProgress = {0, 0, 0, 0.5}, - shipmentsReady = {0, 0, 0, 0.25}, - complete = {0.5, 0.5, 0.5, 0.5} +db.ClassPlanDefaultType = { + + backgroundColor = {0, 0, 0, 0.5}, + textColor = {1,1,1,1} +} +db.ClassPlanTypes = setmetatable({}, {__index = db.ClassPlanDefaultType}) +db.ClassPlanTypes.inProgress = { + backgroundColor = {0, 0, 0, 0.5}, + textColor = {1,1,1} +} +db.ClassPlanTypes.shipmentsReady = { + backgroundColor = {1, 1, 0, 0.25 }, + textColor = {1, 1, 0} +} +db.ClassPlanTypes.complete = { + backgroundColor = {0, 1, 0, 0.25 }, + textColor = {0, 1, 0} } local GetTimeLeftString = function(timeLeft) @@ -34,7 +40,6 @@ end end - ClassOrderPlanCore = { events = {}, freeBlocks = {}, @@ -45,61 +50,72 @@ shipments = {}, playerFirst = false, prototypes = {}, - Queued = {} + Queued = {}, + Timers = {}, + ReportChunks = {}, } -local MissionList = { - templateName = 'ClassPlanMissionEntry', - listKey = {'missions', 'available'}, - listTitle = {'In Progress', 'Available'}, - - point = 'TOPLEFT', - relativePoint ='TOPLEFT', - events = { - 'GARRISON_MISSION_LIST_UPDATE', - 'GARRISON_LANDINGPAGE_SHIPMENTS'}, -} -local ShipmentList = { - templateName = 'ClassPlanShipmentEntry', - listKey = {'shipments'}, - listTitle = {'Work Orders'}, - events = { - 'GARRISON_MISSION_LIST_UPDATE', - 'GARRISON_LANDINGPAGE_SHIPMENTS', - 'GARRISON_TALENT_UPDATE', - "GARRISON_TALENT_COMPLETE", - "GARRISON_SHIPMENT_RECEIVED", - 'GARRISON_FOLLOWER_LIST_UPDATE', - 'GARRISON_SHOW_LANDING_PAGE'}, -} -local SharedHandlers = { +ClassPlanHandlerBase = { numBlocks = 0, isStale = true, maxItems = 10 } -local SharedEntry = {} -local ShipmentEntry = {} -local MissionEntry = {} +ClassPlanEntryBase = {} local ClassPlan = ClassOrderPlanCore +local Embed = function(object, ...) + for i = 1, select('#', ...) do + local src = select(i, ...) + for k,v in pairs(src) do + if not object[k] then + object[k] = v + end + end + end + return object +end function ClassPlan:OnLoad () self:RegisterEvent('PLAYER_LOGIN') self:RegisterEvent('ADDON_LOADED') self:RegisterEvent('PLAYER_REGEN_ENABLED') self:RegisterEvent('PLAYER_REGEN_DISABLED') + self:RegisterEvent('GARRISON_SHOW_LANDING_PAGE') self:RegisterForDrag('LeftButton') self:SetMovable(true) self:SetToplevel(true) - SLASH_CLASSPLAN1 = "/classplan" SLASH_CLASSPLAN2 = "/cp" SlashCmdList.CLASSPLAN = function(args) self:Toggle() end + local originalScript = GarrisonLandingPageMinimapButton:GetScript('OnClick') + GarrisonLandingPageMinimapButton:SetScript("OnClick", function(minimap, button) + if button == 'LeftButton' and (not IsShiftKeyDown()) then + self:Toggle() + else + originalScript(minimap, button) + end + end) + self.FadeOut:SetScript('OnFinished', function() + self:Hide() + self.data.IsShown = nil + self.isAnimating = nil + end) + self.FadeIn:SetScript('OnPlay', function() + self.isAnimating = true + self:SetShown(true) + end) + + --hooksecurefunc(C_Garrison, 'RequestLandingPageShipmentInfo', function() + -- WorldPlan:print("Requesting shipments data.") + --end) + C_Garrison.RequestLandingPageShipmentInfo(); + self.isStale = true end + function ClassPlan:GetCurrentProfile() WorldPlanData.OrderHall = WorldPlanData.OrderHall or {} local db = WorldPlanData.OrderHall @@ -110,38 +126,49 @@ local name, realm = UnitName('player') realm = realm or GetRealmName() + local profileName = name .. '-' .. realm - - self.profile = characters[profileName] or {} + self.profile = characters[profileName] or { + showItems = true + } self.characters = characters characters[profileName] = self.profile - local classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))] local className = UnitClass('player') - print('|cFFFFFF00Loaded:|r', classColor.hex, className, profileName) - self.Background:SetColorTexture(classColor.r, classColor.g, classColor.b, 0.5) self.profile.classColor = classColor self.profile.className = className self.profile.characterName = name self.profile.characterRealm = realm + -- flip it on + self.profile.showItems = true + + self.HeaderInset:SetHeight(CP_HEADER_SIZE) + self.ClassStripe:SetColorTexture(classColor.r, classColor.g, classColor.b, 1) + self.ClassStripe:SetPoint('TOPLEFT', self.HeaderInset, 'BOTTOMLEFT') + return self.profile end -function ClassPlan:SetupHandler(handler) - print('|cFF00FF00'..handler:GetName()..' loaded') - for i, event in ipairs(handler.events) do +function ClassPlan:AddHandler(frame) + print('|cFF00FF00'..frame:GetName()..' loaded') + for i, event in ipairs(frame.events) do print('|cFF00FF00 event', event) - handler:RegisterEvent(event) + frame:RegisterEvent(event) end - for index, listKey in ipairs(handler.listKey) do + frame.sortedItems = {} + for index, listKey in ipairs(frame.listKey) do + frame.profile = self.profile + frame.data = self.data self.profile[listKey] = self.profile[listKey] or {} - local listTitle = handler.listTitle[index] - setmetatable(self.profile[listKey], { __tostring = listTitle }) + local listTitle = frame.listTitle[index] + setmetatable(self.profile[listKey], { __tostring = function() return listTitle end }) + frame.sortedItems[listKey] = {} + end - handler:SetList(1) - handler.sortedItems = {} + frame.owningFrame = self + frame:SetList(1) end function ClassPlan:OnEvent (event, arg) @@ -165,6 +192,8 @@ if not self.initialized then self:Setup() end + elseif event == 'GARRISON_SHOW_LANDING_PAGE' then + self:RefreshData() end end @@ -174,120 +203,124 @@ self:GetCurrentProfile() for _, handler in ipairs(self.Handlers) do - self:SetupHandler(handler) + self:AddHandler(handler) + handler.initialized = true end self.initialized = true self:SetShown(self.data.IsShown) + + end end --- Update space - local max = math.max - function ClassPlan:Update() - print('|cFF00FFFFRefresh()|r') - self.currentHeight = 0 - for index, handler in pairs(self.Handlers) do - if handler.isStale then - print(' |cFF00FF00'..index..' '..handler:GetName()..'|r') - local sortedItems = handler.sortedItems - local activeKey = handler.activeKey +local max = math.max +function ClassPlan:RefreshData() + local detailsFailed + for index, handler in pairs(self.Handlers) do + print(' |cFF00FF00'..handler:GetName()..' data update|r') + handler:RefreshData() + end + if detailsFailed then + db.print('Unable to obtain player details. Trying again later.') + else + self.requestingData = nil + end +end - handler.profile = self.profile[handler.activeKey] - handler.currentTime = GI_currentTime - handler:GetPlayerData(self.profile) - wipe(sortedItems) - for key, profile in pairs(self.data.characters) do - print('profile', key, activeKey) - local profileList = profile[activeKey] - if profileList and #profileList >= 1 then - local classColor = profile.classColor or RAID_CLASS_COLORS['HUNTER'] - local isMine = (profile == self.profile) - for index, data in ipairs(profileList) do - data.classColor = classColor - data.profileKey = key - data.isMine = isMine - if handler.OnGetItem then - handler:OnGetItem(data) - end - tinsert(sortedItems, data) - end - end - end +function ClassPlan:Update() + print('|cFF00FFFF'..self:GetName()..'Refresh()|r') - if handler.SortHandler then - sort(sortedItems, handler.SortHandler) - end + self.currentHeight = 0 + for index, handler in ipairs(self.Handlers) do + local itemsHeight = handler:UpdateItems() + if itemsHeight then + self.currentHeight = max(itemsHeight, self.currentHeight) + end + end - end - handler.isStale = nil - local itemsHeight = handler:UpdateItems() - self.currentHeight = max(itemsHeight, self.currentHeight) - + local index = 1 + for key, info in pairs(self.data.characters) do + print('cbutton', key) + if self.data[key] then + print('|cFFFF4400remove legacy value', key) + self.data[key] = nil end - local index = 1 - for id, profile in pairs(self.data.characters) do - local button = self.characterButtons[index] - if not button then - button = CreateFrame('Button', nil, self, 'ClassOrderPlanCharacterButton') - button:SetID(index) - self.characterButtons[index] = button - if not self.lastButton then - button:SetPoint('BOTTOMLEFT', self, 'TOPLEFT', 0, 0) - else - button:SetPoint('BOTTOMLEFT', self.lastButton, 'BOTTOMRIGHT', 2, 0) - end - self.lastButton = button + local button = self.characterButtons[index] + if not button then + button = CreateFrame('Button', nil, self, 'ClassOrderPlanCharacterButton') + button:SetID(index) + self.characterButtons[index] = button + + if not self.lastButton then + button:SetPoint('TOPLEFT', self.HeaderInset, 'TOPLEFT', 0, 0) + else + button:SetPoint('TOPLEFT', self.lastButton, 'TOPRIGHT', 2, 0) end - if not profile.characterName then - profile.characterName, profile.characterRealm = id:match("%(.+)%-(.+)^") - end - - button.className = profile.className - button.classColor = profile.classColor - button.characterName = profile.characterName - button.characterRealm = profile.characterRealm - button.hideItems = (profile.showItems == false) and (profile ~= self.profile) - button.isMine = (profile == self.profile) - button:Update() - button:Show() - index = index + 1 + self.lastButton = button + end + if not info.characterName then + info.characterName, info.characterRealm = key:match("%(.+)%-(.+)^") end + print(info.characterName) - self.isStale = nil - self:Reanchor() - self:SetHeight(self.currentHeight + CP_HEADER_SIZE) + button:SetSize(CP_HEADER_SIZE, CP_HEADER_SIZE) + button.profileKey = key + button.className = info.className + button.classColor = info.classColor + button.characterName = info.characterName + button.characterRealm = info.characterRealm + button.showItems = info.showItems + button.isMine = (info == self.profile) + button:Update() + button:Show() + index = index + 1 end + self.HeaderInset:SetHeight(CP_HEADER_SIZE) + self.HeaderInset:ClearAllPoints() + self.HeaderInset:SetPoint('TOPLEFT' ,self, 'TOPLEFT') + self.HeaderInset:SetPoint('RIGHT' ,self, 'RIGHT') + self.ClassStripe:ClearAllPoints() + self.ClassStripe:SetPoint('TOPLEFT', self.HeaderInset, 'BOTTOMLEFT', 0, 0) + self.ClassStripe:SetPoint('RIGHT') + self:Reanchor() + self.isStale = nil +end + function ClassPlan:Toggle() if self:IsShown() then - self:Hide() + self.FadeOut:Play() else - self:Show() - end - - if self.data then - self.data.IsShown = self:IsShown() + self.data.IsShown = true + self.FadeIn:Play() end end + function ClassPlan:OnUpdate() - if self.isStale then - print('|cFFFF4400An illusion! What are you hiding?|r') + if self.requestingData then + self:RefreshData() + elseif self.isStale then + -- shouldn't happen, usually self:Update() end + if #self.ReportChunks >= 1 then + db.print(table.concat(self.ReportChunks, ', ')) + wipe(self.ReportChunks) + end + end function ClassPlan:OnShow() print('|cFF00FFFFShow()') - if self.isStale then - self:Update() - end + self.isStale = true self:Reanchor() end @@ -296,30 +329,34 @@ end function ClassPlan:Reanchor() + if not (self.data.positionX and self.data.positionY) then + self.data.positionX = 0 + self.data.positionY = -148 + end self:ClearAllPoints() - self:SetPoint('CENTER', self.data.positionX, self.data.positionY) - + self:SetPoint('TOP', self.data.positionX, self.data.positionY) + self.currentHeight = 0 for index, frame in ipairs(self.Handlers) do frame:Reanchor() - local ListTab = frame.ListTab if ListTab then ListTab:ClearAllPoints() - ListTab:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, CP_HEADER_SIZE) - ListTab:SetPoint('BOTTOMRIGHT', frame, 'TOPRIGHT', 0, 0) + ListTab:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0) + ListTab:SetPoint('BOTTOMRIGHT', frame, 'TOPRIGHT', 0, -CP_HEADER_SIZE) ListTab.Label:SetText(frame.listTitle[frame.currentListIndex]) ListTab:Show() print(ListTab:GetSize()) end + self.currentHeight = max(self.currentHeight, frame.currentHeight or 0) + end + self:SetHeight(self.currentHeight + self.HeaderInset:GetHeight() + self.ClassStripe:GetHeight()) - end end function ClassPlan:OnDragStart() self:StartMoving() end function ClassPlan:OnDragStop() - self:StopMovingOrSizing() local x,y = self:GetCenter() if x and y then @@ -330,7 +367,23 @@ end end -function SharedHandlers:SetList(index) +function ClassPlanHandlerBase:ScheduleUpdate(expires) + -- value will occasionally lag so check here + local duration = expires - time() + self.Timers = self.Timers or {} + if (duration > 0) and (not self.Timers[expires]) then + print(' adding timer at', expires, 'c', duration) + self.Timers[expires] = true + C_Timer.After(duration, function() + self.isStale = true + self:UpdateItems() + self.Timers[expires] = nil + end) + end +end + +function ClassPlanHandlerBase:SetList(index) + local prevIndex = self.currentListIndex if not index then if self.currentListIndex == #self.listKey then index = 1 @@ -339,57 +392,93 @@ end end - print('|cFF0088FF'..self:GetName()..'|r:SetList()', index) + print('|cFF0088FF'..self:GetName()..'|r:SetList()', index, self.listKey[index]) self.currentListIndex = index self.activeKey = self.listKey[index] self.activeTitle = self.listTitle[index] + self.ListTab.Label:SetText(self.listTitle[index]) self.isStale = true + + if self.OnSetList then + self:OnSetList(self.currentListIndex, prevIndex) + end end -function SharedHandlers:OnMouseWheel(delta) +function ClassPlanHandlerBase:OnMouseWheel(delta) self.scrollOffset = (self.scrollOffset or 0) - ((delta > 0) and 1 or -1) self:UpdateItems() end -function SharedHandlers:RequestData() - print('|cFF0088FF'..self:GetName()..':RequestData()') +function ClassPlanHandlerBase:RefreshData() + print('|cFF0088FF'..self:GetName()..':RefreshData()') + local activeKey = self.activeKey + local detailsFailed + self.truncatedItems = 0 + self.currentTime = time() + if self:GetParent().profile then + self:GetPlayerData() + else + detailsFailed = true + end + for _, listKey in ipairs(self.listKey) do + local sortedItems = self.sortedItems[listKey] + wipe(sortedItems) + for key, profile in pairs(self.data.characters) do + local isMine = (profile == self.profile) + print(key, listKey, isMine, profile.showItems) + local profileList = profile[listKey] + if profileList and #profileList >= 1 then + local classColor = profile.classColor or RAID_CLASS_COLORS['HUNTER'] + if profile.showItems then + for index, data in ipairs(profileList) do + data.classColor = classColor + data.profileKey = key + data.isMine = isMine + if self.OnGetItem then + self:OnGetItem(data) + end + tinsert(sortedItems, data) + end + else + self.truncatedItems = self.truncatedItems + 1 + end + end + end + + if self.SortHandler then + sort(sortedItems, self.SortHandler) + end + end + + for k,v in pairs(self.sortedItems) do + print(' ', k) + end + self.isStale = true end -function SharedHandlers:OnEvent(event, arg) - if (event == 'GARRISON_MISSION_LIST_UPDATE') and (arg ~= LE_FOLLOWER_TYPE_GARRISON_7_0) then - -- ignore non-OrderHall updates - return - end - print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, arg) - if self:IsVisible() then - print('|cFF88FF00 frame visible; get busy') - self:RequestData() +function ClassPlanHandlerBase:OnEvent(event, id) + if (event == 'GARRISON_MISSION_LIST_UPDATE') then + if (id == LE_FOLLOWER_TYPE_GARRISON_7_0) then + print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, id) + self:RefreshData() + end else - if not self.NextData then - print('|cFF88FF00 setting timer') - self.NextData = C_Timer.NewTimer(0.25, function() - if self.initialized then - self:RequestData() - self.NextData:Cancel() - self.NextData = nil - print('|cFF88FF00'..self:GetName()..' clearing timer') - end - - end) - end - end -end -function SharedHandlers:OnUpdate() - if self.isStale then - self:GetParent():Update() + print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, id) end end +function ClassPlanHandlerBase:OnUpdate() + if self.isStale then + print('|cFF00FF00'..self:GetName()..':OnUpdate()|r') + + self:UpdateItems() + end +end -- Stuff set on every list item -function SharedHandlers:SetOwnerData (self, data) +function ClassPlanHandlerBase:SetOwnerData (self, data) local name, realm = string.match(data.profileKey, "(.+)%-(.+)") local ownerText = '|c'.. data.classColor.colorStr .. name .. '|r' self.Owner:SetText(ownerText) @@ -397,17 +486,16 @@ self.Name:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b) end -function SharedHandlers:Acquire(id) +function ClassPlanHandlerBase:Acquire(id) end -function SharedHandlers:FreeBlock (block) +function ClassPlanHandlerBase:FreeBlock (block) end -function SharedHandlers:UpdateItems() - +function ClassPlanHandlerBase:UpdateItems() + print('|cFF0088FF '..self:GetName()..':UpdateItems()|r', self.activeKey) self.MoreItemsUp:Hide() self.MoreItemsDown:Hide() - - local sortedItems = self.sortedItems + local sortedItems = self.sortedItems[self.activeKey] local scrollOffset = self.scrollOffset or 0 local numItems = #sortedItems if (not sortedItems[scrollOffset+1]) or (numItems <= self.maxItems) then @@ -416,41 +504,41 @@ scrollOffset = (numItems - self.maxItems) end - + self.ListTab.Count:SetText(numItems) self.blocks = self.blocks or {} local blocks = self.blocks - local lastProfile - local totalHeight = 0 + local totalHeight = (self.ListTab:GetHeight() or 0) self.lastBlock = nil self.numActive = 0 for i = 1, self.maxItems do local index = scrollOffset + i local data = sortedItems[index] if not data then + print('|cFFFF4400end of data') break end - local block = blocks[i] if not block then - block = CreateFrame('Button', nil, self, self.templateName) + block = CreateFrame('Button', self:GetName()..'ListItem'..i , self, self.templateName) block.listType = self.activeKey + + block.doAnimation = true + block.handler = self self.numBlocks = self.numBlocks + 1 blocks[i] = block end block:SetID(index) - - print('RefreshItem', block) self.numActive = self.numActive + 1 if self.lastBlock then block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0) - print('--', index, data.isComplete, data.missionEndTime, data.name) + --print('--', index, data.isComplete, data.missionEndTime, data.name) else - block:SetPoint('TOPLEFT', 0, 0) - print('--top') + block:SetPoint('TOPLEFT', self.ListTab, 'BOTTOMLEFT', 0, 0) + --print('--top') end self.lastBlock = block @@ -491,104 +579,33 @@ end end + self:Reanchor() + if totalHeight ~= self.currentHeight then + self.currentHeight = totalHeight + self:SetHeight(self.currentHeight) + self:GetParent():Reanchor() + end + + self.scrollOffset = scrollOffset - self:Reanchor() - + self.isStale = nil return totalHeight end +function ClassPlanEntryBase:OnAnimFinished() +end +function ClassPlanEntryBase:OnShow() -function ShipmentList:Reanchor() - print('|cFF00FFFF'..self:GetName()..':Reanchor|r') - self:SetPoint('TOPLEFT', 0, -24) - self:SetPoint('BOTTOMRIGHT', -ClassOrderPlan:GetWidth()/2, 0) -end - - - -do - local ShipmentsInfo = {} - local AddShipmentInfo = function(shipmentType, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID, followerID) - -- early login queries may return empty tables, causing the sorter to compare nil - if not creationTime then - return + print('|cFF44FF00'..self:GetName()..':OnShow()') + if self.doAnimation then + self.doAnimation = nil + if not ClassOrderPlan.isAnimating then + self.NewBlockFade:Play() end - --print(shipmentType, name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) - tinsert(ShipmentsInfo, - { - shipmentType = shipmentType, - name = name, - icon = texture, - shipmentCapacity = shipmentCapacity, - shipmentsReady = shipmentsReady, - shipmentsTotal = shipmentsTotal, - creationTime = creationTime, - duration = duration, - timeleftString = timeleftString, - itemName = itemName, - itemIcon = itemIcon, - itemQuality = itemQuality, - itemID = itemID, - followerID = followerID, - }) - end - function ShipmentList:GetPlayerData (profile) - if not profile then - return false - end - local profileList = profile.shipments - wipe(ShipmentsInfo) - - local garrisonType = LE_GARRISON_TYPE_7_0 - local buildings = CG_GetBuildings(garrisonType); - local shipmentIndex = 0 - --print('Buildings:') - for i = 1, #buildings do - local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = CG_GetLandingPageShipmentInfo(buildingID); - AddShipmentInfo('Building', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID) - end - - --print('Follower:') - local followerShipments = CG_GetFollowerShipments(garrisonType); - for i = 1, #followerShipments do - local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = CG_GetLandingPageShipmentInfoByContainerID(followerShipments[i]); - AddShipmentInfo('Follower', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, nil, nil, nil, nil, followerID) - end - - --print('Loose:') - local looseShipments = CG_GetLooseShipments(garrisonType) - for i = 1, #looseShipments do - local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = CG_GetLandingPageShipmentInfoByContainerID(looseShipments[i]); - AddShipmentInfo('Misc', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) - end - - local talentTrees = CG_GetTalentTrees(garrisonType, select(3, UnitClass("player"))); - -- this is a talent that has completed, but has not been seen in the talent UI yet. - local completeTalentID = CG_GetCompleteTalent(garrisonType); - --print('Talents:') - if (talentTrees) then - for treeIndex, tree in ipairs(talentTrees) do - for talentIndex, talent in ipairs(tree) do - local showTalent = false; - if (talent.isBeingResearched) or (talent.id == completeTalentID) then - AddShipmentInfo('Talent', talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString) - end - end - end - end - - wipe(profileList) - for index, data in ipairs(ShipmentsInfo) do - --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration)) - tinsert(profileList, data) - end - self.isStale = true - return true end end - -function SharedEntry:SetTimeLeft(expires, duration) +function ClassPlanEntryBase:SetTimeLeft(expires, duration) self.ProgressBG:Hide() self.ProgressBar:Hide() if not expires then @@ -596,10 +613,14 @@ end -- calculate here since time isn't available - local timeLeft = expires - GI_currentTime + local timeLeft = expires - time() if timeLeft < 0 then -- handle being complete - + if self.shipmentsReady and (self.shipmentsReady < self.shipmentsTotal) then + self.TimeLeft:SetText('Ready') + else + self.TimeLeft:SetText('Complete!') + end else self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) end @@ -610,188 +631,85 @@ local g = ((progress <= .5) and (progress*2)) or 1 self.ProgressBG:Show() self.ProgressBar:Show() - self.ProgressBG:SetColorTexture(r,g,0,0.25) self.ProgressBar:SetColorTexture(r,g,0,0.5) - self.ProgressBar:SetWidth(self:GetWidth() * progress) + self.ProgressBar:SetWidth(self.ProgressBG:GetWidth() * progress) end end --- Update shipment flags data -local SetActualShipmentTime = function(self) - if self.isComplete then - return nil, nil + +ClassPlanHeaderMixin = {} +function ClassPlanHeaderMixin:OnLoad() + self:EnableMouse((#self:GetParent().listKey > 1)) + self:RegisterForClicks('AnyUp') end - - local timestamp = time() - local timeLeft = self.creationTime + self.duration - timestamp - local duration = self.duration * self.shipmentsTotal - local justFinished = false - while (self.shipmentsReady < self.shipmentsTotal) and (timeLeft <= 0) do - if not self.originalReady then - self.originalReady = self.shipmentsReady - self.originalCreationTime = self.creationTime - end - - - self.shipmentsReady = self.shipmentsReady + 1 - self.creationTime = self.creationTime + self.duration - timeLeft = timeLeft + self.duration - print('|cFF00FF88udpating '..self.name..'|r', 'timeLeft:', timeLeft, 'shipments:', self.shipmentsReady, self.shipmentsTotal) - end - - if (timeLeft <= 0) and (not self.isBeingResearched) then - self.isComplete = true - self.isStale = true - end - - - local expires = (self.originalCreationTime or self.creationTime) + duration - - return expires, duration -end - -function ShipmentList:OnGetItem (data) - print('OnGetItem()') - if data.shipmentsTotal then - SetActualShipmentTime(data) +function ClassPlanHeaderMixin:OnClick () + local frame = self:GetParent() + frame:SetList() + if frame.OnHeaderClick then + frame.OnHeaderClick(frame) end end -ShipmentList.SortHandler = function(a, b) - if b.isComplete ~= a.isComplete then - return a.isComplete and true or false - elseif a.shipmentsReady or b.shipmentsReady then - return (a.shipmentsReady or 0) > (b.shipmentsReady or 0) - else - return (a.creationTime) < (b.creationTime) +ClassPlanCharacterButtonMixin = { +} +function ClassPlanCharacterButtonMixin:Update () + --print(CLASS_ICON_TCOORDS[self.className:upper()]) + if self.className and CLASS_ICON_TCOORDS[self.className:upper()] then + self.Icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[self.className:upper()])) end + self.Icon:SetDesaturated((not self.showItems)) + self.SelectGlow:SetShown(self.isMine) end -function ShipmentList:OnLoad() - C_Garrison.RequestLandingPageShipmentInfo(); -end -function ShipmentList:OnShow() - print('|cFF00FF88'..self:GetName()..':OnShow()|r') - C_Garrison.RequestLandingPageShipmentInfo() -end - -function ShipmentEntry:OnLoad() - MissionEntry.OnLoad(self) -end - - -function ShipmentEntry:Update() - print('|cFF0088FF'.. self.name..'|r:Update()') - self.Icon:SetTexture(self.icon) - self.Count:SetText(self.shipmentsReady) - self.Done:SetShown(self.shipmentsReady and (self.shipmentsReady >= 1)) - - -- flag as complete - - local bgColor = CP_BACKGROUND_COLOR.inProgress - if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then - self.Swipe:SetCooldownUNIX(0, 0); - self.Done:Show(); - bgColor = CP_BACKGROUND_COLOR.complete - else - if (self.shipmentsReady >= 1) and (self.shipmentsReady < self.shipmentsTotal) then - bgColor = CP_BACKGROUND_COLOR.shipmentsReady - end - self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0); - end - self.Background:SetColorTexture(unpack(bgColor)) - - SetActualShipmentTime(self) - - if self.originalReady then - print('|cFF00FF88'..self.name..'|r', 'starting ready:', self.originalReady, 'starting time:', self.originalCreationTime) - end -end - -function ShipmentEntry:OnUpdate(sinceLast) - self.throttle = (self.throttle or 1) + sinceLast - if self.throttle >= 1 then - self.throttle = self.throttle - 1 - else +function ClassPlanCharacterButtonMixin:OnEnter() + if not self.profileKey then return end - - if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then - local expires, duration = SetActualShipmentTime(self) - - if self.isComplete then - self.TimeLeft:SetText('Complete!') - self.TimeLeft:SetTextColor(0,1,1) - elseif self.shipmentsReady >= 1 then - self:SetTimeLeft(expires, duration) - self.TimeLeft:SetTextColor(0,1,0) - else - self:SetTimeLeft(expires, duration) - self.TimeLeft:SetTextColor(1,1,1) - end - - elseif self.isBeingResearched then - self:SetTimeLeft(self.researchStartTime + self.researchDuration - time(), self.researchDuration) - self.TimeLeft:SetTextColor(1,1,1) - else - self.TimeLeft:SetText('Complete!') - self.TimeLeft:SetTextColor(0,1,0) + GameTooltip:SetOwner(self, 'ANCHOR_RIGHT') + local info = ClassOrderPlan.data.characters[self.profileKey] + GameTooltip:AddLine(self.characterName, self.classColor.r, self.classColor.g, self.classColor.b) + local numItems = 0 + if info.missions then + GameTooltip:AddLine(#info.missions .. ' mission'..((#info.missions == 1) and '' or 's')..' in progress') end - + if info.shipments then + GameTooltip:AddLine(#info.shipments .. ' work order' .. ((#info.shipments == 1) and '' or 's')) + end + if info.available then + GameTooltip:AddLine(#info.available .. ' mission'..((#info.available == 1) and '' or 's')..' available') + end + GameTooltip:Show() end -function ShipmentEntry:OnEnter() - if ( self.shipmentsReady and self.shipmentsTotal ) then - GameTooltip:SetOwner(self, 'ANCHOR_LEFT') - GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor()) - GameTooltip:AddLine(self.shipmentType) - GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal) - GameTooltip:Show() - end -end - -function ShipmentEntry:OnLeave() +function ClassPlanCharacterButtonMixin:OnLeave() if GameTooltip:IsOwned(self) then GameTooltip:Hide() end end -function ShipmentEntry:OnClick(button) +function ClassPlanCharacterButtonMixin:OnClick(button, down) + print('OnClick', self.profileKey) + local clist = ClassOrderPlan.data.characters + if button == 'RightButton' then - self.handler:FreeBlock(self) + for _, profile in pairs(clist) do + profile.showItems = true + end + else + if clist[self.profileKey].showItems then + clist[self.profileKey].showItems = nil + else + clist[self.profileKey].showItems = true + end end + for i, handler in ipairs(ClassOrderPlan.Handlers) do + handler.isStale = true + end + + ClassOrderPlan:RefreshData() + ClassOrderPlan:Update() + print(clist[self.profileKey].showItems) end - - - - -ClassPlanMissionHandler = Mixin(MissionList, SharedHandlers) -ClassPlanMissionEntryMixin = Mixin(MissionEntry, SharedEntry) -ClassPlanShipmentHandler = Mixin(ShipmentList, SharedHandlers) -ClassPlanShipmentEntryMixin = Mixin(ShipmentEntry,SharedEntry) - -ClassPlanHeaderMixin = { - OnClick = function(self) - self:GetParent():SetList() - self:GetParent().isStale = true - ClassOrderPlan:Update() - end -} - -ClassPlanCharacterButtonMixin = { - Update = function(self) - print(CLASS_ICON_TCOORDS[self.className:upper()]) - if self.className and CLASS_ICON_TCOORDS[self.className:upper()] then - self.Icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[self.className:upper()])) - end - self.Icon:SetDesaturated(self.showItems) - self.SelectGlow:SetShown(self.isMine) - end -} - -function ClassPlanCharacterButtonMixin:OnEnter() end -function ClassPlanCharacterButtonMixin:OnLeave() end -function ClassPlanCharacterButtonMixin:OnClick() end \ No newline at end of file
--- a/ClassPlan.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlan.xml Sun Dec 25 13:04:57 2016 -0500 @@ -18,20 +18,45 @@ <OnShow method="OnShow" /> <OnHide method="OnHide" /> <OnUpdate method="OnUpdate" /> + <OnDragStart method="OnDragStart" /> + <OnDragStop method="OnDragStop" /> </Scripts> + <Animations> + <AnimationGroup parentKey="FadeIn" setToFinalAlpha="true"> + <Alpha parentKey="AlphaFade" fromAlpha="0" toAlpha="1" duration=".3" order="1" /> + </AnimationGroup> + <AnimationGroup parentKey="FadeOut"> + + <Alpha parentKey="AlphaFade" fromAlpha="1" toAlpha="0" duration=".3" order="1" /> + </AnimationGroup> + </Animations> <Layers> <Layer level="BACKGROUND"> - <Texture parentKey="Background" setAllPoints="true"> - <Color a="0.5" r="0" b="0" g="0" /> + <Texture parentKey="HeaderInset"> + <Size y="24" /> + <Anchors> + <Anchor point="TOPLEFT" x="0" y="0" /> + <Anchor point="RIGHT" x="0" y="0" /> + </Anchors> + <Color r="0" g="0" b="0" a="0.5" /> </Texture> </Layer> <Layer level="ARTWORK"> - <Texture parentKey="portrait"> - <Size x="40" y="40" /> + <Texture parentKey="ClassStripe"> + <Size y="4" /> <Anchors> - <Anchor point="TOPLEFT" /> + <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" relativeKey="$parent.HeaderInset" x="0" y="-24" /> + <Anchor point="RIGHT" /> + </Anchors> + <Color a="1" r="0" b="0" g="0" /> + </Texture> + <Texture parentKey="BackgroundInset"> + <Anchors> + <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" relativeKey="$parent.ClassStripe" x="0" y="0" /> + <Anchor point="BOTTOMRIGHT" /> </Anchors> + <Color a="0.65" r="0" g="0" b="0" /> </Texture> </Layer> </Layers> @@ -49,6 +74,41 @@ <OnMouseWheel method="OnMouseWheel" /> </Scripts> <Frames> + <Button name="$parentTab" parentKey="ListTab" mixin="ClassPlanHeaderMixin"> + <Anchors> + <Anchor point="TOPLEFT" /> + <Anchor point="RIGHT" /> + </Anchors> + <Scripts> + <OnLoad method="OnLoad" /> + <OnClick method="OnClick" /> + </Scripts> + <Size y="24" /> + <Layers> + <Layer level="BACKGROUND"> + <Texture parentKey="Background"> + <Color a="1" r="0" g="0" b="0" /> + </Texture> + </Layer> + <Layer level="OVERLAY"> + <FontString parentKey="Label" inherits="ClassPlanFont"> + <Anchors> + <Anchor point="CENTER" /> + </Anchors> + </FontString> + <FontString parentKey="Count" inherits="ClassPlanFont"> + <Anchors> + <Anchor point="LEFT" x="3" y="0" /> + </Anchors> + </FontString> + </Layer> + <Layer level="HIGHLIGHT"> + <Texture parentKey="Highlight"> + <Color a="0.5" r="1" g="1" b="1" /> + </Texture> + </Layer> + </Layers> + </Button> <Frame parentKey="MoreItemsUp" frameStrata="HIGH" hidden="true"> <Size y="24" /> <Anchors> @@ -87,11 +147,31 @@ </Layers> </Frame> </Frames> + <Layers> + <Layer level="OVERLAY"> + <FontString parentKey="Count" inherits="ClassPlanFont"> + <Anchors> + <Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT" x="0" y="3" /> + </Anchors> + </FontString> + </Layer> + </Layers> </Frame> - - <Frame name="$parentShipments" parentKey="Shipments" mixin="ClassPlanShipmentHandler" inherits="ClassPlanPanelTemplate" /> <Button name="ClassPlanListEntryTemplate" virtual="true" hidden="true"> + <Animations> + <AnimationGroup parentKey="NewBlockFade"> + <Scripts> + <OnStop> + self:GetParent():OnAnimFinished() + </OnStop> + <OnFinished> + self:GetParent():OnAnimFinished() + </OnFinished> + </Scripts> + <Alpha parentKey="AlphaFade" duration="0.5" fromAlpha="0" toAlpha="1" order="1" /> + </AnimationGroup> + </Animations> <Scripts> <OnLoad method="OnLoad" /> <OnClick method="OnClick" /> @@ -138,13 +218,19 @@ </Texture> </Layer> <Layer level="ARTWORK"> - <Texture parentKey="Done" atlas="GarrLanding-ShipmentCompleteGlow"> + <Texture parentKey="Done" atlas="GarrLanding-ShipmentCompleteGlow" hidden="true"> <Size x="24" y="24" /> <Anchors> <Anchor point="BOTTOMLEFT"/> </Anchors> </Texture> </Layer> + <Layer level="HIGHLIGHT"> + + <Texture setAllPoints="true"> + <Color a="0.25" r="1" g="1" b="1" /> + </Texture> + </Layer> </Layers> <Frames> <Cooldown parentKey="Swipe" inherits="CooldownFrameTemplate" reverse="true" hideCountdownNumbers="true"> @@ -167,20 +253,21 @@ <Layers> <Layer level="OVERLAY"> - <FontString parentKey="Name" inherits="ClassPlanFont" justifyV="TOP" justifyH="CENTER"> - <Anchors> - <Anchor point="LEFT" x="26" y="0"/> - </Anchors> - <Color r=".75" g=".75" b=".73"/> - </FontString> <FontString parentKey="TimeLeft" inherits="ClassPlanFont" justifyH="CENTER"> <Anchors> <Anchor point="RIGHT" x="-2" y="0"/> </Anchors> </FontString> + <FontString parentKey="Name" inherits="ClassPlanFont" justifyV="TOP" wordwrap="false" justifyH="LEFT"> + <Anchors> + <Anchor point="LEFT" x="26" y="0"/> + <Anchor point="RIGHT" relativePoint="LEFT" relativeKey="$parent.TimeLeft" x="-4" y="0"/> + </Anchors> + <Color r=".75" g=".75" b=".73"/> + </FontString> <FontString parentKey="Count" inherits="WorldPlanFont" justifyH="CENTER"> <Anchors> - <Anchor point="CENTER" relativePoint="LEFT" x="12" y="0"/> + <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="2" y="1" relativeKey="$parent.$parent.Icon"/> </Anchors> </FontString> </Layer> @@ -216,6 +303,11 @@ <TexCoords left="0.5" right="1" top="0" bottom="0.5" /> </Texture> </Layer> + <Layer level="HIGHLIGHT"> + <Texture parentKey="HighlightGlow" file="Interface\Glues\CHARACTERCREATE\UI-CharacterCreate-Highlights" alphaMode="ADD" alpha="0.5"> + <TexCoords left="0" right="0.5" top="0" bottom="0.5" /> + </Texture> + </Layer> </Layers> </Button>
--- a/ClassPlanFollowers.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlanFollowers.lua Sun Dec 25 13:04:57 2016 -0500 @@ -1,11 +1,50 @@ -ClassPlanFollowerMixin = {} -local c = ClassPlanFollowerMixin -function c:OnEvent(event, arg) + +local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop +local c = { + + templateName = 'ClassPlanShipmentEntry', + listKey = {'followers'}, + listTitle = {'Followers'}, + events = { + 'GARRISON_FOLLOWER_LIST_UPDATE', + 'GARRISON_FOLLOWER_XP_CHANGED', + 'GARRISON_FOLLOWER_DURABILITY_CHANGED', + 'GARRISON_FOLLOWER_UPGRADED', + 'GARRISON_FOLLOWER_REMOVED' + } +} + + +function c:OnLoad() + self.followerType = 4 + -- follower type, versus garrison_type +end + +function c:OnEvent(event, ...) + print('|cFF00FF00'..self:GetName()..':OnEvent()|r', event, ...) + self:GetPlayerData() +end + +function c:OnUpdate() end + +function c:GetPlayerData() + + print('|cFF0088FF'..self:GetName()..':GetPlayerData()|r') + local profileList = self:GetParent().profile.followers + local followerInfo = C_Garrison.GetFollowers(self.followerType) + if followerInfo then + table.wipe(profileList) + for followerID, follower in pairs(followerInfo) do + profileList[followerID] = follower + end + end end -function c:GetPlayerData(event, arg) end +function c:UpdateItems() +end +function c:Reanchor() +end -function c:UpdateItems() end -function c:Reanchor() end \ No newline at end of file +ClassPlanFollowerMixin = CreateFromMixins(ClassPlanHandlerBase, c) \ No newline at end of file
--- a/ClassPlanFollowers.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlanFollowers.xml Sun Dec 25 13:04:57 2016 -0500 @@ -1,9 +1,9 @@ <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> - <Script file="FollowerList.lua" /> - <Frame name="$parentFollowerList" parent="ClassOrderPlan"parentKey="FollowerList" parentArray="Handlers" mixin="ClassPlanFollowerMixin"> + <Script file="ClassPlanFollowers.lua" /> + <Frame name="$parentFollowers" parent="ClassOrderPlan" parentKey="FollowerList" parentArray="Handlers" mixin="ClassPlanFollowerMixin" inherits="ClassPlanPanelTemplate"> <Scripts> - <OnEvent method="OnEvent" /> + <OnEvent method="OnEvent"/> <OnUpdate method="OnUpdate" /> <OnShow method="OnShow" /> </Scripts>
--- a/ClassPlanMissions.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlanMissions.lua Sun Dec 25 13:04:57 2016 -0500 @@ -1,19 +1,37 @@ -local MissionList = ClassPlanMissionHandler -local ListEntry = ClassPlanMissionEntryMixin +local _, db= ... local ORDERHALL_TYPE = LE_GARRISON_TYPE_7_0 -function ClassPlanMissionHandler:Reanchor() - self:SetPoint('TOPRIGHT', 0, -24) - self:SetPoint('BOTTOMLEFT', ClassOrderPlan:GetWidth()/2, 0) - -end +local UnitClass = UnitClass +local time, max, min = time, max, min +local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop local GetPrimaryGarrisonFollowerType = GetPrimaryGarrisonFollowerType local C_Garrison = C_Garrison local wipe, tinsert, date, ipairs = table.wipe, table.insert, date, ipairs local GetItemIcon = GetItemIcon -local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop -function ClassPlanMissionHandler:GetPlayerData (profile) + +local MissionList = { + templateName = 'ClassPlanMissionEntry', + listKey = {'missions', 'available'}, + listTitle = {'In Progress', 'Available'}, + + point = 'TOPLEFT', + relativePoint ='TOPLEFT', + events = { + 'GARRISON_MISSION_LIST_UPDATE'}, +} +local ListEntry = {} + +function MissionList:Reanchor() + self:SetPoint('TOPRIGHT', ClassOrderPlan.BackgroundInset, 'TOPRIGHT', 0, 0) + self:SetPoint('BOTTOMLEFT', ClassOrderPlan:GetWidth()/2, 0) +end + + + + +function MissionList:GetPlayerData () + local profile = self:GetParent().profile local items = C_Garrison.GetAvailableMissions(GetPrimaryGarrisonFollowerType(ORDERHALL_TYPE)); if not items then return @@ -38,60 +56,83 @@ return true end -function ClassPlanMissionHandler:OnGetItem (data) - if data.missionEndTime and (data.missionEndTime < self.currentTime) then - data.isComplete = true +function MissionList:OnGetItem (data) + if data.missionEndTime then + if (data.missionEndTime < self.currentTime) then + data.isComplete = true + else + self:ScheduleUpdate(data.missionEndTime) + end end - if data.offerEndTime and (data.offerEndTime < self.currentTime) then - data.isExpired = true - data.timeToKeep = self.currentTime + 300 + + if data.offerEndTime then + if (data.offerEndTime < self.currentTime) then + data.isExpired = true + data.timeToKeep = self.currentTime + 300 + else + self:ScheduleUpdate(data.offerEndTime) + end end + end MissionList.SortHandler = function (a,b) local result = false - --if not a or not b then - -- return true - --else - --if (a.isMine ~= b.isMine) then - -- result = a.isMine - --else - --if (not b.missionEndTime) or (not a.missionEndTime) then - -- print('missing article', b.missionEndTime, a.missionEndTime) - --end if b.isComplete ~= a.isComplete then return a.isComplete - elseif b.isMine ~= a.isMine then - return a.isMine - elseif b.missionEndTime then - return ( b.missionEndTime > a.missionEndTime) else - return ((b.offerEndTime or 0) > (a.offerEndTime or 0)) + if b.isMine ~= a.isMine then + return a.isMine + else + if a.isComplete then + if a.profileKey ~= b.profileKey then + return (a.profileKey < b.profileKey) + else + return (a.name < b.name) + end + else + if b.missionEndTime then + return ( b.missionEndTime > a.missionEndTime) + else + return ((b.offerEndTime or 0) > (a.offerEndTime or 0)) + end + end + end + end +end + +function MissionList:OnEvent(event, ...) + self:RefreshData() + if event == 'GARRISON_MISSION_FINISHED' then + local followerTypeID, missionID = ...; + elseif event == 'GARRISON_TALENT_COMPLETE' then + local garrisonType = ...; + elseif event == '' then end - --end - --end end - function MissionList:OnShow() print('|cFF00FF88'..self:GetName()..':OnShow()|r') end - - -function ClassPlanMissionEntryMixin:OnComplete() +function ListEntry:OnComplete() print('flagging complete', self.name) self:Update() end -function ClassPlanMissionEntryMixin:OnUpdate(sinceLast) +function ListEntry:OnUpdate(sinceLast) + if self.doAnimation then + self.doAnimation = nil + self.NewBlockFade:Play() + end self.throttle = (self.throttle or .5) + sinceLast if self.throttle < .5 then return else self.throttle = self.throttle - .5 end + if self.offerEndTime then self:SetTimeLeft(self.offerEndTime) elseif self.missionEndTime then @@ -99,8 +140,12 @@ end end -function ClassPlanMissionEntryMixin:OnLoad() - print('|cFFFF4400',self:GetName() or tostring(self), 'onload') +function ListEntry:OnHide(...) + print(self:GetName().. ':Hide()', ...) +end + +function ListEntry:OnLoad() + print('|cFFFF4400'..self:GetName()..':OnLoad()') self.Count = self.Overlay.Count self.Name = self.Overlay.Name self.TimeLeft = self.Overlay.TimeLeft @@ -109,9 +154,17 @@ self.Icon:SetDesaturated(false) self.Done:Hide() + --[[ + hooksecurefunc(self.Background, 'SetColorTexture', function(self, ...) + print(self:GetName(), ...) + end) + hooksecurefunc(self.Background, 'SetTexture', function(self, ...) + --print(self:GetName(), ...) + end) + --]] end -function ClassPlanMissionEntryMixin:Update() +function ListEntry:Update() local r,g,b = 1, 1, 1 if self.isRare then r,g,b = 0.1, 0.4, 1 @@ -127,26 +180,31 @@ self.Icon:SetAtlas(self.typeAtlas, false) end + local itemType = db.ClassPlanTypes.inProgress + if self.isComplete then + itemType = db.ClassPlanTypes.complete + end - - if self.isComplete then - self.TimeLeft:SetText('Complete!') - self.Background:SetColorTexture(.25,.25,.25,1) - else - self.Background:SetColorTexture(0,0,0,0.5) - end + self.Background:SetColorTexture(unpack(itemType.backgroundColor)) end function ListEntry:OnEnter() + WorldMap_HijackTooltip(self) if self.rewardInfo and self.rewardInfo.itemID then - GameTooltip:SetOwner(self, 'ANCHOR_LEFT') - GameTooltip:SetItemByID(self.rewardInfo.itemID) - GameTooltip:Show() + WorldMapTooltip:SetOwner(self, 'ANCHOR_LEFT') + WorldMapTooltip:AddLine(self.name) + EmbeddedItemTooltip_SetItemByID(WorldMapTooltip.ItemTooltip, self.rewardInfo.itemID) + WorldMapTooltip:Show() end end function ListEntry:OnLeave() - if GameTooltip:IsOwned(self) then - GameTooltip:Hide() + WorldMap_RestoreTooltip() + if WorldMapTooltip:IsOwned(self) then + WorldMapTooltip:Hide() end -end \ No newline at end of file +end + + +ClassPlanMissionHandler = CreateFromMixins(ClassPlanHandlerBase, MissionList) +ClassPlanMissionEntryMixin = CreateFromMixins(ClassPlanEntryBase, ListEntry) \ No newline at end of file
--- a/ClassPlanMissions.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlanMissions.xml Sun Dec 25 13:04:57 2016 -0500 @@ -7,6 +7,11 @@ <Anchors> <Anchor point="RIGHT" /> </Anchors> + <Scripts> + + <OnShow method="OnShow" /> + <OnHide method="OnHide" /> + </Scripts> </Button> <Frame name="ClassPlanMissionList" parentKey="MissionList" mixin="ClassPlanMissionHandler" inherits="ClassPlanPanelTemplate"> <Scripts> @@ -14,34 +19,7 @@ <OnUpdate method="OnUpdate" /> <OnEvent method="OnEvent" /> <OnShow method="OnShow" /> + <OnHide method="OnHide" /> </Scripts> - <Frames> - <Button name="$parentTab" parentKey="ListTab" mixin="ClassPlanHeaderMixin"> - <Scripts> - <OnClick method="OnClick" /> - </Scripts> - <Size y="24" /> - <Layers> - <Layer level="BACKGROUND"> - <Texture parentKey="Background"> - <Color a="1" r="0" g="0" b="0" /> - </Texture> - </Layer> - <Layer level="OVERLAY"> - <FontString parentKey="Label" inherits="ClassPlanFont"> - <Anchors> - <Anchor point="CENTER" /> - </Anchors> - </FontString> - </Layer> - <Layer level="HIGHLIGHT"> - <Texture parentKey="Highlight"> - <Color a="0.5" r="1" g="1" b="1" /> - </Texture> - </Layer> - </Layers> - - </Button> - </Frames> </Frame> </Ui> \ No newline at end of file
--- a/ClassPlanShipments.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlanShipments.lua Sun Dec 25 13:04:57 2016 -0500 @@ -0,0 +1,329 @@ +local _, db = ... + +local wipe, tinsert, ipairs, select = table.wipe, table.insert, ipairs, select +local UnitClass = UnitClass +local time, max, min = time, max, min +local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop + + +local CG_GetBuildings = C_Garrison.GetBuildings +local CG_GetFollowerShipments = C_Garrison.GetFollowerShipments +local CG_GetLooseShipments = C_Garrison.GetLooseShipments +local CG_GetTalentTrees = C_Garrison.GetTalentTrees +local CG_GetCompleteTalent = C_Garrison.GetCompleteTalent +local CG_GetLandingPageShipmentInfo = C_Garrison.GetLandingPageShipmentInfo +local CG_GetLandingPageShipmentInfoByContainerID = C_Garrison.GetLandingPageShipmentInfoByContainerID + +local AK_NOTES, RECRUIT_MAJOR, RECRUIT_MINOR, OH_TALENT, NOMI = 2, 4, 8, 16, 32 + +local FollowerTypes = { + ['Pathfinders'] = true, + ['Acolytes'] = true, +} +local ShipmentOrder = { + [AK_NOTES] = 2, + [RECRUIT_MAJOR] = 3, + [RECRUIT_MINOR] = 4, + [NOMI] = 5, + [OH_TALENT] = 6, +} +local SortKey = 'shipmentType' +local SortTable = ShipmentOrder + +local ShipmentList = { + templateName = 'ClassPlanShipmentEntry', + listKey = {'shipments'}, + listTitle = {'Work Orders'}, + events = { + 'GARRISON_MISSION_LIST_UPDATE', + 'GARRISON_LANDINGPAGE_SHIPMENTS', + 'GARRISON_TALENT_UPDATE', + "GARRISON_TALENT_COMPLETE", + "GARRISON_SHIPMENT_RECEIVED", + 'GARRISON_FOLLOWER_LIST_UPDATE', + 'SHIPMENT_CRAFTER_INFO', + 'ITEM_PUSH'}, +} + +local ShipmentEntry = {} + +function ShipmentList:Reanchor() + print('|cFF00FFFF'..self:GetName()..':Reanchor|r') + self:SetPoint('TOPLEFT', ClassOrderPlan.BackgroundInset, 'TOPLEFT') + self:SetPoint('BOTTOMRIGHT', -ClassOrderPlan.BackgroundInset:GetWidth()/2, 0) +end + +do + local ShipmentsInfo = {} + local AddShipmentInfo = function(shipmentType, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID, followerID) + -- early login queries may return empty tables, causing the sorter to compare nil + if not creationTime then + return + end + --print(shipmentType, name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) + tinsert(ShipmentsInfo, + { + shipmentType = shipmentType, + name = name, + icon = texture, + shipmentCapacity = shipmentCapacity, + shipmentsReady = shipmentsReady, + shipmentsTotal = shipmentsTotal, + creationTime = creationTime, + duration = duration, + timeleftString = timeleftString, + itemName = itemName, + itemIcon = itemIcon, + itemQuality = itemQuality, + itemID = itemID, + followerID = followerID, + }) + print(' ', name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration) + end + function ShipmentList:GetPlayerData () + local profileList = self:GetParent().profile.shipments + wipe(ShipmentsInfo) + + local garrisonType = LE_GARRISON_TYPE_7_0 + local buildings = CG_GetBuildings(garrisonType); + local shipmentIndex = 0 + --print('Buildings:') + for i = 1, #buildings do + local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = CG_GetLandingPageShipmentInfo(i); + AddShipmentInfo(RECRUIT_MAJOR, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID) + end + + --print('Follower:') + local followerShipments = CG_GetFollowerShipments(garrisonType); + for i = 1, #followerShipments do + local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = CG_GetLandingPageShipmentInfoByContainerID(followerShipments[i]); + AddShipmentInfo(RECRUIT_MINOR, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, nil, nil, nil, nil, followerID) + end + + --print('Loose:') + local looseShipments = CG_GetLooseShipments(garrisonType) + for i = 1, #looseShipments do + local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = CG_GetLandingPageShipmentInfoByContainerID(looseShipments[i]); + AddShipmentInfo(AK_NOTES, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) + end + + local talentTrees = CG_GetTalentTrees(garrisonType, select(3, UnitClass("player"))); + -- this is a talent that has completed, but has not been seen in the talent UI yet. + local completeTalentID = CG_GetCompleteTalent(garrisonType); + --print('Talents:') + if (talentTrees) then + for treeIndex, tree in ipairs(talentTrees) do + for talentIndex, talent in ipairs(tree) do + local showTalent = false; + if (talent.isBeingResearched) or (talent.id == completeTalentID) then + AddShipmentInfo(OH_TALENT, talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString) + end + end + end + end + + wipe(profileList) + for index, data in ipairs(ShipmentsInfo) do + --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration)) + tinsert(profileList, data) + end + self.isStale = true + return true + end +end +-- Update shipment flags data +local SetActualShipmentTime = function(self) + + if self.isComplete then + return nil, nil + end + + local timestamp = time() + local timeLeft = self.creationTime + self.duration - timestamp + local duration = self.duration * (self.fullDuration and (self.shipmentsTotal - self.shipmentsReady) or 1) + local justFinished = false + while (self.shipmentsReady < self.shipmentsTotal) and (timeLeft <= 0) do + if not self.originalReady then + self.originalReady = self.shipmentsReady + self.originalCreationTime = self.creationTime + end + + self.shipmentsReady = self.shipmentsReady + 1 + self.creationTime = self.creationTime + self.duration + timeLeft = timeLeft + self.duration + print('|cFF00FF88 pre-parse "'..self.name..'"|r', 'timeLeft:', timeLeft, 'shipments:', self.shipmentsReady, self.shipmentsTotal) + end + + if (timeLeft <= 0) and (not self.isBeingResearched) then + self.isComplete = true + self.isStale = true + end + + local expires = (self.originalCreationTime or self.creationTime) + duration + return expires, duration +end + +function ShipmentList:OnEvent(event, ...) + if (event == 'SHIPMENT_CRAFTER_INFO' or event == 'ITEM_PUSH' or event == 'GARRISON_FOLLOWER_LIST_UPDATE') then + C_Garrison.RequestLandingPageShipmentInfo() + elseif event == 'SHIPMENT_UPDATE' then + local shipmentStarted = ... + if shipmentStarted then + C_Garrison.RequestLandingPageShipmentInfo() + end + elseif event == 'GARRISON_LANDINGPAGE_SHIPMENTS' then + --WorldPlan:print("New shipments data received.") + self:RefreshData() + else + ClassPlanHandlerBase.OnEvent(self, event, ...) + end +end + + +function ShipmentList:OnGetItem (data) + if data.shipmentsTotal then + local expires = SetActualShipmentTime(data) + if expires and (expires > time()) then + self:ScheduleUpdate(expires) + end + end + + if data.shipmentType == 255 or type(data.shipmentType == 'string') then + if data.name == 'Artifact Research Notes' then + data.shipmentType = AK_NOTES + elseif string.match(data.name, 'Recipes') then + data.shipmentType = NOMI + elseif FollowerTypes[data.name] then + data.shipmentType = RECRUIT_MINOR + else + data.shipmentType = OH_TALENT + end + end + + +end + +function ShipmentList:OnHeaderClick() + -- flip sort table and key, push a sort and refresh +end + + +ShipmentList.SortHandler = function(a, b) + if a[SortKey] then + if b[SortKey] then + return SortTable[a[SortKey]] < SortTable[b[SortKey]] + else + return true + end + else + if b.isComplete ~= a.isComplete then + return a.isComplete and true or false + else + if a.profileKey ~= b.profileKey then + return a.profileKey < b.profileKey + else + if a.shipmentsReady and b.shipmentsReady then + return (a.shipmentsReady) > (b.shipmentsReady) + elseif a.shipmentsReady or b.shipmentsReady then + return (a.shipmentsReady) or true or false + else + + if (a.creationTime ~= b.creationTime) then + return (a.creationTime) < (b.creationTime) + else + return (a.name) < (b.name) + end + end + + end + end + end +end + +function ShipmentList:OnLoad() +end +function ShipmentList:OnShow() + print('|cFF00FF88'..self:GetName()..':OnShow()|r') +end + +function ShipmentEntry:OnLoad() + ClassPlanMissionEntryMixin.OnLoad(self) +end + + +function ShipmentEntry:Update() + --print(' |cFF00FF88"'.. self.name..'":Update()|r') + self.Icon:SetTexture(self.icon) + self.Count:SetText(self.shipmentsReady ..'/'.. self.shipmentsTotal) + + -- flag as complete + local itemType = db.ClassPlanTypes.inProgress + if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then + self.Swipe:SetCooldownUNIX(0, 0); + itemType = db.ClassPlanTypes.complete + else + if (self.shipmentsReady >= 1) and (self.shipmentsReady < self.shipmentsTotal) then + itemType = db.ClassPlanTypes.shipmentsReady + end + self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0); + end + self.Background:SetColorTexture(unpack(itemType.backgroundColor)) + + SetActualShipmentTime(self) + self.throttle = 2 +end + + + +function ShipmentEntry:OnUpdate(sinceLast) + self.throttle = (self.throttle or 1) + sinceLast + if self.throttle >= 1 then + self.throttle = self.throttle - 1 + else + return + end + + if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then + local expires, duration = SetActualShipmentTime(self) + if self.isComplete then + self.TimeLeft:SetText('Complete!') + self.TimeLeft:SetTextColor(0,1,1) + elseif self.shipmentsReady >= 1 then + self:SetTimeLeft(expires, duration) + self.TimeLeft:SetTextColor(1,1,0) + else + self:SetTimeLeft(expires, duration) + self.TimeLeft:SetTextColor(1,1,1) + end + elseif self.isBeingResearched then + self:SetTimeLeft(self.researchStartTime + self.researchDuration - time(), self.researchDuration) + self.TimeLeft:SetTextColor(1,1,1) + else + self.TimeLeft:SetText('Complete!') + self.TimeLeft:SetTextColor(0,1,0) + end +end + +function ShipmentEntry:OnEnter() + if ( self.shipmentsReady and self.shipmentsTotal ) then + GameTooltip:SetOwner(self, 'ANCHOR_LEFT') + GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor()) + GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal) + GameTooltip:Show() + end +end + + +function ShipmentEntry:OnLeave() + if GameTooltip:IsOwned(self) then + GameTooltip:Hide() + end +end + +function ShipmentEntry:OnClick(button) + self.fullDuration = not self.fullDuration + self:Update() +end + +ClassPlanShipmentHandler = CreateFromMixins(ClassPlanHandlerBase, ShipmentList) +ClassPlanShipmentEntryMixin = CreateFromMixins(ClassPlanEntryBase, ShipmentEntry) \ No newline at end of file
--- a/ClassPlanShipments.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/ClassPlanShipments.xml Sun Dec 25 13:04:57 2016 -0500 @@ -0,0 +1,14 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ +..\FrameXML\UI.xsd"> + <Script file="ClassPlanShipments.lua" /> + + <Frame name="$parentShipments" parent="ClassOrderPlan" parentKey="Shipments" mixin="ClassPlanShipmentHandler" inherits="ClassPlanPanelTemplate"> + + <Scripts> + <OnLoad method="OnLoad" /> + <OnUpdate method="OnUpdate" /> + <OnEvent method="OnEvent" /> + <OnShow method="OnShow" /> + </Scripts> + </Frame> +</Ui> \ No newline at end of file
--- a/FilterBar.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/FilterBar.lua Sun Dec 25 13:04:57 2016 -0500 @@ -3,7 +3,7 @@ -- Created: 10/27/2016 8:55 PM -- %file-revision% -- - +local _, db = ... local print = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or nop local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local wipe, ipairs, pairs = table.wipe, ipairs, pairs @@ -39,8 +39,9 @@ } local familiars_id = 9696 -local DEFAULT_FILTER_LAYOUT = { +db.DefaultFilterType = { iconWidth = 24, + iconHeight = 18, borderWidth = 3, highlightWidth = 2, TagSize = 12, @@ -48,7 +49,7 @@ showNumber = true, numberFontObject = 'WorldPlanNumberFontThin' } -local DEFAULT_FILTER_LIST = { +db.DefaultFilters = { { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" }, { filterKey= 'rewardType', cVar = 'worldQuestFilterArtifactPower', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" }, { filterKey= 'rewardType', cVar = 'worldQuestFilterOrderResources', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\Icons\\inv_orderhall_orderresources" }, @@ -62,21 +63,21 @@ } local defaults = {} -WorldPlanSummaryMixin = { - selectedBountyIndex = {}, - bounties = {}, - filterList = {}, - buttons = {}, -} +WorldPlanSummaryMixin = WorldPlanSummaryMixin or {} +WorldPlanSummaryMixin.selectedBountyIndex = {} +WorldPlanSummaryMixin.bounties = {} +WorldPlanSummaryMixin.filterList = {} +WorldPlanSummaryMixin.buttons = {} +WorldPlanSummaryMixin.cvarFiltersDirty = false WorldPlanFilterPinMixin = {} function WorldPlanSummaryMixin:OnLoad() - WorldPlan:AddHandler(self, defaults) - for index, info in ipairs(DEFAULT_FILTER_LIST) do - info.zone = DEFAULT_FILTER_LAYOUT - info.continent = DEFAULT_FILTER_LAYOUT + self:SetParent(WorldMapFrame) + WorldPlan:AddHandler(self) + for index, info in ipairs(db.DefaultFilters) do + info.zone = db.DefaultFilterType + info.continent = db.DefaultFilterType info.pinMask = "Interface\\Minimap\\UI-Minimap-Background" - WorldPlan:AddTypeInfo(self,index, info) end @@ -93,7 +94,6 @@ function WorldPlanSummaryMixin:Setup() print('|cFF00FF88'..self:GetName()..':Setup()') - self:GetFilters() end @@ -117,10 +117,10 @@ wipe(self.filterList) - for index, info in ipairs(DEFAULT_FILTER_LIST) do + for index, info in ipairs(db.DefaultFilters) do tinsert(self.filterList, info) end - self.bounties, self.numBounties = GetQuestBountyInfoForMapID(WorldPlan.currentMapID) + self.bounties, self.numBounties = GetQuestBountyInfoForMapID(db.currentMapID) self.BountyFilters = {} for index, data in ipairs(self.bounties) do local info = self.BountyFilters[index] @@ -148,6 +148,7 @@ end function WorldPlanSummaryMixin:Refresh() + self:GetFilters() self:Update() end @@ -157,59 +158,85 @@ local questResults = {{}} function WorldPlanSummaryMixin:Update() local blocks = self.buttons + local relativeFrame = WorldMapFrame.UIElementsFrame.TrackingOptionsButton - local numHeaders = 0 + if FlightMapFrame and FlightMapFrame:IsVisible() then + relativeFrame = FlightMapFrame + end + self:SetParent(relativeFrame) + + local numHeaders = 0 print('|cFF00FF88'..self:GetName()..':Update()|r', 'currentMap=',WorldPlan.currentMapID) - local layout = DEFAULT_FILTER_LAYOUT + + local layout = db.DefaultFilterType local borderWidth = layout.iconWidth + (layout.borderWidth * 2) local highlightWidth = borderWidth + (layout.highlightWidth * 2) - local quests = WorldPlanQuests.QuestsByZone[WorldPlan.currentMapID] or WorldPlanQuests.QuestsByID - local foundQuests = questResults[1] + local mapQuests = db.QuestsByZone[db.currentMapID] or db.QuestsByID + local firstCvar, lastCvar for index, info in ipairs(self.filterList) do - local numQuests = 0 - local resultIndex = numHeaders + 1 - questResults[resultIndex] = questResults[resultIndex] or {} - wipe(questResults[resultIndex]) - for questID, pin in pairs(quests) do - if pin.used then + local numQuestsHere = 0 + local numQuestsTotal = 0 + info.questList = info.questList or {} + wipe(info.questList) + + for questID, pin in pairs(db.QuestsByID) do + print(pin.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION, (db.Config.ShowAllProfessionQuests or pin.isKnownProfession)) + if (pin.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION) or (db.Config.ShowAllProfessionQuests or pin.isKnownProfession) then + print(pin.title) if not info.filterKey then - numQuests = numQuests + 1 + if mapQuests[questID] then + numQuestsHere = numQuestsHere + 1 + end + numQuestsTotal = numQuestsTotal + 1 elseif pin[info.filterKey] == info.filterValue then - numQuests = numQuests + 1 - tinsert(questResults[resultIndex], pin) + if mapQuests[questID] then + numQuestsHere = numQuestsHere + 1 + tinsert(info.questList, pin) + end + numQuestsTotal = numQuestsTotal + 1 end end end - print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')') + --print('num here', numQuestsHere, numQuestsTotal) + info.totalQuests = maxQuests - if numQuests >= 1 then + --print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')') + + if numQuestsTotal >= 1 then numHeaders = numHeaders + 1 local button = blocks[numHeaders] if not blocks[numHeaders] then - button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, WorldMapScrollFrame, 'WorldPlanFilterPin') - button:SetSize(borderWidth, borderWidth) + button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, self, 'WorldPlanFilterPin') + button:SetSize(32,20) + button.icon:SetTexCoord(0.1,.9,.1,(1 * (20/32))) - button.icon:SetSize(layout.iconWidth, layout.iconWidth) - button.RewardBorder:SetSize(borderWidth, borderWidth) - button.HighlightBorder:SetSize(highlightWidth, highlightWidth) - button.RewardBorder:SetMask(filterMask) - button.RewardBorder:SetDesaturated(true) + button.RewardBorder:ClearAllPoints() + button.RewardBorder:SetPoint('TOPLEFT', button, 'TOPLEFT') + button.RewardBorder:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT') - button.HighlightBorder:Hide() + blocks[numHeaders] = button end button.info = info - button.questList = questResults[resultIndex] + button.numQuestsTotal = numQuestsTotal + button.numQuestsHere = numQuestsHere + button.questList = info.questList + button.isFirst = (numHeaders == 1) button:SetID(index) - button.spacing = ((relativeFrame.cVar and (not info.cVar)) or (relativeFrame.filterKey ~= info.filterKey)) and 5 or 0 + button.spacing = ((relativeFrame.cVar and (not info.cVar)) or (relativeFrame.filterKey ~= info.filterKey)) and 5 or 1 button.relativeFrame = relativeFrame - button:Refresh((numHeaders == 1), numQuests) + button:Refresh() button:Show() relativeFrame = button + + if info.cVar then + firstCvar = firstCvar or button + lastCvar = button + end + end - end self.numHeaders = numHeaders @@ -221,6 +248,16 @@ wipe(questResults[i]) end end + + + if firstCvar and lastCvar then + self.CVarsHighlight:ClearAllPoints() + self.CVarsHighlight:SetPoint('TOPLEFT', firstCvar, 'TOPLEFT', -1, 1) + self.CVarsHighlight:SetPoint('BOTTOMRIGHT', lastCvar, 'BOTTOMRIGHT', 1, -1) + end + self.CVarsHighlight:SetShown(self.cvarFiltersDirty or false) + + self.isStale = nil end @@ -230,13 +267,14 @@ local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF'} function WorldPlanFilterPinMixin:OnEnter() - if self.questList and #self.questList >= 1 then + if #self.questList >= 1 then GameTooltip:SetOwner(self, 'ANCHOR_LEFT') GameTooltip:AddLine(self.info.label) for index, pin in ipairs(self.questList) do local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite - GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. pin.title ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b) + GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b) end + GameTooltip:AddLine(self.numQuestsTotal .. ' total') GameTooltip:Show() end end @@ -247,63 +285,66 @@ end end -function WorldPlanFilterPinMixin:Refresh(isFirst, numQuests) - isFirst = isFirst or self.isFirst - numQuests = numQuests or self.numQuests - +function WorldPlanFilterPinMixin:Refresh() local info = self.info - - self.isFirst = isFirst - self.numQuests = numQuests self.filterKey = info.filterKey self.filterValue = info.filterValue self.tagID = info.tagID - self.icon:SetMask(filterMask) self.icon:SetTexture(info.texture) - self.count:SetText(numQuests) + self.count:SetText(self.numQuestsHere) self.cVar = info.cVar self.itemTexture = self.texture - if isFirst then - self:SetPoint('TOP', self.relativeFrame, 'BOTTOM', 0, -5) + if self.isFirst then + if FlightMapFrame and FlightMapFrame:IsVisible() then + self:SetPoint('TOPRIGHT', FlightMapFrame, 'TOPRIGHT', -4, -25) + else + self:SetPoint('TOP', self.relativeFrame, 'BOTTOM', 0, -5) + end + else self:SetPoint('TOPRIGHT', self.relativeFrame, 'BOTTOMRIGHT', 0, -(self.spacing or 0)) end print('anchor to', self.relativeFrame:GetName(), info.mask) - local r, g, b, a = 1,1,1,1 + self.icon:SetDesaturated(self.numQuestsHere == 0) + + local r, g, b, a = 0,0,0,1 local desaturated = false - if self.cVar then - self.RewardBorder:SetVertexColor(1, 1, 1, 1) - if GetCVarBool(self.cVar) then - self.icon:SetVertexColor(1,1,1,1) - self:SetAlpha(1) - else - self.icon:SetVertexColor(.5, .5, .5, 1) - self:SetAlpha(0.5) - end - else - self:SetAlpha(1) - if WorldPlan.UsedFilters[self.filterKey] then - if WorldPlan.UsedFilters[self.filterKey] == self.filterValue then - self.RewardBorder:SetVertexColor(0, 1, 0) + if (self.numQuestsHere > 0) then + if self.cVar then + if GetCVarBool(self.cVar) then + self.count:SetTextColor(1,1,1) + r,g,b = 0, 1, 0 else - self.RewardBorder:SetVertexColor(1, 0, 0) + self:GetParent().cvarFiltersDirty = true + self.count:SetTextColor(1,0,0) + self.icon:SetDesaturated(true) + r,g,b = 1, 0, 0 end else - if self.filterKey == 'worldQuestType' then - self.RewardBorder:SetVertexColor(0, 1, 1) - elseif self.filterKey == 'factionID' then - self.RewardBorder:SetVertexColor(1, 1, 0) + if db.UsedFilters[self.filterKey] then + if db.UsedFilters[self.filterKey] == self.filterValue then + self.count:SetTextColor(0,1,0) + r,g,b = 0, 1, 0 + else + self.count:SetTextColor(1,0,0) + r, g, b = 1, 0, 0 + end else - self.RewardBorder:SetVertexColor(0.5, 0.5, 0.5) + self.count:SetTextColor(1,1,1) + if self.filterKey == 'worldQuestType' then + r, g, b = 0, 0, 1 + elseif self.filterKey == 'factionID' then + r, g, b = 1, 1, 0 + end end - end end + self.RewardBorder:SetColorTexture(r, g, b, a) --self:UpdateSize() end @@ -313,84 +354,102 @@ self:SetFrameStrata('HIGH') self:SetFrameLevel(151) self:SetScript('OnUpdate', nil) - WorldPlanPOIMixin.OnLoad(self) + self.questList = {} end function WorldPlanFilterPinMixin:OnUpdate () end - -function WorldPlanFilterPinMixin:OnLeave () - if GameTooltip:IsOwned(self) then - GameTooltip:Hide() - end -end - -- shift-click: reset filter -- click: rotate through include(1), exclude(-1), ignore(nil) local filtered_report = {} +local RESET_FILTER = "|cFFFFFFFF+%s|r" +local FILTER_EXCLUDE_TYPE = '|cFFFF0000-%s|r' +local FILTER_INCLUDE_TYPE = '|cFF00FF00+%s|r' function WorldPlanFilterPinMixin:OnClick (button) - print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, operation) local filterKey = self.filterKey local filterValue = self.filterValue local cVar = self.cVar local parent = self:GetParent() - local operation = opPrefix - local setDirty = false + local setDirty + + print('|cFF00FF88'..self:GetName()..':OnClick()|r', filterKey, filterValue, cVar, parent) local resetMode = (button == 'RightButton') wipe(filtered_report) if not (filterKey or cVar) then - wipe(WorldPlan.UsedFilters) - for i, info in ipairs(DEFAULT_FILTER_LIST) do + for i, info in ipairs(db.DefaultFilters) do if info.cVar then - if GetCVar(info.cVar) ~= 1 then - tinsert(filtered_report, '|cFF888888'.. tostring(info.label) ..'|r') + SetCVar(info.cVar, 1) + elseif info.filterKey then + if db.UsedFilters[info.filterKey] then + db.UsedFilters[info.filterKey] = nil end - SetCVar(info.cVar, 1) end end + parent.cvarFiltersDirty = false + --WorldPlan:print('All filters reset.') elseif cVar then - WorldPlan:print('Toggling cvar filter:', cVar) - if (not parent.isDirty) or resetMode then - for i, info in ipairs(DEFAULT_FILTER_LIST) do + if resetMode then + print('|cFFFF4400cleaning dirty') + for i, info in ipairs(db.DefaultFilters) do if info.cVar then - local value = GetCVar(info.cVar) - if resetMode then - value = 1 - parent.isDirty = nil - else - - if (cVar ~= info.cVar) then - value = 0 - else - value = 1 - end - setDirty = true - - end - SetCVar(info.cVar, value) + parent.cvarFiltersDirty = false + SetCVar(info.cVar, 1) end end - if setDirty then - parent.isDirty = true + --WorldPlan:print('Reward filters reset.') + elseif parent.cvarFiltersDirty == true then + if GetCVarBool(cVar) then + tinsert(filtered_report, FILTER_EXCLUDE_TYPE:format(tostring(self.info.label))) + SetCVar(cVar, 0) + else + + tinsert(filtered_report, FILTER_INCLUDE_TYPE:format(tostring(self.info.label))) + SetCVar(cVar, 1) + end + + -- check the visible filters and consider it clean if they're all lit + parent.cvarFiltersDirty = false + for i, info in ipairs(parent.filterList) do + if info.cVar and (#info.questList >= 1) then + print(info.cVar, GetCVarBool(info.cVar)) + if GetCVarBool(info.cVar) == false then + parent.cvarFiltersDirty = true + print('|cFFFF4400still dirty') + break + end + end end else - SetCVar(cVar, (GetCVarBool(cVar) and 0) or 1) + print('|cFFFF4400making dirty') + for i, info in ipairs(db.DefaultFilters) do + if info.cVar then + local msgType = (cVar == info.cVar) and FILTER_INCLUDE_TYPE or FILTER_EXCLUDE_TYPE + SetCVar(info.cVar, ((cVar == info.cVar) and 1) or 0) + tinsert(filtered_report, msgType:format(info.label)) + end + end + parent.cvarFiltersDirty = true end else - local flushValue - print('') - if WorldPlan.UsedFilters[filterKey] == filterValue then - WorldPlan.UsedFilters[filterKey] = nil - tinsert(filtered_report, '|cFFFF0000'.. tostring(filterKey) ..'|r') + if resetMode then + wipe(db.UsedFilters) + --WorldPlan:print('Type filters reset.') else - WorldPlan.UsedFilters[filterKey] = filterValue - tinsert(filtered_report, '|cFF00FF00'.. tostring(filterKey) ..'|r') + if (db.UsedFilters[filterKey] == filterValue) or resetMode then + db.UsedFilters[filterKey] = nil + tinsert(filtered_report, FILTER_INCLUDE_TYPE:format(tostring(filterKey))) + else + db.UsedFilters[filterKey] = filterValue + tinsert(filtered_report, FILTER_EXCLUDE_TYPE:format(tostring(filterKey))) + end end end - WorldPlan:print('Changed:', table.concat(filtered_report, ', ')) + if #filtered_report >= 1 then + --WorldPlan:print('Setting filter(s):', table.concat(filtered_report, ', ')) + end WorldPlan:Refresh(true) end \ No newline at end of file
--- a/FilterBar.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/FilterBar.xml Sun Dec 25 13:04:57 2016 -0500 @@ -8,14 +8,45 @@ <OnShow method="OnShow" /> </Scripts> + <Layers> + <Layer level="OVERLAY"> + <Texture parentKey="CVarsHighlight"> + <Color a=".5" r="1" g="1" b="1" /> + </Texture> + </Layer> + </Layers> </Frame> - <Button name="WorldPlanFilterPin" virtual="true" inherits="WorldPlanQuestPin" mixin="WorldPlanFilterPinMixin"> + <Button name="WorldPlanFilterPin" virtual="true" mixin="WorldPlanFilterPinMixin"> <Scripts> - <OnMouseDown method="OnMouseDown" /> <OnClick method="OnClick" /> <OnLoad method="OnLoad" /> + <OnEvent method="OnEvent" /> + <OnUpdate method="OnUpdate" /> + <OnShow method="OnShow" /> + <OnHide method="OnHide" /> + <OnMouseDown method="OnMouseDown" /> <OnEnter method="OnEnter" /> <OnLeave method="OnLeave" /> </Scripts> + <Layers> + <Layer level="BACKGROUND"> + <Texture parentKey="RewardBorder" setAllPoints="true" /> + </Layer> + <Layer level="ARTWORK"> + <Texture parentKey="icon"> + <Anchors> + <Anchor point="BOTTOMLEFT" x="1" y="1" /> + <Anchor point="TOPRIGHT" x="-1" y="-1" /> + </Anchors> + </Texture> + </Layer> + <Layer level="OVERLAY"> + <FontString parentKey="count" inherits="WorldPlanNumberFontThin"> + <Anchors> + <Anchor point="RIGHT" x="-3" /> + </Anchors> + </FontString> + </Layer> + </Layers> </Button> </Ui> \ No newline at end of file
--- a/FlightMap.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/FlightMap.lua Sun Dec 25 13:04:57 2016 -0500 @@ -1,4 +1,4 @@ - +local _, db = ... local print = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or function() end local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local wipe, pairs, ipairs = wipe, pairs, ipairs @@ -36,6 +36,13 @@ end end +function WorldPlanDataProvider:OnLoad() + + self:SetNudgeTargetFactor(0.015); + self:SetNudgeZoomedOutFactor(1.0); + self:SetNudgeZoomedInFactor(0.25); +end + function WorldPlanDataProvider:OnShow() assert(self.ticker == nil); self.ticker = C_Timer.NewTicker(10, function() self:RefreshAllData() end); @@ -69,7 +76,9 @@ for questId in pairs(self.activePins) do pinsToRemove[questId] = true; end - + print(unpack(db.Config.FlightMapAlphaLimits)) + local alpha1, alpha2, alpha3 = unpack(db.Config.FlightMapAlphaLimits) + local scale1, scale2, scale3 = unpack(db.Config.FlightMapScalingLimits) local mapAreaID = self:GetMap():GetMapID(); for zoneIndex = 1, C_MapCanvas.GetNumZones(mapAreaID) do @@ -82,8 +91,11 @@ for i, info in ipairs(taskInfo) do if HaveQuestData(info.questId) then if QuestUtils_IsQuestWorldQuest(info.questId) then - local pin = WorldPlanQuests:AcquirePin(info.questId, zoneMapID) - pin:RefreshData(info) + local pin = db.QuestsByID[info.questId] + if not db.QuestsByID[info.questId] then + pin = WorldPlanQuests:AcquirePin(info, zoneMapID) + end + pin:IsShowable() if pin.used then print(i, pin.x, pin.y, pin.used, pin.isNew, pin.isStale, pin:IsShown(), pin:GetAlpha()) @@ -92,8 +104,10 @@ local frame = self.activePins[info.questId] if not frame then frame = self:GetMap():AcquirePin("WorldPlanFlightPin") - frame:SetAlphaLimits(1, 0.7, 1) - frame:SetScalingLimits(1, 3, 1.5); + print(alpha1, alpha2, alpha3) + print(scale1, scale2, scale3) + frame:SetAlphaLimits(alpha1, alpha2, alpha3) + frame:SetScalingLimits(scale1, scale2, scale3); frame:SetFrameLevel(1000 + self:GetMap():GetNumActivePinsByTemplate("WorldPlanFlightPin")); frame:Show() self.activePins[info.questId] = frame @@ -101,7 +115,7 @@ frame:SetPosition(info.x, info.y) frame.pin = pin - pin.owningFrame = self:GetMap() + pin.owningFrame = frame:GetMap() pin.isStale = true pin:SetParent(frame) pin:ClearAllPoints() @@ -127,21 +141,15 @@ end function WorldPlanDataProvider:OnEvent() - for pin in self:GetMap():EnumeratePinsByTemplate("WorldQuestPinTemplate") do - pin:Hide() - end end function WorldPlanDataPinMixin:OnShow() - print('|cFFFFFF00'..tostring(self:GetName())..':OnShow()|r') end function WorldPlanDataPinMixin:OnMouseEnter () - end function WorldPlanDataPinMixin:OnMouseLeave () - end function WorldPlanDataPinMixin:RemoveAllData()
--- a/FlightMap.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/FlightMap.xml Sun Dec 25 13:04:57 2016 -0500 @@ -12,7 +12,7 @@ </Scripts> </Frame> - <Frame name="WorldPlanFlightPin" mixin="WorldPlanDataPinMixin" hidden="true" flattenRenderLayers="true" frameStrata="MEDIUM" enableMouseMotion="true" virtual="true"> + <Frame name="WorldPlanFlightPin" mixin="WorldPlanDataPinMixin" hidden="true" flattenRenderLayers="true" frameStrata="MEDIUM" enableMouse="false" enableMouseMotion="true" virtual="true"> <Size x="50" y="50"/> </Frame> </Ui> \ No newline at end of file
--- a/QuestPOI.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/QuestPOI.lua Sun Dec 25 13:04:57 2016 -0500 @@ -3,6 +3,7 @@ -- Created: 10/1/2016 7:21 PM -- %file-revision% -- +local _, db = ... local TQ_GetQuestInfoByQuestID = C_TaskQuest.GetQuestInfoByQuestID -- Return the name of a quest with a given ID local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation @@ -12,6 +13,9 @@ local QuestPOIGetIconInfo, WorldMapPOIFrame = QuestPOIGetIconInfo, WorldMapPOIFrame local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest +local GetAchievementNumCriteria, GetAchievementCriteriaInfo, GetAchievementInfo = GetAchievementNumCriteria, GetAchievementCriteriaInfo, GetAchievementInfo +local pairs, ipairs, tinsert, unpack, select = pairs, ipairs, tinsert, unpack, select +local floor, mod, tostring, tonumber, GetSuperTrackedQuestID = floor, mod, tostring, tonumber, GetSuperTrackedQuestID local GameTooltip = GameTooltip local GetItemIcon = GetItemIcon @@ -20,17 +24,18 @@ local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end +local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or function() end local QuestPOI = WorldPlanPOIMixin + +local PIN_REFRESH_DELAY = .5 +local PIN_REQUEST_DELAY = .2 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" -local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background" -local POI_BORDER_FILL = "Interface\\BUTTONS\\YELLOWORANGE64" -local POI_BORDER_BLUE = "Interface\\BUTTONS\\GRADBLUE" -local POI_BORDER_RED = "Interface\\BUTTONS\\RedGrad64" -local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64" -local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64" +local WORLD_QUEST_BORDER = "Interface\\UNITPOWERBARALT\\Generic1Target_Circular_Frame" +local PENDING_BORDER +local PENDING_ICON = "Interface\\BUTTONS\\YELLOWORANGE64" local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER @@ -38,7 +43,6 @@ local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS - local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON @@ -51,226 +55,294 @@ local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL -local subStyles = { - continent = { - iconWidth = 14, - borderWidth = 2, - highlightWidth = 1, - TagSize = 6, - maxAlertLevel = 0, - showNumber = false, - numberFontObject = 'WorldPlanFont' - }, - zone = { - iconWidth = 22, - borderWidth = 3, - highlightWidth = 2, - TagSize = 12, - maxAlertLevel = 3, - showNumber = true, - numberFontObject = 'WorldPlanNumberFontThin' - }, - minimized = { - iconWidth = 4, - borderWidth = 0, - highlightWidth = 1, - NoIcon = true, - maxAlertLevel = 1, - showNumber = false, - } -} +local STYLE_TYPE_PENDING = 768 + -- Pin color/display variables +db.TooltipExtras = db.TooltipExtras or {} -- idiot-proofing + local familiars = { - [42159] = {npc = 106552, name = 'Nightwatcher Merayl'}, - [40277] = {npc = 97804, name = 'Tiffany Nelson'}, - [40298] = {npc = 99182, name = 'Sir Galveston'}, - [40282] = {npc= 99150, name = 'Grixis Tinypop'}, - [40278] = {npc = 98270, name = 'Robert Craig'}, - [48195] = {npc = 105250, name = 'Aulier'}, - [41990] = {npc = 105674, name = 'Varenne'}, - [41860] = {npc = 104970, name = 'Xorvasc'}, - [40299] = {npc = 99210, name = 'Bodhi Sunwayver'}, - [42442] = {npc = 107489, name = 'Amalia'}, - [40280] = {npc = 99077, name = 'Bredda Tenderhide'}, - [41687] = {npc = 104553, name = 'Odrogg'}, - [41944] = {npc = 105455, name = 'Trapper Jarrun'}, - [40337] = {npc = 97709, name = 'Master Tamer Flummox'}, - [40279] = {npc = 99035, name = 'Durian Strongfruit'} + [42159] = 'Nightwatcher Merayl', + [40277] = 'Tiffany Nelson', + [40298] = 'Sir Galveston', + [40282] = 'Grixis Tinypop', + [40278] = 'Robert Craig', + [48195] = 'Aulier', + [41990] = 'Varenne', + [41860] = 'Xorvasc', + [40299] = 'Bodhi Sunwayver', + [42442] = 'Amalia', + [40280] = 'Bredda Tenderhide', + [41687] = 'Odrogg', + [41944] = 'Trapper Jarrun', + [40337] = 'Master Tamer Flummox', + [40279] = 'Durian Strongfruit' +} +local falcosaurs = { + [44895] = {44881, 'Sharptalon Hatchling', 115786}, + [44894] = {44882, 'Bloodgazer Hatchling', 115787}, + [44893] = {44880, 'Direbeak Hatchling', 115785}, + [44892] = {44879, 'Snowfeather Hatchling', 115784}, } local familiars_id = 9696 +for questID, name in pairs(familiars) do + db.TooltipExtras[questID] = {{ + achievementID = familiars_id, + name = name + }} +end +for questID, info in pairs(falcosaurs) do + local trackingQuestID, petName, petID = unpack(info) - --- update a masked texture without messing up its blending mask - - --- update a masked texture without messing up its blending mask -local SetMaskedTexture = function(region, file, mask) - mask = mask or "Interface\\Minimap\\UI-Minimap-Background" - region:SetMask(nil) - region:SetTexture(file) - region:SetMask(mask) + db.TooltipExtras[questID] = {{ + questID = trackingQuestID, + pet = petName, + petID = petID + }} end +local GetAchievementTooltipExtras = function(info) --- use tooltip object to extract item details -local ParseItemReward = function(questID) - local name, icon, quantity, quality, _, itemID = GetQuestLogRewardInfo(1, questID) - local scanner = _G.WorldPlanTooltip - if not itemID then - return + local hasInfo + local achievementID = info.achievementID + local _, name, _, completed, _, _, _, _, _, icon = GetAchievementInfo(achievementID) + if not completed then + + WorldMapTooltip:AddLine(" ") + WorldMapTooltip:AddLine("Achievements:") + WorldMapTooltip:AddLine(' |T'..icon..':20:20|t '..name) + + local numItems = GetAchievementNumCriteria(achievementID) + local numNeeded = 0 + local tooltipLines = {} + for i =1, numItems do + local criteriaName, criteriaType, completed, _, _, _, _, subAchievementID = GetAchievementCriteriaInfo(achievementID, i) + print(GetAchievementCriteriaInfo(achievementID, i)) + + if not completed then + print('::', criteriaName, completed, subAchievementID) + if criteriaType == 8 then + local _, _, _, completed, _, _, _, _, _, subIcon = GetAchievementInfo(subAchievementID) + print(' -', criteriaName, completed, subIcon) + if not completed then + local numCompleted = 0 + local numSubItems = GetAchievementNumCriteria(subAchievementID) + local subCriteriaLine + for j = 1, numSubItems do + local subName, _, completed = GetAchievementCriteriaInfo(subAchievementID, j) + + print(' -',subName, completed) + if completed then + numCompleted = numCompleted + 1 + else + numNeeded = numNeeded + 1 + if subName:match(info.name) then + hasInfo = true + subCriteriaLine = ' |T'..subIcon..':16:16|t ' .. criteriaName + end + end + + end + if subCriteriaLine then + tinsert(tooltipLines, subCriteriaLine .. ' ('..numCompleted..'/'..numSubItems..')') + end + end + elseif criteriaName:match(info.name) and (not completed) then + numNeeded = numNeeded + 1 + tinsert(tooltipLines, criteriaName) + end + end + end + if numNeeded >= 1 then + for i, line in ipairs(tooltipLines) do + WorldMapTooltip:AddLine(line) + end + else + WorldMapTooltip:AddLine('Criteria completed!', 0, 1, 0) + end + + end + return hasInfo +end + +local GetQuestTooltipExtras = function(info) + local questID = info.questID + local hasInfo + + if info.pet then + local index, guid = C_PetJournal.FindPetIDByName(info.pet) + if not index then + hasInfo = true + WorldMapTooltip:AddLine('Pets:') + WorldMapTooltip:AddLine(' - ' .. info.petName) + + if not IsQuestFlaggedCompleted(questID) then + WorldMapTooltip:AddLine(' Required Quest Flags', 1, 1, 0) + else + WorldMapTooltip:AddLine(' Quest Flags Complete!', 0, 1, 0) + end + + end end - scanner:SetOwner(WorldPlan, "ANCHOR_NONE") - scanner:SetItemByID(itemID) - scanner:Show() - local ttl1 = _G['WorldPlanTooltipTextLeft1'] - local ttl2 = _G['WorldPlanTooltipTextLeft2'] - local ttl3 = _G['WorldPlanTooltipTextLeft3'] - local ttl4 = _G['WorldPlanTooltipTextLeft4'] - if ttl2 then - local text = ttl2:GetText() - -- Artifact Power - if text then - if text:match("|cFFE6CC80") then - --print('AP token!', text) - local power - if ttl4 then - local text = ttl4:GetText() - --print('tip line 4', text) - if text then - power = text:gsub("%p", ""):match("%d+") - power = tonumber(power) - end - - end - return REWARD_ARTIFACT_POWER, "Interface\\ICONS\\inv_7xp_inscription_talenttome01", power, name, itemID, quality - elseif text:match("Item Level") then - --print('equipment!', text) - quantity = text:match("Item Level ([%d\+]+)") - return REWARD_GEAR, icon, quantity, name, itemID, quality - elseif text:match("Crafting Reagent") then - --print('|cFFFF4400it is a reagent', text) - return REWARD_REAGENT, icon, quantity, name, itemID, quality - end - end - - elseif ttl3 then - local text = ttl3:GetText() - if text:match("Crafting Reagent") then - --print('|cFFFF4400it is a reagent', text) - return REWARD_REAGENT, icon, quantity, name, itemID, quality - end - end - return 128, icon, quantity, name, itemID, quality end -function WorldPlanPOIMixin:OnEnter() - if WorldMapFrame:IsVisible() then - WorldMapTooltip:SetOwner(self, 'ANCHOR_RIGHT') +local GetFactionInfoByID, GetQuestObjectiveInfo = GetFactionInfoByID, GetQuestObjectiveInfo + +function QuestPOI:OnEnter() + if not WorldMapFrame:IsVisible() then + WorldMap_HijackTooltip(self.owningFrame) else - WorldMap_HijackTooltip(self.owningFrame) - end - - local completed = select(4,GetAchievementInfo(familiars_id)) - if not completed then - if self.worldQuestType == LE_QUEST_TAG_TYPE_PET_BATTLE and familiars[self.questID] then - - WorldMapTooltip:AddLine(self.title, 1, 1, 1) - if self.quality then - local c = ITEM_QUALITY_COLORS[self.quality] - WorldMapTooltip:AddLine(" ") - WorldMapTooltip:AddLine('Rewards') - WorldMapTooltip:AddLine(self.itemName .. (self.quantity and (' x'..self.quantity) or ''), c.r, c.g, c.b) - WorldMapTooltip:AddTexture(self.itemTexture) - - local cLine = WorldMapTooltip:NumLines() - local line = _G['WorldMapTooltipTextLeft'..cLine] - local pline = _G['WorldMapTooltipTextLeft'..(cLine-1)] - local icon = _G['WorldMapTooltipTexture'..(cLine-3)] - icon:SetSize(24,24) - icon:ClearAllPoints() - icon:SetPoint('TOPLEFT', pline, 'BOTTOMLEFT', 0, -2) - line:ClearAllPoints() - line:SetPoint('TOPLEFT', icon, 'TOPRIGHT', 7, 0) - - --- voodoo workaround for IDs getting coerced to string - if type(self.itemTexture) == 'number' then - icon:Show() - icon:SetTexture(self.itemTexture) - end - end - - - WorldMapTooltip:AddLine(" ") -- causes crash for some reason - WorldMapTooltip:AddLine('Family Familiars') - local trainer = familiars[self.questID].name - local numCheevs = GetAchievementNumCriteria(familiars_id) - for index = 1, numCheevs do - local cheevName, cType, cCompleted, quantity, requiredQuantity, charName, flags, cheevID, quantityString, criteriaID = GetAchievementCriteriaInfo(familiars_id, index) - local numTrainers = GetAchievementNumCriteria(cheevID) - for subIndex = 1, numTrainers do - local desc, cType, partCompleted = GetAchievementCriteriaInfo(cheevID, subIndex) - if desc == trainer then - if not partCompleted then - local iconPath = select(10, GetAchievementInfo(cheevID)) - WorldMapTooltip:AddLine(cheevName) - WorldMapTooltip:AddTexture(iconPath) - end - end - end - end - WorldMapTooltip:Show() + if self.filtered then return end end - TaskPOI_OnEnter(self) + WorldMapTooltip:SetOwner(self, "ANCHOR_RIGHT"); + print('doing tooltip stuff') + + -- Can't add stuff after, so most of the blizzard tooltip hook is simply copied over + local questID = self.questID + local color = WORLD_QUEST_QUALITY_COLORS[self.rarity] or NORMAL_FONT_COLOR; + + + WorldMapTooltip:SetText(self.title, color.r, color.g, color.b); + QuestUtils_AddQuestTypeToTooltip(WorldMapTooltip, questID, NORMAL_FONT_COLOR); + + if ( self.factionID ) then + local factionName = GetFactionInfoByID(self.factionID); + if ( factionName ) then + if (self.capped) then + WorldMapTooltip:AddLine(factionName, GRAY_FONT_COLOR:GetRGB()); + else + WorldMapTooltip:AddLine(factionName); + end + end + end + + if self.worldQuest then + WorldMap_AddQuestTimeToTooltip(questID); + end + + + for objectiveIndex = 1, self.numObjectives do + local objectiveText, objectiveType, finished = GetQuestObjectiveInfo(questID, objectiveIndex, false); + if ( objectiveText and #objectiveText > 0 ) then + local color = finished and GRAY_FONT_COLOR or HIGHLIGHT_FONT_COLOR; + WorldMapTooltip:AddLine(QUEST_DASH .. objectiveText, color.r, color.g, color.b, true); + end + end + + local percent = C_TaskQuest.GetQuestProgressBarInfo(self.questID); + if ( percent ) then + GameTooltip_InsertFrame(WorldMapTooltip, WorldMapTaskTooltipStatusBar); + WorldMapTaskTooltipStatusBar.Bar:SetValue(percent); + WorldMapTaskTooltipStatusBar.Bar.Label:SetFormattedText(PERCENTAGE_STRING, percent); + end + + if db.TooltipExtras[self.questID] then + for index, info in pairs(db.TooltipExtras[questID]) do + if info.achievementID then + GetAchievementTooltipExtras(info) + end + if info.questID then + GetQuestTooltipExtras(info) + end + end + end + WorldMap_AddQuestRewardsToTooltip(questID) + + self.MouseGlow:Show() + WorldMapTooltip:Show() + --WorldMapTooltip.recalculatePadding = true; + --print(WorldMapTooltip:GetParent()) + --print(WorldMapTooltip:IsVisible()) end -function WorldPlanPOIMixin:OnLeave() +function QuestPOI:OnLeave() WorldMap_RestoreTooltip() - TaskPOI_OnLeave(self) + self.MouseGlow:Hide() + WorldMapTooltip:Hide(); end -function WorldPlanPOIMixin:OnMouseDown() +function QuestPOI:OnMouseDown() TaskPOI_OnClick(self) end - - --- create or update the pin using the given questID and C_TaskQuest results -function WorldPlanPOIMixin:RefreshData (info) - - qprint('|cFF00FF88'..self:GetName()..':RefreshData()|r') - - if info then - self.inProgress = info.inProgress - self.floor = info.floor - self.numObjectives = info.numObjectives or 0 - if info.x and info.y then - self.x = info.x or self.x - self.y = info.y or self.y - --qprint('|cFFFF4400applying taskInfo coords:', info.x, info.y) - end - +-- attempt to pull pin data +local GetQuestTagInfo, GetProfessionInfo = GetQuestTagInfo, GetProfessionInfo +function QuestPOI:GetData () + qprint('|cFF00FF88'..self:GetName()..':GetWorldQuestInfo()|r') + local questID = self.questID + if not questID then + rprint('|cFFFF4400bad pin|r', self:GetName()) + return nil end + local questTitle, factionID, capped = TQ_GetQuestInfoByQuestID(questID) + -- if the title is nil, then wait and try later + if not questTitle then + self.isPending = true + rprint('|cFFBB8844nodata|r|cFF00FFFF', self.questId) + else + self.title, self.factionID, self.capped = questTitle, factionID, capped + rprint('|cFFBB8844 data|r|cFF00FFFF', (self.isPending and 'late|r' or 'jit|r'), self.title, '|r', self.factionID) + -- set tag details + local worldQuestType + self.tagID, self.tagName, worldQuestType, self.rarity, self.isElite, self.tradeskillLineIndex = GetQuestTagInfo(questID); + local tagAtlas + if worldQuestType == LE_QUEST_TAG_TYPE_PET_BATTLE then + tagAtlas = "worldquest-icon-petbattle" + elseif worldQuestType == LE_QUEST_TAG_TYPE_PVP then + tagAtlas = "worldquest-icon-pvp-ffa" + elseif worldQuestType == LE_QUEST_TAG_TYPE_PROFESSION then + self.isKnownProfession = nil + local id = self.tradeskillLineIndex and select(7, GetProfessionInfo(self.tradeskillLineIndex)) + if id then + self.isKnownProfession = true + qprint('profession' , self.title, id) + tagAtlas = WORLD_QUEST_ICONS_BY_PROFESSION[id] + end + elseif worldQuestType == LE_QUEST_TAG_TYPE_DUNGEON then + tagAtlas = "worldquest-icon-dungeon" + end + self.worldQuestType = worldQuestType - local questID = self:GetID() - local questTitle, rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality, _ - local hasUpdate, isPending = (self.isStale or self.isNew), self.isPending + self.tagAtlas = tagAtlas + self:SetRewardInfo() + + -- force throttle on success + --qprint(' |cFF00FFFF'..questID..'|r hasUpdate:', hasUpdate, 'isPending:', isPending, 'isShown', self:IsShown()) + --qprint(' ', 'rewardType:', self.rewardType, 'tag:', self.tagID) + qprint(' ', tostring(self.title), " |T"..tostring(self.itemTexture)..":12:12|t", tostring(self.itemName)) + + if self.itemTexture and self.itemName and self.title then + self.isPending = nil + self.throttle = 1 + self.updateRate = PIN_REFRESH_DELAY + end + end + + self.isCriteria = WorldMapFrame.UIElementsFrame.BountyBoard:IsWorldQuestCriteriaForSelectedBounty(questID) + + return self.isStale, self.isPending +end + +local GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, HaveQuestData = GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, HaveQuestData +local GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString +function QuestPOI:SetRewardInfo() + local questID = self.questID if not HaveQuestData(questID) then - TQ_RequestPreloadRewardData(questID) - isPending = true + self.isPending = true else + local rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality -- set reward category local numRewards = GetNumQuestLogRewards(questID) local numCurrency = GetNumQuestLogRewardCurrencies(questID) local money = GetQuestLogRewardMoney(questID) if numRewards >= 1 then - rewardType, rewardIcon, rewardCount, rewardName, itemID, quality = ParseItemReward(questID) + rewardType, rewardIcon, rewardCount, rewardName, itemID, quality = WorldPlanQuests:GetRewardHeader(questID) elseif numCurrency >= 1 then rewardName, rewardIcon, rewardCount = GetQuestLogRewardCurrencyInfo(1, questID) rewardType = REWARD_CURRENCY @@ -279,84 +351,40 @@ rewardName = GetMoneyString(money) rewardType = REWARD_CASH end - rewardStyle = self:GetTypeInfo(rewardType) - self.itemNumber = rewardCount or self.itemNumber - self.rewardType = rewardType or REWARD_ITEM - self.style = rewardStyle + print(' '..self.questID..':|cFFFFFF00SetRewardInfo():', rewardType) + self.itemNumber = tonumber(rewardCount or self.itemNumber) + self.rewardType = rewardType or REWARD_GEAR self.quality = quality - -- title, faction, capped state - local questTitle, factionID, capped = TQ_GetQuestInfoByQuestID(questID) - self.factionID = factionID - self.capped = capped - - -- set tag details - local tagID, tagName, worldQuestType, rarity, isElite, tradeskillLineIndex = GetQuestTagInfo(questID); - local tagAtlas - if worldQuestType == LE_QUEST_TAG_TYPE_PET_BATTLE then - tagAtlas = "worldquest-icon-petbattle" - elseif worldQuestType == LE_QUEST_TAG_TYPE_PVP then - tagAtlas = "worldquest-icon-pvp-ffa" - elseif worldQuestType == LE_QUEST_TAG_TYPE_PROFESSION then - local id = tradeskillLineIndex and select(7, GetProfessionInfo(tradeskillLineIndex)) - if id then - tagAtlas = WORLD_QUEST_ICONS_BY_PROFESSION[id] - end - elseif worldQuestType == LE_QUEST_TAG_TYPE_DUNGEON then - tagAtlas = "worldquest-icon-dungeon" - end - - self.tagID = tagID - self.tagName = tagName - self.worldQuestType = worldQuestType - self.isElite = isElite - self.tradeskillLineIndex = tradeskillLineIndex - self.rarity = rarity - self.tagAtlas = tagAtlas + self.itemTexture = rewardIcon or self.itemTexture + self.itemName = rewardName or self.itemName -- flag unresolved info if not (rewardIcon and rewardName) then - isPending = true - qprint('because not have icon') - TQ_RequestPreloadRewardData (questID) + self.isPending = true + return true, nil --WorldPlan:print('|cFFFFFF00'..tostring(self.title)..'|r waiting on texture info') else - if (rewardIcon and rewardName) and isPending then + if (rewardIcon and rewardName) and self.isPending then --WorldPlan:print('|cFF00FF00'..tostring(self.title)..'|r has info', rewardIcon, rewardName) - hasUpdate = true + self.isStale = true end - isPending = false + self.isPending = nil end - self.title = questTitle or "|cFFFF0000Retrieving..." - self.itemTexture = rewardIcon or self.itemTexture - self.itemName = rewardName or self.itemName - self.isStale = hasUpdate - self.isPending = isPending + end + return self.isStale, self.isPending - - --qprint(' |cFF00FFFF'..questID..'|r hasUpdate:', hasUpdate, 'isPending:', isPending, 'isShown', self:IsShown()) - --qprint(' ', 'rewardType:', self.rewardType, 'tag:', self.tagID) - --qprint(' ', tostring(self.title), " |T"..tostring(self.itemTexture)..":12:12|t", tostring(self.itemName)) - end - self.cheevos = familiars[self.questID] - - return hasUpdate, isPending -end - - -function WorldPlanPOIMixin:SetAchievementProgressTooltip() - print('cheevos') end -- run from OnShow if .isNew is set -function WorldPlanPOIMixin:OnNew() +function QuestPOI:OnNew() if not self.isAnimating then --qprint('|cFFFFFF00'.. self.title .. ' added to quest log.') self:SetAlpha(0) - if WorldPlan.db.FadeWhileGrouped then + if db.Config.FadeWhileGrouped then self.FadeIn.FadeIn:SetToAlpha(0.15) self.PendingFade.FadeIn:SetToAlpha(0.15) self.PendingFade.FadeOut:SetFromAlpha(0.15) @@ -367,11 +395,12 @@ end self.isAnimating = true self.isNew = nil + self.isStale = true self.FadeIn:Play() end end -function WorldPlanPOIMixin:OnShow () +function QuestPOI:OnShow () -- pop this on principle if self.isNew or self.isStale then @@ -392,7 +421,7 @@ --WorldPlan:print(self:GetAlpha()) end -function WorldPlanPOIMixin:OnHide() +function QuestPOI:OnHide() --qprint('|cFFFFFF00["'..tostring(self.title)..'"]|r:OnHide()') if not self:IsShown() then self.isAnimating = nil @@ -402,8 +431,8 @@ self.Overlay:SetShown(false) end -function WorldPlanPOIMixin:SetAnchor(frame, mapID, mapWidth, mapHeight) - --qprint(' |cFF00FF00'..self:GetName()..':SetAnchor()|r', self.questID, mapID, mapWidth) +function QuestPOI:SetAnchor(frame, mapID, mapWidth, mapHeight) + qprint(' |cFF00FF00'..self:GetName()..':SetAnchor()|r', self.questID, mapID) self:ClearAllPoints() local dX, dY = TQ_GetQuestLocation(self.questID) if not dX or dX == 0 then @@ -414,50 +443,53 @@ dX, dY = self.x, self.y end end + local oX, oY = self.x, self.y self.x = dX self.y = dY - --qprint(' |cFF00FF00'..self.questID..':|r', format("%0.2f %0.2f", dX, dY)) local pX = (dX * mapWidth) local pY = (-dY * mapHeight) + if oX ~= dX then + wqprint(' |cFF00FF00'..self.questID..':|r', oX, dX, format("%0.2f %0.2f", pX, pY)) + end + self:SetParent(WorldMapPOIFrame) self:SetPoint('CENTER', frame, 'TOPLEFT', pX, pY) end - -function WorldPlanPOIMixin:OnLoad() - qprint('|cFF00FF88'..self:GetName()..':OnLoad()|r',WorldPlan.db) +function QuestPOI:OnLoad() + qprint('|cFF00FF88'..self:GetName()..':OnLoad()|r',db.Config) self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') + self.title = '|cFF0088FF' .. RETRIEVING_DATA..'|r' + self.isPending = true self.count = self.Overlay.count self.timeLabel = self.Overlay.timeLabel + self.updateRate = PIN_REQUEST_DELAY + self.itemName = '|cFF0088FF' .. RETRIEVING_DATA..'|r' end -function WorldPlanPOIMixin:OnEvent(event, ...) +function QuestPOI:OnEvent(event, ...) if event == 'SUPER_TRACKED_QUEST_CHANGED' then self.isStale = true end end - -local PIN_UPDATE_DELAY = .016 -local TOP_PIN_ID -function WorldPlanPOIMixin:OnUpdate (sinceLast) +function QuestPOI:OnUpdate (sinceLast) + -- control update check intervals + self.throttle = (self.throttle or self.updateRate) + sinceLast + if self.throttle >= self.updateRate then + -- factor overtime into the throttle timer + self.throttle = self.throttle - self.updateRate + else + return + end if self.isNew then print('|cFFFFFF00push new poi stuff') self:OnNew() - end - -- control update check intervals - self.throttle = (self.throttle or PIN_UPDATE_DELAY) - sinceLast - if self.throttle <= 0 then - -- factor overtime into the throttle timer - self.throttle = PIN_UPDATE_DELAY - self.throttle - else - return - end - if self.isStale and not self.isAnimating then + elseif (self.isStale or (not self.title)) and not self.isAnimating then wprint('|cFFFFFF00push poi update') self:Refresh() return @@ -466,7 +498,7 @@ -- query for reward data if it wasn't found in the original scan local questID = self.questID if self.isPending then - self:RefreshData() + self:GetData() if not (self.PendingFade:IsPlaying() or self.isAnimating) then self.PendingFade:Play() end @@ -479,67 +511,100 @@ -- update time elements - local tl = self.alertLevel - local timeLeft = TQ_GetQuestTimeLeftMinutes(questID) - if timeLeft > 0 then - local text, timeState = WorldPlan:GetTimeInfo(timeLeft, self.maxAlertLevel) - if tl ~= timeState then - tl = timeState - self.timeLabel:SetText(text) - end - else - -- remove self in a timely manner - if not TQ_IsActive(self.questID) then - print('|cFFFF4400'..self:GetName()..' pin hard timeout') + if TQ_IsActive(self.questID) then + + local tl = self.alertLevel + local timeLeft = TQ_GetQuestTimeLeftMinutes(questID) + if timeLeft > 0 then + + local text, timeState = WorldPlan:GetTimeInfo(timeLeft, self.maxAlertLevel) + if tl ~= timeState then + tl = timeState + self.timeLabel:SetText(text) + end + else if self.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION then - self:Hide() + self:SetShown(false) end end + self.alertLevel = tl end - self.alertLevel = tl - - if self:IsMouseOver() then - self.MouseGlow:Show() - else - self.MouseGlow:Hide() - end + self.timeLabel:SetShown(self.worldQuest and (self.maxAlertLevel >= 1)) end -function WorldPlanPOIMixin:Refresh () - local db = WorldPlan.db +function QuestPOI:Refresh () print('|cFF00FF88'..self:GetName()..'|r:Refresh()') - + local styleType = (self.isPending and STYLE_TYPE_PENDING) or self.rewardType + local style,subStyle = self:GetTypeInfo(self.rewardType) + if self.filtered then + subStyle = style.minimized + end + self.style = style + self.subStyle = subStyle + --print(style, subStyle) + self.currentWidth = subStyle.iconWidth + self.borderWidth = subStyle.borderWidth + self.highlightWidth = subStyle.highlightWidth + self.tagSize = subStyle.TagSize + self.maxAlertLevel = subStyle.maxAlertLevel + self.NoIcon = subStyle.NoIcon local questID = self:GetID() local iconBorder = self.RewardBorder local trackingBorder = self.HighlightBorder local icon = self.icon local count = self.count - - - - --WorldPlan:print(tostring(self.title), "|T"..tostring(self.itemTexture)..":16:16|t", tostring(self.itemName)) - - if self.itemName then --wqprint('filtered:', self.filtered, 'showNumber:', self.showNumber) + if self.itemNumber and self.itemNumber >= 1000 then + local numeral = floor(self.itemNumber/1000) + local decimal = mod(self.itemNumber, 1000) + local numberString = numeral + if decimal > 100 then + numberString = numberString .. '.' .. tostring(floor(decimal/100)) + end + numberString = numberString .. 'k' + self.count:SetText(numberString) + else + self.count:SetText(self.itemNumber) + end - self.count:SetText(self.itemNumber) + end + icon:SetMask("Interface\\Minimap\\UI-Minimap-Background") if self.itemTexture then - icon:SetTexture(self.itemTexture) - icon:SetMask("Interface\\Minimap\\UI-Minimap-Background") + iconBorder:SetTexture(WORLD_QUEST_BORDER) + + if self.NoIcon then + icon:SetTexture(PENDING_ICON) + icon:SetDesaturated(true) + icon:SetVertexColor(style.r, style.g, style.b, style.a) + else + + icon:SetTexture(self.itemTexture) + icon:SetDesaturated(false) + icon:SetVertexColor(1, 1, 1) + end + else + iconBorder:SetTexture(PENDING_BORDER) + icon:SetTexture(PENDING_ICON) + icon:SetDesaturated(true) + icon:SetVertexColor(style.r, style.g, style.b, style.a) end - local border = self:GetTypeInfo(self.rewardType) - iconBorder:SetVertexColor(border.r, border.g, border.b, border.a) + local borderStyle = style + if self.rarity and WORLD_QUEST_QUALITY_COLORS[self.rarity] then + borderStyle = WORLD_QUEST_QUALITY_COLORS[self.rarity] + end + + iconBorder:SetVertexColor(borderStyle.r, borderStyle.g, borderStyle.b, 1) iconBorder:SetDesaturated(true) - + iconBorder:SetAlpha(subStyle.alpha or 1) if questID == GetSuperTrackedQuestID() then trackingBorder:SetVertexColor(0,0,0,1) @@ -547,12 +612,10 @@ trackingBorder:SetVertexColor(0,0,0,0.5) end + self.tagIcon:SetShown(self.tagSize and true or false) self.tagIcon:SetAtlas(self.tagAtlas) - self.tagIcon:SetTexCoord(0,1,0,1) + self.tagIcon:SetAlpha(subStyle.alpha or 1) self.EliteBorder:SetShown(self.isElite and not self.filtered) - --qprint('|cFF88FF00updated', questID, self.title, self.rewardType, (style.showNumber and self.itemNumber) or '') - --print(' - subStyle:', (self.filtered == true), self.subStyle) - self.Overlay:SetShown(self:IsShown()) self.Overlay:SetParent(self:GetParent()) self.Overlay:SetFrameLevel(self:GetFrameLevel()+200) @@ -560,9 +623,7 @@ self:UpdateSize() - self.isStale = nil - end local cvar_check = { @@ -574,44 +635,44 @@ } +function QuestPOI:IsFiltered () + for filterKey, value in pairs(db.UsedFilters) do + print('|cFFFF4400', filterKey, self[filterKey]) + if self[filterKey] ~= value then + return true + end + end + if self.rewardType and cvar_check[self.rewardType] then + if self.rewardType == REWARD_CASH then + print('##', cvar_check[self.rewardType], GetCVarBool(cvar_check[self.rewardType])) + end + if not GetCVarBool(cvar_check[self.rewardType]) then + return true + end + end + print(' '..self.questID..':|cFFFFFF00IsFiltered()|r') +end + function QuestPOI:IsShowable () local print = qprint - local db = WorldPlan.db local qType = self.worldQuestType - local rType = self.rewardType - self.filtered = nil - self.used = true - for filterKey, value in pairs(WorldPlan.UsedFilters) do - print('|cFFFF4400', filterKey, self[filterKey]) - if self[filterKey] ~= value then - self.filtered = true + if not self.worldQuest then + print('ignoring showable check') + return self.used, self.filtered + end + self.used = TQ_IsActive(self.questID) + + if qType == LE_QUEST_TAG_TYPE_PROFESSION then + qprint('hide flags:', (not self.isKnownProfession), (db.Config.ShowAllProfessionQuests == false)) + if (not self.isKnownProfession) and (db.Config.ShowAllProfessionQuests == false) then + qprint(self.used) + self.used = nil + qprint(self.used) end end - - self.questId = self:GetID() - if self.rewardType then - if cvar_check[self.rewardType] then - if self.rewardType == REWARD_CASH then - print('##', cvar_check[self.rewardType], GetCVarBool(cvar_check[self.rewardType])) - end - if not GetCVarBool(cvar_check[self.rewardType]) then - self.filtered = true - - end - - end - end - - if not TQ_IsActive(self.questID) then - self.used = nil - elseif qType == LE_QUEST_TAG_TYPE_PROFESSION then - if not (db.ShowAllProfessionQuests or (self.tradeskillLineIndex and GetProfessionInfo(self.tradeskillLineIndex))) then - self.used = nil - end - end - print(' |cFF'.. (((self.rewardType == REWARD_CASH) and 'FFFF00') or '0088FF') ..'IsShowable()|r ', cvar_check[self.rewardType], 'used:', self.used, 'filtered:', self.filtered, self.title) - return self.used, self.filtered + print(' '..self.questID..':|cFFFFFF00IsShowable()|r ', self.used, self.title) + return self.used end function QuestPOI:UpdateTimer (timeLeft, timeType) @@ -621,12 +682,10 @@ --- Fixes icons upon size update function QuestPOI:UpdateSize () - local style,subStyle = self:GetTypeInfo(self.rewardType) - if self.filtered then - subStyle = style.minimized - end - --qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', style, subStyle) + qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', self.style, self.subStyle) + local style = self.style + local subStyle = self.subStyle local icon = self.icon local iconBorder = self.RewardBorder local trackingBorder = self.HighlightBorder @@ -638,6 +697,7 @@ local iconTexture = self.itemTexture + self.tagIcon:SetSize(self.tagSize, self.tagSize) self:SetSize(iconWidth, iconWidth) icon:SetSize(iconWidth, iconWidth) iconBorder:SetSize(borderWidth, borderWidth) @@ -658,50 +718,5 @@ self.count:SetShown((subStyle.showNumber and self.itemNumber) and style.hasNumeric) - --[[ - if self.tagSize then - tag:Show() - tag:ClearAllPoints() - tag:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', borderWidth, -borderWidth) - else - tag:Hide() - end - - if self.NoIcon then - self.icon:Hide() - else - self.icon:Show() - if style.rewardMask then - icon:SetMask(rewardMask) - else - icon:SetMask(iconTexture) - end - if style.pinMask then - iconBorder:Show() - trackingBorder:Show() - iconBorder:SetMask(pinMask) - trackingBorder:SetMask(pinMask) - else - iconBorder:Hide() - trackingBorder:Hide() - end - end - - - icon:SetTexture(iconTexture) - iconBorder:SetTexture(iconBorder:GetTexture()) - trackingBorder:SetTexture(trackingBorder:GetTexture()) - --]] - self.currentWidth = subStyle.iconWidth - self.borderWidth = subStyle.borderWidth - self.highlightWidth = subStyle.highlightWidth - self.tagSize = subStyle.TagSize - self.maxAlertLevel = subStyle.maxAlertLevel - self.NoIcon = subStyle.NoIcon - self.style = style - self.subStyle = subStyle - if self.rewardType == REWARD_CASH then - qprint('using mask:', pinMask or iconTexture, rewardMask or iconTexture, self.used, self.filtered) - end end \ No newline at end of file
--- a/WorldPlan.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/WorldPlan.lua Sun Dec 25 13:04:57 2016 -0500 @@ -1,31 +1,38 @@ -- WorldPlan.lua -- Created: 8/16/2016 8:19 AM -- %file-revision% +local addonFileName, db = ... +local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end +local WP_VERSION = "1.0" +local tinsert, pairs, floor = tinsert, pairs, floor +local tremove, ipairs, wipe, unpack = tremove, ipairs, wipe, unpack +local select, type, tostring, tonumber = select, type, tostring, tonumber +local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS +local BROKEN_ISLES_ID = 1007 +local GetCurrentMapAreaID = GetCurrentMapAreaID +local GetTime, IsLoggedIn = GetTime, IsLoggedIn -WorldPlanCore = { - defaults = {}, - modules = {}, - FilterOptions = {}, - UsedFilters = {}, - QuestsByZone = {}, - QuestsByID = {}, - TaskQueue = {}, -} +-- Define tables here so the pointers match up +WorldPlanCore = { defaults = {}, modules = {}, TaskQueue = {}, } WorldPlanQuestsMixin = { - QuestsByZone = {}, - QuestsByID = {}, - freePins = {}, + UsedPositions = {}, } WorldPlanPOIMixin = {} -local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end -local WP_VERSION = "1.0" -local tinsert, pairs, floor = table.insert, pairs, floor -local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS -local BROKEN_ISLES_ID = 1007 -local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID +WorldPlanSummaryMixin = {} +db.filtersDirty = true +db.questsDirty = true +db.OrderedModules = {} +db.LoadedModules = {} +db.UsedFilters = {} +db.QuestsByZone = {} +db.QuestsByID = {} +db.TasksByID = {} +db.FreePins = {} +db.UsedPins = {} +db.ReportChunks = {} -- default color templates -local DEFAULT_TYPE = { +db.DefaultType = { a = 1, r = 1, g = 1, b = 1, x = 0, y = 0, @@ -34,10 +41,10 @@ rewardMask = "Interface\\Minimap\\UI-Minimap-Background", texture = "Interface\\BUTTONS\\YELLOWORANGE64", continent = { - PinSize = 14, - Border = 2, + iconWidth = 14, + borderWidth = 2, highlightWidth = 1, - TagSize = 6, + TagSize = 8, maxAlertLevel = 0, showNumber = true, numberFontObject = 'WorldPlanFont' @@ -52,36 +59,32 @@ numberFontObject = 'WorldPlanNumberFontThin' }, minimized = { - iconWidth = 6, - borderWidth = 0, + r = 0, g = 0, b = 0, a = 0.1, + iconWidth = 8, + borderWidth = 2, + alpha = 0.5, highlightWidth = 0, - maxAlertLevel = 1, + maxAlertLevel = 0, NoIcon = true, + + TagSize = 8, TimeleftStage = 1, showNumber = false, + alpha = 0.1, } } - - - -local defaults = { +db.DefaultConfig = { ShowAllProfessionQuests = false, DisplayContinentSummary = true, DisplayContinentPins = true, NotifyWhenNewQuests = true, EnablePins = true, FadeWhileGrouped = false, + FlightMapAlphaLimits = {1, 1, 1}, + FlightMapScalingLimits = {1, 3, 1.5}, } --- operating flags -local superTrackedID -local currentMapName -local hasNewQuestPins -local isContinentMap -local hasPendingQuestData -local notifyPlayed -local scanner, wmtt, WorldMapPOIFrame -- tracking menu toggler @@ -97,21 +100,32 @@ _G.WorldPlan:Refresh() end -function WorldPlanCore:print(...) - local msg +function db.print(...) for i = 1, select('#', ...) do - msg = (msg and (msg .. ' ') or '') .. tostring(select(i, ...)) + tinsert(db.ReportChunks, tostring(select(i, ...))) end - DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg) end -local current_type_owner -function WorldPlanCore:AddHandler (frame, defaults) - print('|cFFFFFF00'..self:GetName()..':AddHandler()', frame:GetName()) - tinsert(self.modules, frame) - self.defaults[frame] = defaults - frame.GetTypeInfo = function(frame, typeID) - return self:GetTypeInfo(frame, typeID) +function WorldPlanCore:print(...) db.print(...) end + +function WorldPlanCore:AddHandler (frame) + if not db.LoadedModules[frame] then + print('|cFFFFFF00'..self:GetName()..':AddHandler()', frame:GetName(), self.initialized) + db.LoadedModules[frame] = true + tinsert(db.OrderedModules, frame) + + if frame.defaults then + db.DefaultConfig[frame:GetName()] = frame.defaults + end + + frame.GetTypeInfo = function(frame, typeID) + return self:GetTypeInfo(frame, typeID) + end + + frame.owningFrame = self + else + + print('|cFFFF4400'..self:GetName()..':AddHandler()', frame:GetName()) end end @@ -124,10 +138,10 @@ v = setmetatable(v, { __newindex = function(t2,k2,v2) if type(v2) == 'table' then - print('adding type', k2) + --print('adding type', k2) v2 = setmetatable(v2, {__index = function(t3,k3) --print('##deferring to default key', k3) - return DEFAULT_TYPE[k3] + return db.DefaultType[k3] end}) end rawset(t2,k2,v2) @@ -144,47 +158,54 @@ end - WorldPlanCore:print('v'..WP_VERSION) + db.print('v'..WP_VERSION) + self:RegisterEvent("QUESTLINE_UPDATE") self:RegisterEvent("QUEST_LOG_UPDATE") self:RegisterEvent("WORLD_MAP_UPDATE") + self:RegisterEvent("SPELLS_CHANGED") + self:RegisterEvent('PLAYER_ENTERING_WORLD') self:RegisterEvent("WORLD_QUEST_COMPLETED_BY_SPELL") self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED") self:RegisterEvent("SKILL_LINES_CHANGED") self:RegisterEvent("ARTIFACT_XP_UPDATE") self:RegisterEvent("ADDON_LOADED") - self:SetParent(WorldMapFrame) + self:RegisterEvent("PLAYER_LOGIN") + --self:SetParent(WorldMapFrame) end function WorldPlanCore:OnShow() - print(self:GetName()..':OnShow()') - if self.isStale then - self:Refresh() - end - - hooksecurefunc(self, 'SetScript', function(...) self:print('|cFFFFFF00'..self:GetName()..':SetScript()|r', ...) end) + --print(self:GetName()..':OnShow()') + --hooksecurefunc(self, 'SetScript', function(...) self:print('|cFFFFFF00'..self:GetName()..':SetScript()|r', ...) end) end +function WorldPlanCore:GetMapInfo() + + db.currentMapID = GetCurrentMapAreaID() + db.isContinentMap = (db.currentMapID == BROKEN_ISLES_ID) + db.useContinentType = (WorldMapDetailFrame:GetScale() < 1) + +end + + function WorldPlanCore:OnEvent (event, ...) - print() - print(event, 'init:', self.initialized) + + print('|cFF00FF88'..self:GetName().. ':OnEvent()|r', event, GetTime(), 'init:', self.initialized) if event == 'ADDON_LOADED' then if IsLoggedIn() and not self.initialized then self:Setup() end else - if event == 'WORLD_MAP_UPDATE' then - self.currentMapID = GetCurrentMapAreaID() - self.isContinentMap = (self.currentMapID == BROKEN_ISLES_ID) - --self:print('|cFFFF4400currentMapID =', self.currentMapID) - self.isStale = true + if (event == 'WORLD_MAP_UPDATE') or (event == 'PLAYER_ENTERING_WORLD') then + print('|cFFFF4400currentMapID =', db.currentMapID, ...) + self:GetMapInfo() end - for i, module in ipairs(self.modules) do + for i, module in ipairs(db.OrderedModules) do if module.OnEvent then - print(' |cFF0088FF'..module:GetName() .. ':OnEvent()|r') + print(' |cFF00FFFF'..module:GetName() .. ':OnEvent()|r') module:OnEvent(event, ...) end end @@ -206,48 +227,56 @@ end if self.isStale then - print('|cFF00FF00pushing global update') - self.isStale = nil - self:Refresh() - else - for i, module in ipairs(self.modules) do - if module.isStale then + -- these need to happen in load order + for i, module in ipairs(db.OrderedModules) do + if module:IsVisible() and module.isStale then print('|cFF00FF00internal '..module:GetName()..':Refresh()|r') module:Refresh() end end + self.isStale = nil end + + if #db.ReportChunks >= 1 then + + DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FF"..addonFileName.."|r: " .. table.concat(db.ReportChunks, ', ')) + wipe(db.ReportChunks) + end + end function WorldPlanCore:Setup () + print('|cFFFFFF00'..self:GetName()..':Setup()|r') + if not WorldPlanData then - WorldPlanData = {key = 0 } + WorldPlanData = {key = 0} end WorldPlanData.key = (WorldPlanData.key or 0) + 1 - self.db = WorldPlanData - self.db.WorldQuests = self.db.WorldQuests or {} - db = self.db - for k,v in pairs(defaults) do + db.Config = WorldPlanData + for k,v in pairs(db.DefaultConfig) do --[===[@non-debug@ - if not db[k] then - db[k] = v + if not db.Config[k] then + db.Config[k] = v end --@end-non-debug@]===] --@debug@ - db[k] = v + db.Config[k] = v --@end-debug@ end - self.currentMapID = GetCurrentMapAreaID() - for i, module in ipairs(self.modules) do - module.db = self.db + db.currentMapID = GetCurrentMapAreaID() + + for i, module in ipairs(db.OrderedModules) do + db.Config[module:GetName()] = db.Config[module:GetName()] or {} if module.Setup then module:Setup() end if not module.RegisterEvent then module.RegisterEvent = self.RegisterEvent end end + + self.initialized = true hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) @@ -261,14 +290,71 @@ self:Refresh(true) end end) + + + hooksecurefunc("WorldMapFrame_Update", function() + print('|cFFFF4400WorldMapFrame_Update|r') + self:GetMapInfo() + end) + + + SLASH_WORLDPLAN1 = "/worldplan" + SLASH_WORLDPLAN2 = "/wp" + + + + SlashCmdList.WORLDPLAN = function(args) + local arg1, arg2, extraArgs = args:match("(%S+)%s*(%S*)%s*(.*)") + + if arg1 == 'wq' then + if arg2 and WorldPlanQuests[arg2] then + self:print('WorldPlanQuests:'..arg2..'()') + WorldPlanQuests[arg2](WorldPlanQuests) + elseif arg2 == 'flightscale' and extraArgs then + local val1, val2, val3 = extraArgs:match("(%S+)%s*(%S*)%s*(%S*)") + if tonumber(val1) and tonumber(val2) and tonumber(val3) then + db.Config.FlightMapScalingLimits = {tonumber(val1), tonumber(val2), tonumber(val3)} + self:print('FlightMapFrame scaling limits updated:', unpack(db.Config.FlightMapScalingLimits)) + else + self:print('FlightMapFrame scaling limits:', unpack(db.Config.FlightMapScalingLimits)) + end + elseif arg2 == 'flightalpha' and extraArgs then + local val1, val2, val3 = extraArgs:match("(%S+)%s*(%S*)%s*(%S*)") + if tonumber(val1) and tonumber(val2) and tonumber(val3) then + db.Config.FlightMapAlphaLimits = {tonumber(val1), tonumber(val2), tonumber(val3)} + self:print('FlightMapFrame alpha limits updated:', unpack(db.Config.FlightMapAlphaLimits)) + else + self:print('FlightMapFrame alpha limits:', unpack(db.Config.FlightMapAlphaLimits)) + end + else + + self:print('WorldPlanQuests:Refresh(true)') + WorldPlanQuests:Refresh(true) + end + elseif arg1 == 'filter' then + if arg2 and WorldPlanSummary[arg2] then + self:print('WorldPlanSummary:'..arg2..'()') + WorldPlanSummary[arg2](WorldPlanSummary) + else + self:print('WorldPlanSummary:Refresh(true)') + WorldPlanSummary:Refresh(true) + end + else + self:print('Refreshing data.') + self:Refresh(true) + end + + end end +-- registers a template table function WorldPlanCore:AddTypeInfo(owner, id, info) self.Types[owner] = self.Types[owner] or {} self.Types[owner][id] = info print('Type('..owner:GetName()..')('..id..') = '.. tostring(info)) end +-- recall a template table, with situational details filled in function WorldPlanCore:GetTypeInfo(owner, typeID) local info, extraInfo if not owner then @@ -280,21 +366,26 @@ owner = owner or self if (not typeID) or (not self.Types[owner][typeID]) then --print('## sending list default') - info = DEFAULT_TYPE + info = db.DefaultType else --print('## sent list definition', typeID) info = self.Types[owner][typeID] end - if isContinentMap then - extraInfo = info.continent - --print('### continent subtype', extraInfo) - else - extraInfo = info.zone + local subType = 'continent' + if ( + FlightMapFrame + and FlightMapFrame:IsVisible() + and FlightMapFrame:IsZoomedIn() + ) or ( + not db.isContinentMap + ) or ( + db.useContinentType == false + ) then + subType = 'zone' + end - --print('### zone subtype', extraInfo) - end - return info, extraInfo + return info, info[subType] or db.DefaultType[subType] end do @@ -314,7 +405,6 @@ } -- Generates a timeleft string function WorldPlanCore:GetTimeInfo(timeLeft, limit) - limit = limit or #timeStates for index = 1, limit do local state = timeStates[index] if timeLeft <= state.maxSeconds then @@ -335,12 +425,14 @@ return end - for i, module in ipairs(self.modules) do + for i, module in ipairs(db.OrderedModules) do if module.Refresh then print('|cFF00FF00external '..module:GetName()..':Refresh()|r') module:Refresh(forced) end end + + self.isStale = nil end -- insert visual options into the tracking button menu @@ -348,8 +440,7 @@ if self ~= WorldMapFrameDropDown then return end - local db = WorldPlan.db - + local config = WorldPlanData local info = UIDropDownMenu_CreateInfo() info.text = "" info.isTitle = true @@ -365,7 +456,7 @@ info.text = "Enable" info.isNotRadio = true info.value = "EnablePins" - info.checked = db.EnablePins + info.checked = config.EnablePins info.tooltipTitle = "Enable World Quest Overlays" info.tooltipText = "Toggle the detail layers here." info.func = DropDown_OnClick @@ -374,7 +465,7 @@ info.text = "Display All Profession Quests" info.isNotRadio = true info.value = "ShowAllProfessionQuests" - info.checked = db.ShowAllProfessionQuests + info.checked = config.ShowAllProfessionQuests info.tooltipTitle = "Hidden Quests" info.tooltipText = "Display work order and profession-related quests that are skipped by the default UI." info.func = DropDown_OnClick @@ -383,7 +474,7 @@ info.text = "Show Continent Pins" info.isNotRadio = true info.value = "DisplayContinentPins" - info.checked = db.DisplayContinentPins + info.checked = config.DisplayContinentPins info.tooltipTitle = "Continent Pins" info.tooltipText = "Display quest pins on the continent map (may get cramped)." info.func = DropDown_OnClick @@ -394,16 +485,26 @@ info.value = "DisplayContinentSummary" info.tooltipTitle = "Summary Bar" info.tooltipText = "Display a summary of active world quests. Note: requires directly viewing Broken Isle and Dalaran maps to gain complete info." - info.checked = db.DisplayContinentSummary + info.checked = config.DisplayContinentSummary info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) - info.text = "Fade In Groups" + + info.text = "Nudge Pins" + info.isNotRadio = true + info.value = "NudgePins" + info.tooltipTitle = "Pin Nudging" + info.tooltipText = "Adjust the position of quest pins that overlap." + info.checked = config.NudgePins + info.func = DropDown_OnClick + UIDropDownMenu_AddButton(info) + + info.text = "Fade Whiled Grouped" info.isNotRadio = true info.value = "FadeWhileGrouped" info.tooltipTitle = "Group Fade" info.tooltipText = "Reduce pin alpha when grouped, so player dots are easier to see." - info.checked = db.FadeWhileGrouped + info.checked = config.FadeWhileGrouped info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) end @@ -417,15 +518,4 @@ -SLASH_WORLDPLAN1 = "/worldplan" -SLASH_WORLDPLAN2 = "/wp" -SlashCmdList.WORLDPLAN = function() - print('command pop') - WorldPlanCore:GetPinsForMap() - WorldPlanCore:RefreshPins() - - SetTimedCallbackForAllPins(0, function(self) self.FadeIn:Play() self.FlashIn:Play() end) - SetTimedCallbackForAllPins(5, function(self) self.PendingFade:Play() end) - SetTimedCallbackForAllPins(8, function(self) self.PendingFade:Stop() end) -end --%end-debug% \ No newline at end of file
--- a/WorldPlan.xml Fri Nov 04 02:54:32 2016 -0400 +++ b/WorldPlan.xml Sun Dec 25 13:04:57 2016 -0500 @@ -148,15 +148,6 @@ </Frame> </Frames> </Button> - <Button name="WorldPlanFilterPin" virtual="true" inherits="WorldPlanQuestPin" mixin="WorldPlanFilterPinMixin"> - <Scripts> - <OnMouseDown method="OnMouseDown" /> - <OnClick method="OnClick" /> - <OnLoad method="OnLoad" /> - <OnEnter method="OnEnter" /> - <OnLeave method="OnLeave" /> - </Scripts> - </Button> <Frame name="WorldPlan" mixin="WorldPlanCore" parent="UIParent"> <KeyValues>
--- a/WorldQuests.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/WorldQuests.lua Sun Dec 25 13:04:57 2016 -0500 @@ -2,21 +2,21 @@ -- WorldQuests.lua -- Created: 11/2/2016 3:40 PM -- %file-revision% - +local _, db = ... local WorldQuests = WorldPlanQuestsMixin local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID local GetMapInfo = GetMapInfo -local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end +local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end +local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or function() end local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end -local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or function() end -local PinBaseIndex = 1000 +local PinBaseIndex = 1200 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', } @@ -29,9 +29,8 @@ local numPins = 0 -local ZoneInfo = {} local NumPinFrames = 1 - +WorldQuests.TasksByID = {} --%debug% local SetTimedCallbackForAllPins = function(seconds, callback) @@ -42,21 +41,35 @@ end) end +function WorldQuests:OnShow() + self:Refresh(true) +end + +function WorldQuests:OnUpdate(sinceLast) + if self.filtersDirty or self.isStale then + self:Refresh() + end +end + function WorldQuests:Setup() - + print('|cFFFF4400'..self:GetName()..':Setup()') for mapID, mapName in pairs(WORLD_QUEST_MAPS) do - self.QuestsByZone[mapID] = {} + db.QuestsByZone[mapID] = {} end -- refresh positions any time blizzard does so (i.e. mousewheel zoom) hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() + print('|cFFFF4400WorldMapScrollFrame_ReanchorQuestPOIs') self:Refresh(true) end) + -- hide the original world quest POIs + hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function() + print('|cFFFF4400WorldMap_UpdateQuestBonusObjectives') for i = 1, NUM_WORLDMAP_TASK_POIS do local button = _G['WorldMapFrameTaskPOI'..i] if button and button.worldQuest then @@ -65,22 +78,24 @@ end end) end -local WorldMapPOIFrame local defaults = {} +local REWARD_UNKNOWN = 768 function WorldQuests:OnLoad() - print('|cFF00FF88'..self:GetName()..':OnLoad') + print('|cFFFF4400'..self:GetName()..':OnLoad()') + self:SetParent(WorldMapFrame) WorldPlan:AddHandler(self, defaults) - local rgbWhite = {1, 1, 1} + local rgbWhite = {1, 1, 1 } + WorldPlan:AddTypeInfo(self, REWARD_UNKNOWN, { r = 1, g = 1, b = 1}) WorldPlan:AddTypeInfo(self, REWARD_REAGENT, { r = 0, g = 1, b = 1 }) WorldPlan:AddTypeInfo(self, REWARD_ARTIFACT_POWER, { r = 1, g = .25, b = .5, hasNumeric = true, numberRGB = rgbWhite }) WorldPlan:AddTypeInfo(self, REWARD_GEAR, { r = .1, g = .2, b = 1 }) WorldPlan:AddTypeInfo(self, REWARD_CURRENCY, { r = 1, g = 1, b = 0, hasNumeric = true, numberRGB = {1,1,0}, }) - WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = .7, g = .6, b = .32, pinMask = false, rewardMask = false }) + WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = 1, g = 1, b = .32, pinMask = false, rewardMask = false }) for areaID, fileName in pairs(WORLD_QUEST_MAPS) do - self.QuestsByZone[areaID] = {} + db.QuestsByZone[areaID] = {} end self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') @@ -91,40 +106,53 @@ end function WorldQuests:OnEvent (event, ...) - local print = wqprint - print('|cFFFFFF00'..self:GetName()..':OnEvent()'..event..'|r', GetTime(), ...) - if event == 'QUEST_LOG_UPDATE' then + + print('|cFFFFFF00'..self:GetName()..':OnEvent() '..event..'|r', GetTime(), ...) + if event == 'QUEST_LOG_UPDATE' or event == 'PLAYER_LOGIN' then local questID, added = ... if questID and added then local questPOI = self:AcquirePin(questID) - self.isStale, self.isPending = questPOI:RefreshData() + questPOI:GetQuestInfo() + questPOI.isStale = true + self.isStale = true else - self:RefreshData() + self:Refresh(true) end print('WorldMapFrame', WorldMapFrame:IsVisible(), 'hasUpdates:', self.isStale) - elseif event == 'WORLD_MAP_UPDATE' or event == 'PLAYER_ENTERING_WORLD' then - self.isStale = true + elseif event == 'WORLD_MAP_UPDATE' then + self:Refresh(true) elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then local questID = ... - if questID and self.QuestsByID[questID] then - self:ReleasePin(self.QuestsByID[questID]) + if questID and db.QuestsByID[questID] then + self:ReleasePin(db.QuestsByID[questID]) + rprint('|cFFFF4400release|r', questID) end elseif event == 'SKILL_LINES_CHANGED' then - self.isStale = true + self:SetFilteredPins() end end +local totalPins = 0 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation -function WorldQuests:AcquirePin (questID, mapID) - local pin = self.QuestsByID[questID] - local isNew = false +function WorldQuests:AcquirePin (info) + local questID = info.questId + if not questID then + return nil + end + + if not QuestUtils_IsQuestWorldQuest(questID) then + return nil + end + + + local pin = db.QuestsByID[questID] if not pin then - isNew = true - local numFree = #self.freePins + local numFree = #db.FreePins if numFree >= 1 then - pin = tremove(self.freePins, numFree) + pin = tremove(db.FreePins, numFree) --print('|cFF00FF00Re-using', pin:GetName()) else + totalPins = totalPins + 1 local name = 'WorldPlanQuestMarker' .. NumPinFrames --print('|cFF00FF00Creating', name) pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') @@ -133,181 +161,355 @@ pin.GetTypeInfo = function(frame, typeID) return self:GetTypeInfo(typeID) end + pin:SetID(totalPins) NumPinFrames = NumPinFrames + 1 --pin.iconBorder:SetVertexColor(0,0,0,1) end - pin:SetID(questID) + pin.questID = questID + pin.worldQuest = true + pin.throttle = 1 pin.isNew = true pin.currentWidth = nil + db.QuestsByID[questID] = pin + tinsert(db.UsedPins, pin) + end - -- used by TaskPOI_x scripts - pin.questID = questID - pin.worldQuest = true + 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 + pin.x = info.x or pin.x + pin.y = info.y or pin.y + rprint('|cFFFF4400coords|r', info.x, info.y) + end + end - self.QuestsByID[questID] = pin - else - --print('|cFF00FF00Using', pin:GetName()) - end - mapID = mapID or TQ_GetQuestZoneID(questID) - self.QuestsByZone[mapID][questID] = pin - - return pin, isNew + pin:GetData() + C_TaskQuest.RequestPreloadRewardData(info.questId) + return pin end -- remove from index and add it to the recycling heap function WorldQuests:ReleasePin (pin) - local id = pin.questId + local id = pin.questID if id then - self.QuestsByID[id] = nil - for i, zone in pairs(self.QuestsByZone) do + 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:Hide() + pin:SetShown(false) pin:ClearAllPoints() - tinsert(self.freePins, pin) - print('|cFFFF4400Clearing out', pin:GetName(),id) + tinsert(db.FreePins, pin) + + print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title) end +function WorldQuests:GetBonusObjectives() + + + local tasksTable = GetTasksTable() + if tasksTable ~= nil then + print('|cFF00FF88'..self:GetName()..':BonusObjectives()|r ') + self.numTasks = #tasksTable + for i, taskID in ipairs(tasksTable) do + if not QuestUtils_IsQuestWorldQuest(taskID) then + local info = db.TasksByID[taskID] + if not info then + local isInArea, isOnMap, numObjectives, taskName, displayAsObjective = GetTaskInfo(taskID) + if isOnMap then + print(' * '..i, taskID, GetTaskInfo(taskID)) + info = { + questID = taskID, + numObjectives = numObjectives, + title = taskName, + isInArea = isInArea, + isOnMap = isOnMap, + displayAsObjective = displayAsObjective, + worldQuest = false, + isPending = false, + isNew = true, + } + + + db.TasksByID[taskID] = info + + local pin = self:AcquirePin(taskID) + for k,v in pairs(info) do + pin[k] = v + end + pin:GetBonusObjectiveInfo(info) + end + end + end + + + end + end +end + + + + +-- use tooltip object to extract item details +function WorldQuests:GetRewardHeader(questID) + local name, icon, quantity, quality, _, itemID = GetQuestLogRewardInfo(1, questID) + local scanner = _G.WorldPlanTooltip + local print = qprint + if not itemID then + return + end + --print('GetRewardHeader', questID) + + scanner:SetOwner(WorldPlan, "ANCHOR_NONE") + scanner:SetItemByID(itemID) + scanner:Show() + local ttl1 = _G['WorldPlanTooltipTextLeft1'] + local ttl2 = _G['WorldPlanTooltipTextLeft2'] + local ttl3 = _G['WorldPlanTooltipTextLeft3'] + local ttl4 = _G['WorldPlanTooltipTextLeft4'] + --print(ttl2, ttl3, ttl4) + if ttl2 then + local text = ttl2:GetText() + -- Artifact Power + --print(text) + if text then + if text:match("|cFFE6CC80") then + --print('AP token!', text) + local power + if ttl4 then + local text = ttl4:GetText() + --print('tip line 4', text) + if text then + power = text:gsub("%p", ""):match("%d+") + power = tonumber(power) + end + + end + return REWARD_ARTIFACT_POWER, "Interface\\ICONS\\inv_7xp_inscription_talenttome01", power, name, itemID, quality + elseif text:match("Item Level") then + --print('equipment!', text) + quantity = text:match("Item Level ([%d\+]+)") + return REWARD_GEAR, icon, quantity, name, itemID, quality + elseif text:match("Crafting Reagent") then + --print('|cFFFF4400it is a reagent', text) + return REWARD_REAGENT, icon, quantity, name, itemID, quality + end + end + end + + if ttl3 then + local text = ttl3:GetText() + if text and text:match("Crafting Reagent") then + --print('|cFFFF4400it is a reagent', text) + return REWARD_REAGENT, icon, quantity, name, itemID, quality + end + end + return 128, icon, quantity, name, itemID, quality +end + +local GetCurrentMapAreaID, GetMapNameByID= GetCurrentMapAreaID, GetMapNameByID +local wipe, pairs = wipe, pairs -- create of update quest pins for a map and its underlying zones -function WorldQuests:RefreshData (mapID) - local print = wqprint - mapID = mapID or WorldPlan.currentMapID +function WorldQuests:UpdateWorldQuests (mapID) + + mapID = mapID or db.currentMapID if not mapID then -- info not available yet return end - print('|cFF00FF88'..self:GetName()..':RefreshData()|r', 'map:', mapID, 'realMap:', GetCurrentMapAreaID()) + print('|cFF00FF88'..self:GetName()..':UpdateWorldQuests()|r', 'map:', mapID, 'realMap:', db.currentMapID) - if mapID == BROKEN_ISLES_ID then - self.isStale = false - print('|cFF00FFFFContinent:|r', mapID, GetMapNameByID(mapID), superTrackedID) - self.fullSearch = true - for i = 1, MC_GetNumZones(mapID) do - local submapID, name, depth = MC_GetZoneInfo(mapID, i) - self:RefreshData(submapID) - end - self.fullSearch = nil - elseif self.QuestsByZone[mapID] then - local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID, WorldPlan.currentMapID) - local numQuests = 0 - if taskInfo and #taskInfo >= 1 then - print('|cFF00FFFF Zone:|r', mapID, GetMapNameByID(mapID), #taskInfo) - wipe(self.QuestsByZone[mapID]) - ZoneInfo[mapID] = taskInfo - qprint('|cFFFF4400START of', GetMapNameByID(mapID)) - for taskID, info in pairs(taskInfo) do - local questID = info.questId - info.mapID = mapID - local questPOI = self:AcquirePin(questID, mapID) - local hasUpdate, isPending = questPOI:RefreshData(info) - -- WorldPlan:print('|cFF0088FF'..questPOI.title..'|r', hasUpdate) - self.isStale = (self.isStale or hasUpdate) - self.isPending = (self.isPending or isPending) - numQuests = numQuests + 1 + + self.isStale = nil + print('|cFF00FFFFContinent:|r', BROKEN_ISLES_ID, GetMapNameByID(BROKEN_ISLES_ID)) + self.isRecursed = true + for i = 1, MC_GetNumZones(BROKEN_ISLES_ID) do + local submapID, name, depth = MC_GetZoneInfo(BROKEN_ISLES_ID, i) + local taskInfo = TQ_GetQuestsForPlayerByMapID(submapID, BROKEN_ISLES_ID) + if taskInfo then + local zoneName = GetMapNameByID(submapID) + print('|cFF00FFFF Zone:|r', submapID, zoneName, #taskInfo) + db.QuestsByZone[submapID] = db.QuestsByZone[submapID] or {} + for i, info in ipairs(taskInfo) do + if HaveQuestData(info.questId) then + rprint('|cFF44FF44update|r', info.questId, zoneName) + local questID = info.questId + local pin = self:AcquirePin(questID) + local pin = db.QuestsByID[questID] + if pin then + pin.isStale = true + if pin.isPending then + self.isPending = true + end + end + else + rprint('|cFFFF4400no data|r', info.questId, zoneName) + end end - qprint('|cFFFF4400END of', GetMapNameByID(mapID)) end end - if not self.fullSearch then - print(' hasUpdate:', self.isStale, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or '')) - --WorldPlan.isStale = (self.isStale or WorldPlan.isStale) + self:GetBonusObjectives() + + print(' hasUpdate:', self.isStale, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or '')) + --WorldPlan.isStale = (self.isStale or WorldPlan.isStale) + if self.isStale and self:IsVisible() then + self:Refresh() + end +end + +function WorldQuests:Report() + for i, pin in ipairs(db.UsedPins) do + db:print(i, pin.questID, pin.title) end + for id, pin in pairs(db.QuestsByID) do + db:print(id, pin.worldQuestType, pin.rewardType, pin.title) + end end -function WorldQuests:Refresh(forced) - local print = wqprint - print('|cFF00FF88'..self:GetName()..':Refresh()|r') +function WorldQuests:Refresh(fromUser) + self.currentMapID = GetCurrentMapAreaID() + print('|cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal') if not self:IsVisible() then + print(' not visible, flag for later') self.isStale = true - print('frame closed, do it later') + return + end + wprint(' |cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal') + + for index, pin in pairs(db.QuestsByID) do + pin.used = nil + pin:SetShown(false) + end + + self:SetFilteredPins(db.QuestsByID) + self:UpdateAnchors(nil, fromUser) + self:Cleanup (fromUser) + self.isStale = nil +end + +-- update visibility states of all pins +function WorldQuests:SetFilteredPins(pins) + print(' |cFFFFFF00'..self:GetName()..':SetFilteredPins()|r', pins) + pins = pins or db.QuestsByID + for questID, pin in pairs(pins) do + pin.filtered = pin:IsFiltered() + pin.isStale = true + rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used) + end +end + +local abs = math.abs +function WorldQuests:UpdateQuestButton(info, mapID) + local questID, x, y = info.questId, info.x, info.y + local pin = self:AcquirePin(info) + if not pin then return end - self:Reset() - self:UpdateAnchors() - self:Cleanup () -end --- prepares elements for a map update -function WorldQuests:Reset () - local print = wqprint - print('|cFF00FF88'..self:GetName()..':Reset()|r') - for questID, pin in pairs(self.QuestsByID) do - pin.used = nil + print('~ ', pin.mapID, pin.questID, pin.title) + rprint('|cFF00FF00update|r', x, y, pin.title) + pin:IsShowable() + + if x and y then + + pin.x = x + pin.y = y + pin:SetFrameLevel(PinBaseIndex+numPins) + pin:SetPoint('CENTER', self.hostFrame, 'TOPLEFT', self.hostWidth * pin.x, -self.hostHeight * pin.y) + pin.throttle = 1 + pin:SetShown(pin.used) + tinsert(self.UsedPositions, pin) + end + pin.owningFrame = self.hostFrame + pin:SetParent(self.hostFrame) + + if mapID then + if not db.QuestsByZone[mapID] then + db.QuestsByZone[mapID] = {} + end + db.QuestsByZone[mapID][questID] = pin end end --- update visibility states of all pins -function WorldQuests:UpdateAnchors (submapID) +function WorldQuests:UpdateMap(taskInfo, mapID) + print('Map', GetMapNameByID(mapID), GetMapNameByID(self.currentMapID)) + for index, info in pairs(taskInfo) do + self:UpdateQuestButton(info, mapID) + end +end - local print = wqprint - local db = WorldPlan.db +function WorldQuests:UpdateAnchors (fromUser) + + + wipe(self.UsedPositions) + print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()', fromUser) + self.hostFrame = WorldMapPOIFrame + self.hostWidth, self.hostHeight = self.hostFrame:GetSize() + self.nudgeThrescholdX = 16/self.hostWidth + self.nudgeThrescholdY = 16/self.hostHeight + local print = rprint + print('|cFF00FF00'..self:GetName()..':UpdateAnchors()', fromUser) local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() if isMicroDungeon then return end - local currentMap = GetCurrentMapAreaID() - local submapID = submapID or currentMap - - if submapID == BROKEN_ISLES_ID and (not db.DisplayContinentPins) then - print('not updating map for reasons') - return + numPins = 0 + local taskInfo = TQ_GetQuestsForPlayerByMapID(self.currentMapID) + if taskInfo then + self:UpdateMap(taskInfo, self.currentMapID) end - print('|cFF88FF00'..self:GetName()..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins) - local numZones = MC_GetNumZones(submapID) + local numZones = MC_GetNumZones(self.currentMapID) if numZones then for i = 1, numZones do - local subMapID = MC_GetZoneInfo(submapID, i) - self:UpdateAnchors(subMapID) + local mapAreaID = MC_GetZoneInfo(self.currentMapID, i) + local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, self.currentMapID) + if taskInfo then + self:UpdateMap(taskInfo, mapAreaID) + end end end - local pins = self.QuestsByZone[submapID] - - if pins then - local hostFrame = WorldMapPOIFrame - local mapWidth, mapHeight = hostFrame:GetSize() - for questID, pin in pairs(pins) do - pin:IsShowable() - if pin.used then - pin.isStale = true - pin:SetFrameLevel(PinBaseIndex+ numPins) - print('level', PinBaseIndex+ numPins) - pin:SetAnchor(_G.WorldMapPOIFrame, currentMap, mapWidth, mapHeight) - numPins = numPins + 1 - end - end + if self.filtersDirty then + self:SetFilteredPins(db.QuestsByID) end end -- shows, animates, or hides pins based on their current visibility flags -local debug_show = {} -local debug_animate = {} -local debug_hide = {} -function WorldQuests:Cleanup () - local print = wqprint - local showQuestPOI = WorldPlan.db.EnablePins +function WorldQuests:Cleanup (fromUser) + print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') - -- continent or zone sizing + local print = rprint + print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') + --local showQuestPOI = db.Config.EnablePins + for questID, pin in pairs(db.QuestsByID) do + local oV = pin:IsShown() + if pin.used then + pin:SetShown(true) + pin.throttle = 1 + if oV == false then + print('|cFF00FF00cleanup +|r', questID, pin.title) + end + else + if oV == true then + print('|cFFFF4400 -|r', questID, pin.title) + end + end - - numPins = 0 - for questID, pin in pairs(self.QuestsByID) do - pin:SetShown((showQuestPOI and pin.used)) + if pin.worldQuest and (not C_TaskQuest.IsActive(pin.questID)) then + self:ReleasePin(pin) + end + pin.isStale = true end - self.isStale = nil end -function WorldQuests:FilterCheckByID(questID) - local pin = WorldQuests:GetPinByQuestID(questID) - return pin:IsShowable() -end - -