# HG changeset patch
# User Nenue
# Date 1476364118 14400
# Node ID b8a19781f79b2d4c8df82bb3875a29459d16926c
# Parent 232617b8bcd5273eca39496c9ce0e629946b3745
shipment logging
diff -r 232617b8bcd5 -r b8a19781f79b ClassPlan.lua
--- a/ClassPlan.lua Thu Oct 13 05:32:43 2016 -0400
+++ b/ClassPlan.lua Thu Oct 13 09:08:38 2016 -0400
@@ -1,3 +1,11 @@
+local wipe = table.wipe
+local pairs, ipairs = pairs, ipairs
+local GetTime = GetTime
+local blockTemplate = {
+ point = 'TOPLEFT',
+ relativePoint ='TOPLEFT',
+}
+
SLASH_CLASSPLAN1 = "/classplan"
SLASH_CLASSPLAN2 = "/cp"
SlashCmdList.CLASSPLAN = function(args)
@@ -10,27 +18,85 @@
end
ClassOrderPlanCore = {
+ freeBlocks = {},
blocks = {},
- playerFirst = true,
- timers = {}
+ shipmentBlocks = {},
+ freeShipmentBlocks = {},
+ sortedShipments = {},
+ sortedMissions = {},
+ timers = {},
+ shipments = {},
+ playerFirst = false,
+ templates = setmetatable({}, {
+ __newindex = function(t,k ,v)
+ if type(v) == 'table' then
+ setmetatable(v, {__index = blockTemplate})
+ rawset(t,k,v)
+ end
+ end
+ })
}
-ClassPlanBlockMixin = {
- followers = {},
- blocks = {},
-}
-local core, block = ClassOrderPlanCore, ClassPlanBlockMixin
+ClassPlanBlockMixin = {}
+ClassPlanShipmentMixin = setmetatable({}, {__index = ClassPlanBlockMixin})
+local core, block, shipment = ClassOrderPlanCore, ClassPlanBlockMixin, ClassPlanShipmentMixin
local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
+
+
function core:OnLoad ()
self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player')
- self:RegisterEvent('GARRISON_MISSION_STARTED')
- self:RegisterEvent('GARRISON_MISSION_FINISHED')
self:RegisterEvent('PLAYER_LOGIN')
self:RegisterEvent('PLAYER_ENTERING_WORLD')
+ self:RegisterEvent('PLAYER_REGEN_ENABLED')
+
+ self:RegisterEvent('GARRISON_MISSION_LIST_UPDATE')
+ self:RegisterEvent('GARRISON_MISSION_FINISHED')
+ self:RegisterEvent("GARRISON_LANDINGPAGE_SHIPMENTS");
+ self:RegisterEvent("GARRISON_SHIPMENT_RECEIVED");
+ self:RegisterEvent("GARRISON_TALENT_UPDATE");
+ self:RegisterEvent("GARRISON_TALENT_COMPLETE");
end
+core.templates.ClassPlanBlock = {
+ SetItemData = function(block, data)
+ block.isComplete = data.isComplete
+ block.missionEndTime = data.missionEndTime
+ end
+}
+
+core.templates.ClassPlanShipment = {
+
+ parent = false,
+ point = 'TOPRIGHT',
+ relativePoint ='TOPRIGHT',
+ SetItemData = function(block, data)
+ block.icon = data.icon
+ block.shipmentCapacity = data.shipmentCapacity
+ block.shipmentsReady = data.shipmentsReady
+ block.shipmentsTotal = data.shipmentsTotal
+ block.creationTime = data.creationTime
+ block.duration = data.duration
+ block.itemID = data.itemID
+ block.itemQuality = data.itemQuality
+ --[[
+ icon = texture,
+ shipmentCapacity = shipmentCapacity,
+ shipmentsReady = shipmentsReady,
+ shipmentsTotal = shipmentsTotal,
+ creationTime = creationTime,
+ duration = duration,
+ timeleftString = timeleftString,
+ itemName = itemName,
+ itemIcon = itemIcon,
+ itemQuality = itemQuality,
+ itemID = itemID
+
+ --]]
+ end
+}
function core:OnEvent (event, ...)
+ print(event)
if event == 'UNIT_PORTRAIT_UPDATE' then
SetPortraitTexture(self.portrait, 'player')
elseif event == 'PLAYER_LOGIN' then
@@ -48,166 +114,461 @@
end
self.profile = self.data[self.profileKey]
+ self.profile.shipments = self.profile.shipments or {}
+ self.profile.missions = self.profile.missions or {}
+ self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
+
+ C_Garrison.RequestLandingPageShipmentInfo();
self.initialized = true
- print('initialized')
end
end
+ elseif event == 'GARRISON_LANDINGPAGE_SHIPMENTS' or event == 'GARRISON_TALENT_UPDATE' then
+ self:UpdateShipments()
+ elseif event == 'PLAYER_REGEN_ENABLED' or event == 'GARRISON_MISSION_FINISHED' or event == 'GARRISON_TALENT_COMPLETE' or event == 'GARRISON_SHIPMENT_RECEIVED' then
+ self:UpdateNotifications()
else
- self:Refresh ()
+ self:UpdateItems ()
end
end
-function core:UpdateList()
- self.sortedMissions = self.sortedMissions or {}
- table.wipe(self.sortedMissions)
+function core:UpdateNotifications()
+end
+function core:RefreshItems(sortedItems, templateName)
+ self.blocks[templateName] = self.blocks[templateName] or {}
+ local blocks = self.blocks[templateName]
+ local template = self.templates[templateName] or {
+ parent = self.portrait,
+ point = 'TOPLEFT',
+ relativePoint ='TOPRIGHT',
+ }
+
+ local lastProfile
+ local numItems = #sortedItems
+ for i, data in ipairs(sortedItems) do
+ local block = blocks[i]
+
+ if not block then
+ block = CreateFrame('Frame', nil, self, templateName)
+ block:SetID(i)
+ template.numBlocks = (template.numBlocks or 0) + 1
+
+ if template.lastBlock then
+ block:SetPoint('TOPLEFT', template.lastBlock, 'BOTTOMLEFT', 0, 0)
+ else
+ block:SetPoint(template.point, self[template.parent] or self, template.relativePoint, 0, 0)
+ end
+ template.lastBlock = block
+ blocks[i] = block
+ end
+
+ if template.SetItemData then
+ template.SetItemData(block, data)
+ end
+
+
+ block.lastProfile = lastProfile
+ block:Refresh(data)
+ block:Show()
+ lastProfile = data.profileKey
+ end
+
+ for i = numItems + 1, template.numBlocks do
+ if blocks[i] then
+ blocks[i]:Hide()
+ end
+ end
+end
+
+function core:Refresh()
+ if self.isStale then
+ self:SortLists()
+ end
+ self.isStale = nil
+
+ self:RefreshItems(self.sortedMissions, 'ClassPlanBlock')
+ self:RefreshItems(self.sortedShipments, 'ClassPlanShipment')
+
+
+ local posX = self.data.posX or 0
+ local posY = self.data.posY or -24
+ local point = self.point or 'TOP'
+ local relativePoint = self.point or 'TOP'
+ self:SetPoint(point, UIParent, relativePoint, posX, posY)
+
+
+end
+
+function core:OnUpdate()
+ if self.fadeTimer and self.fadeTimer < GetTime() then
+ self:Hide()
+ end
+end
+
+function core:OnShow()
+ if self.isStale then
+ print('updating items on show')
+ self:Refresh()
+ end
+
+end
+
+function core:SortLists()
+
+ wipe(self.sortedShipments)
+ wipe(self.sortedMissions)
for name, profile in pairs(self.data) do
local isMine = (profile == self.profile)
for index, data in pairs(profile.missions) do
data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7}
-
data.profileKey = name
data.isMine = (profile == self.profile)
tinsert(self.sortedMissions, data)
end
+
+ if not profile.shipments then
+ profile.shipments = {}
+ profile.shipment = nil
+ end
+
+ for index, data in pairs(profile.shipments) do
+ data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7}
+ data.profileKey = name
+ data.isMine = (profile == self.profile)
+ tinsert(self.sortedShipments, data)
+ end
end
- for i, v in ipairs(self.sortedMissions) do
- print(i, v.missionEndTime, v.name)
- end
-
-
- table.sort(self.sortedMissions, function(a,b)
+ table.sort(self.sortedMissions, function (a,b)
local result = false
if not a or not b then
result = true
else
-
if (a.isMine ~= b.isMine) and self.playerFirst then
result = a.isMine
else
if (not b.missionEndTime) or (not a.missionEndTime) then
print('missing article', b.missionEndTime, a.missionEndTime)
end
-
result = ( b.missionEndTime > a.missionEndTime)
end
end
- print('cmp', (b and (b.missionEndTime .. ' ' .. tostring(b.isMine)) or '-'), '>', (a and (a.missionEndTime .. ' ' .. tostring(a.isMine)) or '-'), result, n)
+ --print('cmp', (b and (b.missionEndTime .. ' ' .. tostring(b.isMine)) or '-'), '>', (a and (a.missionEndTime .. ' ' .. tostring(a.isMine)) or '-'), result, n)
return result
end)
- self.isStale = nil
- local lastProfile
- local numItems = #self.sortedMissions
- for i, data in ipairs(self.sortedMissions) do
- local block = self.blocks[i]
- if not block then
- block = CreateFrame('Frame', nil, self, 'ClassPlanBlock')
- block:SetID(i)
- self.numBlocks = (self.numBlocks or 0) + 1
+end
- if self.lastBlock then
- block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0)
- else
- block:SetPoint('TOPLEFT', self.portrait, 'TOPRIGHT', 0, 0)
+function core:UpdateShipments()
+ print('|cFF0088FFShipments|r:', self.profileKey)
+ if not self.profile then
+ return
+ end
+ wipe(self.shipments)
+
+
+ local garrisonType = LE_GARRISON_TYPE_7_0
+ local buildings = C_Garrison.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 = C_Garrison.GetLandingPageShipmentInfo(buildingID);
+ print(buildings[i], name, creationTime, duration)
+ tinsert(self.shipments,
+ {
+ shipmentType = 'Work Order',
+ name = name,
+ icon = texture,
+ shipmentCapacity = shipmentCapacity,
+ shipmentsReady = shipmentsReady,
+ shipmentsTotal = shipmentsTotal,
+ creationTime = creationTime,
+ duration = duration,
+ timeleftString = timeleftString,
+ itemName = itemName,
+ itemIcon = itemIcon,
+ itemQuality = itemQuality,
+ itemID = itemID
+ })
+ end
+
+ print('Follower:')
+ local followerShipments = C_Garrison.GetFollowerShipments(garrisonType);
+ for i = 1, #followerShipments do
+ local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = C_Garrison.GetLandingPageShipmentInfoByContainerID(followerShipments[i]);
+ print(followerShipments[i], name, creationTime, duration)
+ tinsert(self.shipments,
+ {
+ shipmentType = '',
+ name = name,
+ icon = texture,
+ shipmentCapacity = shipmentCapacity,
+ shipmentsReady = shipmentsReady,
+ shipmentsTotal = shipmentsTotal,
+ creationTime = creationTime,
+ duration = duration,
+ timeleftString = timeleftString,
+ followerID = followerID,
+ })
+ end
+
+ print('Loose:')
+ local looseShipments = C_Garrison.GetLooseShipments(garrisonType)
+ for i = 1, #looseShipments do
+ local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = C_Garrison.GetLandingPageShipmentInfoByContainerID(looseShipments[i]);
+ print(looseShipments[i], name, creationTime, duration)
+ tinsert(self.shipments,
+ {
+ shipmentType = '',
+ name = name,
+ icon = texture,
+ shipmentCapacity = shipmentCapacity,
+ shipmentsReady = shipmentsReady,
+ shipmentsTotal = shipmentsTotal,
+ creationTime = creationTime,
+ duration = duration,
+ timeleftString = timeleftString,
+ })
+ end
+
+ local talentTrees = C_Garrison.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 = C_Garrison.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) then
+ showTalent = true;
+ end
+ if (talent.id == completeTalentID) then
+ showTalent = true;
+ end
+ if (showTalent) then
+ print(talent.name)
+ talent.creationTime = talent.researchStartTime
+ talent.duration = talent.researchDuration
+ talent.shipmentType = 'Talent: '
+ tinsert(self.shipments, talent)
+ end
end
- self.lastBlock = block
- self.blocks[i] = block
end
+ end
- local r,g,b = 1, 1, 1
- if data.isRare then
- r,g,b = 0.1, 0.4, 1
+ self.profile.shipments = self.profile.shipments or {}
+ if #self.shipments >= 1 then
+
+ wipe(self.profile.shipments)
+ for index, shipment in ipairs(self.shipments) do
+ tinsert(self.profile.shipments, shipment)
end
- if data.isMine then
- block.Icon:SetVertexColor(0,1,0,1)
- else
- block.Icon:SetVertexColor(1,1,1)
- end
+ self.isStale = true
+ end
-
- --block.missionData = data
- block.missionID = data.missionID
- block.missionEndTime = data.missionEndTime
- block.Icon:SetAtlas(data.typeAtlas, false)
- block.Label:SetText(data.name)
- block.Label:SetTextColor(r, g, b)
-
- if lastProfile ~= data.profileKey then
- block.Owner:SetText(data.profileKey)
- block.Owner:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
- else
- block.Owner:SetText(nil)
- end
- block.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b, 0.5)
-
- block:Show()
- lastProfile = data.profileKey
- end
- for i = numItems + 1, self.numBlocks do
- if self.blocks[i] then
- self.blocks[i]:Hide()
- end
+ if self:IsVisible() then
+ self:Refresh()
end
end
-function core:OnShow()
- if self.isStale then
- print('updating items on show')
- self:UpdateList()
- end
-end
-
-function core:Refresh ()
+function core:UpdateItems ()
if not self.profile then
return
end
-
self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0)
- self.profile.missions = self.profile.missions or {}
- self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
- print('|cFF0088FFLocal Scoop|r:', self.profileKey)
+ print('|cFF0088FFLandingPageItems|r:', self.profileKey)
if #self.items >= 1 then
- table.wipe(self.profile.missions)
+ wipe(self.profile.missions)
for index, data in ipairs(self.items) do
print('', data.name)
print(' |cFF00FF00', data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime))
tinsert(self.profile.missions, data)
end
+ print('items update pending')
+ self.isStale = true
end
if self:IsVisible() then
- self:UpdateList()
+ self:Refresh()
+ end
+end
+
+function block:OnComplete()
+ self.isComplete = true
+ self:Refresh()
+end
+
+local GetTimeLeftString = function(timeLeft)
+
+ local days = floor(timeLeft/(24*3600))
+ local hours = floor(mod(timeLeft, (24*3600)) / 3600)
+ local minutes = floor(mod(timeLeft, 3600) / 60)
+ local seconds = mod(timeLeft, 60)
+ if days >= 1 then
+ return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h ') or '')
else
- print('items update pending')
- self.isStale = true
+ return ((hours > 0) and (hours .. 'h ') or '') .. ((minutes > 0) and (minutes .. ' min') or '')
end
end
function block:OnUpdate()
+ if self.isComplete then
+ return
+ end
+
if self.missionEndTime then
local timeLeft = self.missionEndTime - time()
if timeLeft < 0 then
- self.TimeLeft:SetText('Complete!')
+ self:OnComplete()
else
- local days = floor(timeLeft/(24*3600))
- local hours = floor(mod(timeLeft, (24*3600)) / 3600)
- local minutes = floor(mod(timeLeft, 3600) / 60)
- local seconds = mod(timeLeft, 60)
- self.TimeLeft:SetText(
- ((days > 0) and (days .. ' d') or '') ..
- ((hours > 0) and (' '.. hours .. ' hr') or '')..
- ((minutes > 0) and (' ' .. minutes .. ' min' or ''))
- , 1,1,1)
+ self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
+
+ if timeLeft > 3600 then
+ self.TimeLeft:SetTextColor(1,1,1)
+ else
+ self.TimeLeft:SetTextColor(1,1,0)
+ end
+
end
else
self.TimeLeft:SetText(self.missionEndTime)
end
+end
+
+local SetClassColors = function(self, data)
+
+ if self.lastProfile ~= data.profileKey then
+ self.Owner:SetText(data.profileKey)
+ self.Owner:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
+ else
+ self.Owner:SetText(nil)
+ end
+ self.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b,
+ (data.isComplete and 0.5 or 0.1))
+end
+
+function block:Refresh(data)
+ data = data or self.data
+ self.data = data
+
+ local r,g,b = 1, 1, 1
+ if data.isRare then
+ r,g,b = 0.1, 0.4, 1
+ end
+
+
+ --self.missionData = data
+ self.Label:SetText(data.name)
+ self.Label:SetTextColor(r, g, b)
+
+ if #data.rewards >= 1 then
+ self.Icon:SetTexture(data.rewards[1].icon or GetItemIcon(data.rewards[1].itemID))
+ self.rewardInfo = data.rewards[1]
+ else
+ self.Icon:SetAtlas(data.typeAtlas, false)
+ end
+
+ SetClassColors(self, data)
+
+ if self.isComplete then
+ self.TimeLeft:SetText('Complete!')
+ end
+end
+
+
+function block:OnEnter()
+ if self.rewardInfo and self.rewardInfo.itemID then
+ GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
+ GameTooltip:SetItemByID(self.rewardInfo.itemID)
+ GameTooltip:Show()
+ end
+end
+function block:OnLeave()
+ if GameTooltip:IsOwned(self) then
+ GameTooltip:Hide()
+ end
+end
+
+
+
+function shipment:Refresh(data)
+ data = data or self.data
+ self.Icon:SetTexture(data.icon)
+ self.data = data
+
+ self.Name:SetText(data.shipmentType .. data.name)
+ self.Count:SetText(data.shipmentsReady)
+
+ self.Done:SetShown(data.shipmentsReady and (data.shipmentsReady >= 1))
+
+ if ( data.shipmentsReady == data.shipmentsTotal ) then
+ self.Swipe:SetCooldownUNIX(0, 0);
+ self.Done:Show();
+ if not data.isBeingResearched then
+ data.isComplete = true
+ end
+ else
+ self.Swipe:SetCooldownUNIX(data.creationTime or 0 , data.duration or 0);
+ end
+
+
+
+ SetClassColors(self, data)
+end
+function shipment:UpdateShipment()
+
+ local data = self.data
+ if data.shipmentsTotal then
+ local timeLeft = data.creationTime + data.duration - time()
+ if timeLeft < 0 then
+ local numReady = floor((1*timeLeft) / data.duration)
+ data.shipmentsReady = data.shipmentsReady + numReady
+ data.creationTime = data.creationTime + (numReady * data.duration)
+ self:Refresh()
+ end
+ end
+end
+function shipment:OnUpdate()
+ local data = self.data
+ if (data.shipmentsReady and data.shipmentsTotal) and (data.shipmentsReady ~= data.shipmentsTotal) then
+ local timeLeft = data.creationTime + data.duration - time()
+ if timeLeft < 0 then
+ self:UpdateShipment()
+ return
+ end
+
+ self.TimeLeft:SetText('Next: '.. GetTimeLeftString(timeLeft) .. ' |cFFFFFF00'..data.shipmentsTotal..' orders|r')
+
+
+ elseif data.isBeingResearched then
+ self.TimeLeft:SetText(GetTimeLeftString(data.researchStartTime + data.researchDuration - time()))
+ else
+ self.TimeLeft:SetText('Complete!')
+ end
+
+end
+
+function shipment:OnEnter()
+ local data = self.data
+ if ( data.shipmentsReady and data.shipmentsTotal ) then
+ GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
+ GameTooltip:AddLine(data.shipmentsReady .. ' of '.. data.shipmentsTotal)
+ GameTooltip:Show()
+ end
+end
+
+function shipment:OnLeave()
+ if GameTooltip:IsOwned(self) then
+ GameTooltip:Hide()
+ end
+end
+
+function shipment:OnClick(button)
+ --todo: trigger cleanup script for dead shipment data
end
\ No newline at end of file
diff -r 232617b8bcd5 -r b8a19781f79b ClassPlan.xml
--- a/ClassPlan.xml Thu Oct 13 05:32:43 2016 -0400
+++ b/ClassPlan.xml Thu Oct 13 09:08:38 2016 -0400
@@ -3,8 +3,11 @@
+
+
+
-
+
@@ -31,6 +34,8 @@
+
+
@@ -47,22 +52,101 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ self:Show()
+
+
+ -- update via event
+ C_Garrison.RequestLandingPageShipmentInfo();
+
+
+
+
\ No newline at end of file