view Modules/WorldState.lua @ 109:26938ae258b7

- Re-use the basic addon table for core mixin - add /rl command
author Nick@Zahhak
date Mon, 06 Mar 2017 02:30:22 -0500
parents a41f6b74709a
children 1196c2bad31c
line wrap: on
line source
-- Veneer
-- WorldState.lua
-- Created: 10/7/2016 10:55 PM
-- %file-revision%
--

local print = DEVIAN_WORKSPACE and function(...) print('VnWorldState', ...) end or nop
local WorldStateBlockMixin = {}
VeneerOrderHallMixin = {
  anchorPoint = 'TOP',
  anchorFrom = 'TOP',
  anchorX = 0,
  anchorY = 0,
  addonTrigger = 'Blizzard_OrderHallUI',
  addonFrame = 'OrderHallCommandBar',
}

VeneerWorldStateHeadsUpMixin = {
}

VeneerWorldStateCurrencyMixin = {
}
VeneerWorldStateProgressMixin = {
  keepOpen = true,
}
VeneerWorldStateMixin = {
  maxHeight = 0,
  detectedFrames = {},
  anchorPoint = 'TOP',
}

function VeneerWorldStateMixin:Reset()
  for i, frame in ipairs(self.modules) do
    if frame.Reset then
      frame:Reset()
    end
  end
  self:Update()
end

function VeneerWorldStateMixin:Setup()
  --DEFAULT_CHAT_FRAME:AddMessage('Loaded')
  print('|cFFFFFF00'..self:GetName()..'|r:Setup()')

  self.modules = self.modules or {self:GetChildren()}
  for i, frame in ipairs(self.modules) do
    print('--'.. frame:GetName()..' exists')
    if frame.Setup then
      print('--'.. frame:GetName()..':Setup()')
      frame:Setup()
    end


    for k,v in pairs(WorldStateBlockMixin) do
      if not frame[k] then
        frame[k] = v
        if k:match('^On') then
          frame:SetScript(k, v)
        end
      end
    end

  end
  self:UnregisterEvent('PLAYER_LOGIN')
end

function VeneerWorldStateMixin:SetOrderHallUIMods()
  print('|cFFFF4400remove me', debugstack())
end


function VeneerWorldStateMixin:OnLoad ()
  self.modules = {self:GetChildren()}
  print('|cFFFFFF00'..self:GetName()..'|r!')
  self:RegisterEvent('PLAYER_ENTERING_WORLD')
  self:RegisterEvent('PLAYER_REGEN_ENABLED')
  self:RegisterEvent('PLAYER_REGEN_DISABLED')
  Veneer:AddHandler(self, self.anchorPoint, 2)
  SLASH_VENEERWORLDSTATE1 = "/vws"
  SLASH_VENEERWORLDSTATE2 = "/worldstate"
  SlashCmdList.VENEERWORLDSTATE = function()
    self:Reset()
  end
end

function VeneerWorldStateMixin:OnEvent(event, arg)
  print(event, arg)
  if event == 'PLAYER_ENTERING_WORLD' then
    self:Update()
  elseif event == 'PLAYER_REGEN_ENABLED' then
    self:Update(true)
  elseif event == 'PLAYER_REGEN_DISABLED' then
    self:Update(true)
  end
end

function VeneerWorldStateMixin:Update(isBatchUpdate)
  print('|cFFFFFF00All:Update()|r')
  for index, frame in ipairs(self.modules) do
    if frame.Update then
      print('  '..index..' |cFFFF00FFUpdate:|r '.. frame:GetName())
      frame:Update(isBatchUpdate)
      print('    ', frame:IsVisible(), frame:IsShown())
    end
  end
end

function VeneerWorldStateMixin:OnShow()
  print('OnShow()', debugstack())
end

