WeakAuras

WeakAuras

200M Downloads

GetTotemInfo vs GetTotemTimeLeft

mrbuds opened this issue ยท 10 comments

commented

Is there an existing issue for this?

  • I have searched the existing open and closed issues.

Description

TotemFrame.lua use the function GetTotemTimeLeft to show remaining time
Totem trigger use startTime + duration from GetTotemInfo

following aura show difference between these 2 when i drop a Earthbind Totem

!WA:2!1rvZUTTrq4iOdfGOiWrhCAt7bcx0azevKeJICOPPaMUsXUvXYLIUo9e7sUdf3KL7Uy3LYs5Oqrrp7R9Mo3Erpc5jGWOpb5ripbDwsfBdJyccWzw8nFZFFlBnOtrhAh6FTTwwA5mbOhDC0WdoSFyQKl1)uB8zfLzuCY8iyMDRVoDzAPXklCEZATrwPi1YKIUB75JpCzkH7t8FM)ZbBK0cfrScyiKz7(4gexbwCp3RXs0whQE(0snXr2vc)arM8dH2efmtXAG5ccHEbb(eb1V7LUp4cc32xQ9F0tVcljyGxlYl9(b)hvFY1s13uxvOv3g(QPtPzcBxsp)KT9ab9CtoHkp93gLLza7xERverAUuFKerLSx)dJ6hQ8VYanotQli2yvSfjETxl1gxoKpwrjwiPS(Z7iL4XyjLEcJAZd2fD1K6nG5jH1DGxsgtWm5Eb4hR3cRMnzcOn3((61M)5skYxww0CfO3V)WJgC8Wal6esW51olmkGZpGA8ENPmbMcc7yenB2Q492DCu84ODdJckrYtCDbOdfKcW4fwdnzFGWT5xe6rAadnC8r9ho8SsX6sWtDhxvpfIA8FHKc)ZTuBDZtMcjng3fWVRU)ndIdtiPZJZ4sPo)mdWZAg8bJIIg9IGmPWQ2yGM9g)FPKqr6i(rrQV4Jqy6AJaHuabCjHoiXs4ydTzyrj3Y8cWXu6Mvp0lmLtmgNvGH9gWzSWLPXOZNVwp8Yg9q7pAUuRncD9aDPgM4uC4(iWIOoJiyf1IWNuTXG3cedm2QbXeB(NuD3QEN)brESBfQnqQuqnlC4CCu1lOGWedQ(UA0vpT67REg(9ox)K3Jdkqli8FfjbP7VvF1npOvAiL5q1EPlDSAbONEwtB2kbpmJnXt)kugZYMhmS)GOLwz60gU)Sw)7QTy0Doeov9GBol05OYILgBZ1GjxYPZxLPrTg2)4QR97BUBnWDKRvtgVxy)(hQNVUk2PKrxPgAOV2(Z7)4N)TNJxEq8Junv7ItLA6jAIAXjRnw1SS2R(xFTA1Q9su6c06RA)XNUIjAkpmAVLO(oSErzU3Mv39C0nHK(6j4)rf0oMD(ryANP)3l)))
Wow_2024-09-03_01-53-05.mp4
function()
    local a = GetTotemTimeLeft(1)
    
    local _, _, startTime, duration = GetTotemInfo(1)
    local expirationTime = startTime and (startTime + duration) or 0;
    local b =  startTime and startTime > 0 and expirationTime - GetTime() or 0
    print(a, b)
end

When i drop totem, using data from GetTotemInfo timer start at 19.5379 instead of 20

Totem visually despawn when GetTotemTimeLeft reach 0

Problem is that GetTotemTimeLeft is only accurate when totem is casted, when checking later with a scheduled scan the data is not good enough

A solution could be to keep track of timers in GenericTrigger.lua, only update value when there was no totem or value is higher than calculated remaining time + gcd?

WeakAuras Version

dev

World of Warcraft Flavor

Retail (Default)

World of Warcraft Region

EU

Tested with only WeakAuras

I got this issue with only WeakAuras enabled

Lua Error

No response

Reproduction Steps

drop a Earthbind Totem on shaman

Last Good Version

No response

Screenshots

No response

Export String

No response

Bisector Report

No response

commented

Can't demo warlocks summon multiple totems of the same type?

Yes, it's even on a 1 min cd now so it's not quite so annoying to test with: Cast Call Dreadstalkers, then Summon Demonic Tyrant (extending all totem summons by 15 seconds), and then Call Dreadstalkers again.

Also, I believe restoration shamans can summon two Healing Stream Totems at once.

commented

old

Wow_2024-09-04_16-00-51.mp4

