view ClassPlanShipments.lua @ 113:03e4a8b93012 v7.3.0-2

7.3 Updates - Added some map frame adjustments to keep the filter bar from obstructing edge of zone clicks KNOWN ISSUES: - Argus quests can only be filtered when viewing Argus maps - Main Argus map in the WorldMapFrame has misaligned pins; this is due to it using a different map texture from what is used in the teleporter map, so all the POI coordinates are based on that map in the client info
author Nenue
date Tue, 05 Sep 2017 03:14:34 -0400
parents e8b6c5433128
children
line wrap: on
line source
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 = C_Garrison.GetTalentTreeIDsByClassID(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, treeID in ipairs(talentTrees) do
        local _, _, tree = C_Garrison.GetTalentTreeInfoForID(treeID);
        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)
  local status = false
  if b.isComplete ~= a.isComplete then
    if a.isComplete then
      status = true
    end
  else
    if a[SortKey]  then
      if b[SortKey] then
        status = (SortTable[a[SortKey]] < SortTable[b[SortKey]])
      else
        status = true
      end
    else
      if a.profileKey ~= b.profileKey then
          status = (a.profileKey < b.profileKey)

      else
        if a.shipmentsReady and b.shipmentsReady then
          status =  (a.shipmentsReady) > (b.shipmentsReady)
        elseif a.shipmentsReady or b.shipmentsReady then
          status =  (a.shipmentsReady) or true or false
        else

          if (a.creationTime ~= b.creationTime) then
            status =  (a.creationTime) < (b.creationTime)
          else
            status =  (a.name) < (b.name)
          end
        end

      end
    end
  end
  return status
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)