2019年12月18日水曜日

ステータス(buff)の残り時間の取得方法


ヘイストやリフレシュなどの buff があと何分もつかは、公式の機能 /statustimer により画面上部のステータスアイコン上に数値で表示される。しかし windower本体はその数値を管理してはいない。Timersプラグインにはデータがあると思われるが、アドオンからはプラグインの内部データにアクセスすることはできないのでbuffが切れる直前に何かを実行させたいと思っても簡単にはできない。

"windower duration timer"でググるとこんな投稿があった
If you're working outside of gearswap, or if you absolutely need the duration, the incoming packet which contains that information is 0x063. The packet id is reused for different types of information, but will contain the timestamps that indicate when buffs will wear off when the fifth byte has the value 9. This change was made to the packet in the update that introduced the timer display.

GearSwapはbuff情報を自前で管理している。buffactiveにリアルタイムのbuff情報が格納されている。そのbuffactiveよりも詳細な情報が player.buff_details に格納されていて、buff がいつ切れるかの時間も入っている。以下は、packet_parsing.lua の該当部分のコード。
parse.i[0x063] = function (data)
  if data:byte(0x05) == 0x09 then
    local newbuffs = {}
    for i=1,32 do
        local buff_id = data:unpack('H',i*2+7)
        if buff_id ~= 255 and buff_id ~= 0 then -- 255 is used for "no buff"
          local t = data:unpack('I',i*4+0x45)/60+501079520+1009810800
          newbuffs[i] = setmetatable({
            name=res.buffs[buff_id].name,
            buff=copy_entry(res.buffs[buff_id]),
            id = buff_id,
            time=t,
            date=os.date('*t',t),
         },
         {__index=function(t,k)
           if k and k=='duration' then
              return rawget(t,'time')-os.time()

           else
              return rawget(t,k)
           end
        end})
     end
  end
        table.reassign(_ExtraData.player.buff_details,newbuffs)

GearSwap のユーザーlua ファイルの中であれば player.buff_details[i].duration で buff の残り時間が参照できると思われる。

そして、ユーザーイベント関数 buff_change(name,gain,buff_details) の引数として渡される buff_details に player.buff_details の値が格納されているので、それを利用することも可能。




windower本体がこのbuff情報を正式に管理してくれるとありがたいのだが。

0 件のコメント:

コメントを投稿