new

Wow_2024-09-04_18-45-20.mp4

using this

function Private.InitTotemTimer()
  print("InitTotemTimer")
  local totemInfo
  if not Private.ExecEnv.GetTotemTimer then
    totemInfo = {}

    function Private.ExecEnv.GetTotemTimer(totemSlot)
      local info = totemInfo[totemSlot]
      if info then
        print("GetTotemTimer", info.duration, info.startTime)
        return info.startTime, info.duration
      end
    end

    local totemTimerFrame = CreateFrame("Frame")

    -- run every frame until GetTotemTimeLeft has changed
    local function recheckTimers(self, elapsed)
      local stillrecheck = false
      local sendEvent
      for slot, info in pairs(totemInfo) do
        if info.recheck then
          local newTimeLeft = GetTotemTimeLeft(slot)
          if newTimeLeft ~= info.duration then
            info.duration = (GetTime() - info.startTime) + newTimeLeft
            print("duration2", info.duration, "exp", info.startTime + info.duration)
            info.recheck = false
            sendEvent = true
          else
            stillrecheck = true
          end
        end
      end
      if not stillrecheck then
        totemTimerFrame:SetScript("OnUpdate", nil)
      end
      if sendEvent then
        WeakAuras.ScanEvents("WA_TOTEM_UPDATE")
      end
    end

    local function OnEventScript(self, event, totemSlot)
      local timeLeft = GetTotemTimeLeft(totemSlot)
      print("duration1", timeLeft, "exp", GetTime() + timeLeft)
      totemInfo[totemSlot] = { duration = timeLeft, startTime = GetTime(), recheck = true }
      WeakAuras.ScanEvents("WA_TOTEM_UPDATE")
      totemTimerFrame:SetScript("OnUpdate", recheckTimers)
    end

    totemTimerFrame:RegisterEvent("PLAYER_TOTEM_UPDATE")
    totemTimerFrame:SetScript("OnEvent", OnEventScript)
  end
end
commented

I think totem slot numbers are not stable, that is a totem that is in slot X will when a totem with a lower slot number expires change it slot number. Though I might be misremembering. Probably worth testing

Can't demo warlocks summon multiple totems of the same type?

And historical, the first implementation of Gargoyle increased its duration each time the player used runic power. I'm not 100% certain it was an totem back then though. But class designers have used the totem api for lots of things, which behave in lots of ways...

Is this totem inaccuracy new with TWW? Or what triggered this investigation?

commented

I can't tell if this inaccuracy is new, this discord thread caught my attention https://discord.com/channels/172440238717665280/1280310878096593058/1280310878096593058 and i was surprised to see the game wasn't using GetTotemInfo

You guys convinced me this is something wow's dev needs to solve, and we shouldn't try to work around it

Opened a ticket at Stanzilla/WoWUIBugs#651

commented

There is also C_TooltipInfo.GetTotem, though it isn't that interesting:
image

commented

So some totems do have secondary effects that can be tracked, e.g. I think there's a shielding totem, spirit link gives a buff etc. I'd would want to test how the timing of these match up to what the totem apis return.

GetTotemTimeLeft() is clearly some rounded value and assuming that on initial totem dropping the totem duration is exactly that rounded value seems a questionable assumption.

commented

test with SLT

function()
    local a = GetTotemTimeLeft(1)
    
    local _, _, startTime, duration = GetTotemInfo(1)
    local expirationTime = startTime and (startTime + duration) or 0;
    local b =  startTime and startTime > 0 and expirationTime - GetTime() or 0
    
    local sltInfo = C_UnitAuras.GetPlayerAuraBySpellID(325174)
    local slt = sltInfo and true or false 
    print(a, b, slt)
end
Wow_2024-09-03_14-48-34.mp4

image

buff is still active when timer from GetTotemInfo is negative

commented

Buff is still active for a few frame after GetTotemTimeLeft return 0

commented

Oh boy what an output, the last line is:
0 -1.1138.. true

So the GetTotemInfo is off by a whole second.

commented

Lookng at the video again, at the start the difference is .96s, at the end of the video it's 1.11.

grafik

So this screenshot from the video shows the exact timestamp from when the duration jumps from 6 to 5 in GetTotemTimeLeft, which seems to indicate it's a simple "ceil".

I think our options are:
a) Keep using the GetTotemInfo (verify that we show the totem as long as GetTotemInfo returns something, even if we get negative times)
b) Get an initial time from GetTotemTimeLeft and assume that all totem duration are always integers at the start
c) Sync via GetTotemTimeLeft, that is check every frame whether that switched and then sync to that

We should also complain to blizzard, that api stinks.