function VeneerWorldStateMixin:Reanchor(isUpdate)
  print('  |cFF0088FF'..self:GetName()..':Reanchor()|r', #self.modules, 'blocks')
  self.maxHeight = 0
  local lastFrame
  for i, frame in ipairs(self.modules) do
    print('  '..frame:GetName()..':',frame:IsShown(), frame:GetHeight())
    if frame:IsShown() then
      if lastFrame then
        frame:SetPoint('TOP', lastFrame, 'BOTTOM')
      else
        frame:SetPoint('TOP', self, 'TOP')
      end

      self.maxHeight = self.maxHeight + frame:GetHeight()
      lastFrame = frame
    end
  end
  if (self.maxHeight == 0) or InCombatLockdown() then
    print ('  hiding; combat =', InCombatLockdown())
    self:SetShown(false)
  else
    print ('  height update:', self.maxHeight)
    self:SetHeight(self.maxHeight)
    self:SetShown(true)
  end

  if not isUpdate then
    Veneer:InternalReanchor(self, print)
  end

  WorldStateAlwaysUpFrame:ClearAllPoints()
  WorldStateAlwaysUpFrame:SetPoint('TOP', self, 'BOTTOM', 0, 0)
end



function VeneerWorldStateMixin:OnMouseDown()
end

function VeneerOrderHallMixin:Setup()
  print('|cFFFFFF00'..self:GetName()..':Setup()')
  self:SetParent(OrderHallCommandBar)
  self:RegisterEvent("ZONE_CHANGED");
  self:RegisterEvent("ZONE_CHANGED_INDOORS");
  self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
  self:SetShown(true)
end

function VeneerOrderHallMixin:OnLoad()
  Veneer:AddHandler(self, 'TOP', 1)
end

function VeneerOrderHallMixin:OnEvent(event, ...)

  print('|cFF00AAFF'..self:GetName()..'|r:'.. event, ...)
  self:Update()
end

function VeneerOrderHallMixin:OnShow()
  if OrderHallCommandBar then
    print('|cFF00AAFF'..self:GetName()..'|r:OnShow()', OrderHallCommandBar:IsShown(), self:IsShown())
    self:Update()
  end
  Veneer:DynamicReanchor()
end

function VeneerOrderHallMixin:OnHide()
  if OrderHallCommandBar then
    print('|cFF00AAFF'..self:GetName()..'|r:OnHide()', OrderHallCommandBar:IsShown(), self:IsShown())
  end
  Veneer:Reanchor()
end

function VeneerOrderHallMixin:Update()

  if not OrderHallCommandBar then
    print('|cFFFF4400'..self:GetName()..' updater called without target')
    return
  end

  OrderHallCommandBar:ClearAllPoints()
  OrderHallCommandBar:SetAllPoints(self)
  OrderHallCommandBar:SetWidth(600)
  OrderHallCommandBar.Background:SetColorTexture(0,0,0,0.5)
  OrderHallCommandBar.WorldMapButton:Hide()
  OrderHallCommandBar:EnableMouse(false)
  self:SetSize(OrderHallCommandBar:GetSize())

  print('|cFF00AAFF'..self:GetName()..'|r:Update()', OrderHallCommandBar:IsVisible(), self:IsShown())
  print(debugstack(6))
  Veneer:DynamicReanchor()
end

function VeneerWorldStateCurrencyMixin:OnLoad ()
  self:RegisterEvent("PLAYER_ENTERING_WORLD");
  self:RegisterEvent("ZONE_CHANGED");
  self:RegisterEvent("ZONE_CHANGED_INDOORS");
  self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
  self:RegisterEvent('CURRENCY_DISPLAY_UPDATE')
  self:RegisterEvent('CHAT_MSG_CURRENCY')
end

function VeneerWorldStateCurrencyMixin:OnEvent (event, arg)
  self:Update()
end
local zoneCurrency = {
  ['Suramar'] = 1155,
  ["Sashj'tar Ruins"] = 1155,
  ["Faronaar Ruins"] = 1155
}
local zoneBountyInfo = {
  ['Suramar'] = 1859,
  ["Sashj'tar Ruins"] = 1859,
  ["Faronaar Ruins"] = 1859,

  ['Azsuna'] = 1900,
}
local globalBountyInfo = {
}
function VeneerWorldStateCurrencyMixin:Update(isBatchUpdate)
  local zoneText = GetRealZoneText()
  if zoneText then
    local currency = zoneCurrency[zoneText]
    if currency then
      local name, earned, texture, earnedThisWeek, weeklyMax, totalMax = GetCurrencyInfo(zoneCurrency[zoneText])
      self.Icon:SetTexture(texture)
      self.Label:SetFormattedText("%d / %d", earned, totalMax)
      self:Show()
      self:SetWidth(self.Icon:GetWidth() + self.Label:GetStringWidth() + 6)
    end
  else
    self:Hide()
  end
end

function VeneerWorldStateProgressMixin:OnUpdate(sinceLast)
  self.timeLived = (self.timeLived or 0) + sinceLast
  if self.keepOpen then
    return
  end
  if self.timeLived >= 3 and not self.TimedFadeOut:IsPlaying() then
    self.TimedFadeOut:Play()
  end
end

function VeneerWorldStateProgressMixin:OnLoad()
  self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED')

  self:RegisterEvent("PLAYER_XP_UPDATE");
  self:RegisterEvent("UPDATE_EXHAUSTION");
  self:RegisterEvent("PLAYER_LEVEL_UP");
  self:RegisterEvent("PLAYER_UPDATE_RESTING");

  self:RegisterEvent("ARTIFACT_UPDATE");
  self:RegisterEvent("ARTIFACT_XP_UPDATE");
  self:RegisterEvent("ARTIFACT_CLOSE");
  self:RegisterEvent("ARTIFACT_MAX_RANKS_UPDATE");

  self.progressPercent = 0
  self.progressAmount = 0
  self.progressMax = 1
  self.progressOverflow = 0

end

function VeneerWorldStateProgressMixin:Setup()
  self:UpdateXPGain()
  if self.canGainXP then
    self.mode = 'xp'
  else
    self.mode = 'artifact'
  end
  print('setup mode:', self.mode)
end

function VeneerWorldStateProgressMixin:OnEvent(event, ...)
  local lastMode = self.mode
  if event == 'PLAYER_LEVEL_UP' or event == 'ENABLE_XP_GAIN' or event == 'DISABLE_XP_GAIN' then
    self:UpdateXPGain()
  elseif event == 'ARTIFACT_XP_UPDATE' or event == 'ARTIFACT_UPDATE' then
    self.mode = 'artifact'

  elseif event == 'PLAYER_EQUIPMENT_CHANGED' then
    local slot, hasEquip = ...
    if slot == 16 then
      self.mode = 'artifact'
      lastMode = nil
    end
  elseif event == 'PLAYER_XP_UPDATE' or event == 'PLAYER_LEVEL_UP' then
    print('forcing to XP mode')
    self.mode = 'xp'
  end
  self.modeChanged = (lastMode ~= self.mode)
  if self.modeChanged and self:IsVisible() then
    print('|cFF88FF00'..self:GetName()..'.TransitionFadeOut:Play()', event, ...)
    self:AnimateMode()
  else
    print('|cFFFFFF00'..self:GetName()..':Update()', event, ...)
    self:Update()
  end
end
function VeneerWorldStateProgressMixin:UpdateXPGain()
  self.canGainXP = (UnitLevel('player') < GetMaxPlayerLevel()) and (not IsXPUserDisabled())
  if not self.canGainXP then
    self.ProgressBar:SetColorTexture(0.75,0.75,0.75)
  end
end

local GetEquippedArtifactInfo = _G.C_ArtifactUI.GetEquippedArtifactInfo
local GetCostForPointAtRank = _G.C_ArtifactUI.GetCostForPointAtRank


local progressHandlers = {
  xp = function(self)
    local hasNewInfo, showChange = false, false
    local xp = UnitXP('player')
    local xpMax = UnitXPMax('player')
    local bonusXP = GetXPExhaustion()
    if xp then
      self.progressPercent = xp / xpMax
    end
    self.progressText = '|cFFFFCC00' .. UnitLevel('player') .. '|r ' .. xp .. '/' .. xpMax
    if bonusXP then
      self.progressOverflow = min(1,(bonusXP / xpMax))
      self.OverflowBar:SetColorTexture(0.5, 0.5,0.5, 0.25)
      self.OverflowBar:SetPoint('LEFT', self.ProgressBar, 'LEFT')
    else
      self.progressOverflow = nil
    end
    self.ProgressBar:SetColorTexture(0, 0.5,1,1)
    self.OverflowAnchor = self.ProgressBar
    self.hasNewInfo = (self.progressAmount ~= xp)
    showChange = (hasNewInfo and not self.modeChanged) and ((xp - self.progressAmount) / xpMax)

    self.progressAmount = xp
    self.progressMax = xpMax
    return hasNewInfo, showChange
  end,
  artifact = function(self)
    local hasNewInfo, showChange = false, false
    local itemID, altItemID, name, icon, totalXP, pointsSpent = GetEquippedArtifactInfo()
    if itemID then
      local nextRankCost = GetCostForPointAtRank(pointsSpent) or 0
      print('    API:', itemID, name, 'XP:', totalXP, 'Points:', pointsSpent, 'Next:', nextRankCost)
      hasNewInfo = (self.progressAmount ~= totalXP)
      showChange = (hasNewInfo and not self.modeChanged) and (((totalXP - self.progressAmount) / nextRankCost))

      if totalXP > nextRankCost then
        self.progressPercent = 1
      else
        self.progressPercent = totalXP / nextRankCost
      end

      self.progressText = name .. ' ('..pointsSpent .. '): '.. totalXP .. ' / ' .. nextRankCost

      self.ProgressBar:SetColorTexture(1,0.5,0,1)
      self.OverflowBar:Hide()

      if totalXP > nextRankCost then
        self.progressText = self.progressText .. ' Level Up!'
        self.progressOverflow = (totalXP - nextRankCost) / nextRankCost
        self.OverflowBar:SetPoint('LEFT', self.ProgressBG, 'LEFT')
        self.OverflowAnchor = self.OverflawBar
      else
        self.progressOverflow = nil
        self.OverflowAnchor = self.ProgressBar
      end

      self.progressAmount = totalXP
      self.progressMax = nextRankCost
    else
      self.progressOverflow = nil
      self.progressAmount = 0
      self.progressMax = 1
      self.progressText = ''
    end
    return hasNewInfo, showChange
  end
}

function VeneerWorldStateProgressMixin:Update(isBatchUpdate)

  local progressChange = false
  print('  current mode:', self.mode, 'vis:', self:IsVisible())
  if (not self.mode) or (not progressHandlers[self.mode]) then
    self:HidePanel()
    return
  end

  local hasNewInfo, showProgress = progressHandlers[self.mode](self)
  self:SetSize(600,16)
  if hasNewInfo then
    self.timeOut = nil
    self.timeLived = 0
  end


  if not self:IsVisible() then
    self.TransitionFadeIn:Play()
  else
    self:ShowPanel()
  end

  print('    Percent:', floor(self.progressPercent*100)/100, 'BarLength:', floor(self:GetWidth()* self.progressPercent), 'new:', hasNewInfo, 'shown:', self:IsShown())
  print('    Metrics:', self:IsVisible(), self:GetWidth(), self.ProgressBG:GetWidth())
  if self.progressPercent > 0 then
    self.ProgressBar:Show()
    self.ProgressBar:SetPoint('TOPRIGHT', self.ProgressBG, 'TOPLEFT', self:GetWidth()* self.progressPercent , 0)
    self.Label:SetText(self.progressText)

    self.ProgressSpark:ClearAllPoints()
    if self.progressOverflow then
      print('    Overflow:', self.progressOverflow)
      self.OverflowBar:Show()
      self.OverflowBar:SetWidth(self.progressOverflow * self:GetWidth(), 0)
    else
      self.OverflowBar:Hide()
    end
    self.ProgressSpark:SetPoint('CENTER', self.OverflowAnchor, 'RIGHT', 0, 0)

  else
    self.ProgressBar:Hide()
  end

  if self.progressOverflow and (self.progressOverflow >= self.progressPercent) then
    self.OverflowBar:SetDrawLayer('ARTWORK', 1)
    self.ProgressBar:SetDrawLayer('ARTWORK', 2)
  else
    self.OverflowBar:SetDrawLayer('ARTWORK', 2)
    self.ProgressBar:SetDrawLayer('ARTWORK', 1)
  end

    if progressChange then
    self:AnimateProgress(progressChange)
  end

  self.modeChanged = nil
end


function VeneerWorldStateProgressMixin:AnimateProgress(progressChange)


  local changeAnchor = (self.progressOverflow and self.OverflowBar) or self.ProgressBar
  local progressWidth = self:GetWidth() * min(progressChange, changeAnchor:GetWidth())

  self.ProgressAdded:Show()
  self.ProgressAdded:ClearAllPoints()
  self.ProgressAdded:SetPoint('TOPRIGHT', changeAnchor, 'TOPRIGHT', 0, 0)
  self.ProgressAdded:SetPoint('BOTTOMLEFT', changeAnchor, 'BOTTOMRIGHT', - (progressWidth), 0)

  print('  Render change:', progressWidth, changeAnchor)
  self.ProgressFlash.translation:SetOffset(progressWidth, 0)
  self.ProgressFlash:Play()
end

function VeneerWorldStateProgressMixin:OnMouseDown(button)
  if button == 'RightButton' then
    if self.keepOpen then
      self.keepOpen = nil
      self.timeLived = 1000
    else
      self.keepOpen = true

      self.modeChanged = true
    end
    print('keepOpen =', self.keepOpen)
    self:Update()
  else

    if self.mode == 'xp' then
      self.mode = 'artifact'
    else
      if not self.canGainXP then
        return
      end
      self.mode = 'xp'
    end
    print('|cFFFF4400Change mode:', self.mode)


    self:AnimateMode()
  end

end

function VeneerWorldStateProgressMixin:AnimateMode()

  self.TransitionFadeIn:Stop()
  print('|cFF88FF00'..self:GetName()..'.TransitionFadeOut:Play()')
  self.modeChanged = true
  self.TransitionFadeOut:Play()
end

do
  function WorldStateBlockMixin:ShowPanel()
    print('|cFF0088FF'..self:GetName()..':ShowPanel()')
    self:SetShown(true)
    self:SetAlpha(1)
    VeneerWorldState:Show()
  end
  function WorldStateBlockMixin:HidePanel()
    print('|cFF0088FF'..self:GetName()..':HidePanel()')
    self:SetShown(false)
    VeneerWorldState:Reanchor()
  end

  function WorldStateBlockMixin:OnSizeChanged ()
    local h = self:GetHeight()
    if h > VeneerWorldState.maxHeight then
      VeneerWorldState.maxHeight = h
      VeneerWorldState:SetHeight(h)
      print('updating max height:', h)
    elseif h < VeneerWorldState.maxHeight then
      VeneerWorldState:Reanchor()
    end
  end
  function WorldStateBlockMixin:OnHide ()
    print('|cFF0088FF'..self:GetName()..':OnHide()')
    VeneerWorldState:Reanchor()
  end
  function WorldStateBlockMixin:OnShow ()
    self.timeLived = 0
    print('|cFF0088FF'..self:GetName()..':OnShow()')
    VeneerWorldState:Reanchor()
  end
  function WorldStateBlockMixin:Setup()
    print('|cFF0088FF'..self:GetName()..':Setup()|r -- nop')
    self:Update()
  end
  function WorldStateBlockMixin:Reset()
    print('|cFF0088FF'..self:GetName()..':Reset()')
    self.keepOpen = true
    self:Setup()
  end
end