Mercurial > wow > worldplan
view ClassPlan.lua @ 2:b8a19781f79b
shipment logging
author | Nenue |
---|---|
date | Thu, 13 Oct 2016 09:08:38 -0400 |
parents | 232617b8bcd5 |
children | c006ce87a147 |
line wrap: on
line source
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) if ClassOrderPlan:IsVisible() then ClassOrderPlan:Hide() else ClassOrderPlan:Show() DEFAULT_CHAT_FRAME:AddMessage('|cFF88FF00WorldPlan|r: Order Hall Panel') end end ClassOrderPlanCore = { freeBlocks = {}, blocks = {}, 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 = {} 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('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 if not self.initialized then if IsLoggedIn() then WorldPlanData.OrderHall = WorldPlanData.OrderHall or {} self.data = WorldPlanData.OrderHall local name, realm = UnitName('player') realm = realm or GetRealmName() self.profileKey = name .. '-' .. realm if not self.data[self.profileKey] then self.data[self.profileKey] = {} 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 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:UpdateItems () end end 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 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) return result end) end 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 end end 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 self.isStale = true end if self:IsVisible() then self:Refresh() end end function core:UpdateItems () if not self.profile then return end self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0) print('|cFF0088FFLandingPageItems|r:', self.profileKey) if #self.items >= 1 then 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: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 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:OnComplete() else 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