Windowerアドオンを作ってみよう!その3[FF11]

f:id:yyoshisaur:20190227133637p:plain
今回もWindowerアドオンを作っていきます。
前回、前々回で作ったアドオンはプレイヤーの入力に応じて動作するものでした。
yyoshisaur.hatenablog.com

今回はNPCの行動に応じて動作するアドオンを作ってみたいと思います。

作りたいもの

今回は上位ミッションBF"☆武士道とは"でTenzenの使用する"八重霞", "白羽取り"効果時間を表示するアドオンを作ります。

岩餅棒を得るために上位ミッションBFによく行っていますが、試練系のBFが混んでいる場合は"☆武士道とは"によく行きます。
"☆武士道とは"でTenzenが使用してくる"八重霞", "白羽取り"はWSを無効にしたり、カウンターがあったりと強力です。
その効果時間を知らせてくれるアドオンがあれば、アビリティの開始や効果が切れた時を把握でき、効率的に攻撃ができると思います。
(※"白羽取り"の場合、効果中はその場から動かなくなるので、離れていれば効果時間を把握できます。)


"action"イベント

今回はNPCの行動をトリガーにしてアドオンを動作させる必要があります。
PC, NPCが行動した時に呼ばれるイベントとして"Action Event"があります。
Action Event · Windower/Lua Wiki · GitHub
このイベントはWSの実行、魔法の詠唱や通常攻撃などのアクションで登録した処理が呼ばれ、
誰がどんな行動をしたのかという情報が得られます。
このイベントを使って、目的のアビリティが使用されたタイミングでタイマーを開始されるようにします。
アビリティの効果時間は難易度によって変わるか分かりませんが、私が調べた限りでは「とてもむずかしい」で八重霞が45秒、白羽取りが30秒でした。
パケットを見てみると以下のようなデータが八重霞の実行時に来ています。
f:id:yyoshisaur:20190226084542p:plain
Paramの"3186"というのが八重霞のIDです。
(敵が使用するアビリティはres/monster_abilities.luaで確認できます。)
Actorはこの行動を行ったPCまたはNPCのIDでwindower.ffxi.get_mob_by_idを使うと行動したキャラクターの詳細が取得できます。
FFXI Functions · Windower/Lua Wiki · GitHub

"action"イベントの他に"incoming chunk"イベントでid=0x028の時に同等の情報が取得できます。

タイマー

WindowerプラグインのTimersにはユーザーが任意に設定できるカスタムタイマーがあります。
効果時間を表示させるタイマー部分はこのタイマーを使うことにします。

//timers c timer_name time up/down icon

timer_nameは表示されるタイマー名
timeはタイマー時間
up/downはタイマーをカウントアップ or カウントダウン
iconは表示されるタイマーのアイコン

実装

イベントの処理と表示方法が決ったので、実装していきます。

local tenzen = {
    [3186] = {id=3186,english="Yaegasumi",japanese="八重霞",duration=45,icon='abilities/00205.png'},
    [3251] = {id=3251,english="Amatsu: Shirahadori",japanese="白羽取り",duration=30,icon='abilities/00206.png'},
}

local tenzen_name = 'Tenzen'

windower.register_event('load', function()
    -- ロード時に言語を取得
    lang = windower.ffxi.get_info().language:lower()
end)

-- アクション イベントの処理
windower.register_event('action', function(act)
    -- Actor IDからモブの情報を取得
    local mob_info = windower.ffxi.get_mob_by_id(act.actor_id)

    -- モブの名前が"Tenzen"、行動が"八重霞"または、"白羽取り"ならタイマー作成
    if mob_info and  mob_info.name == tenzen_name then
        if tenzen[act.param] then
            local skill_name = tenzen[act.param][lang]
            local skill_duration = tenzen[act.param].duration
            local icon = tenzen[act.param].icon
            local timer_commnad = 'timers c "'..skill_name..'('..mob_info.name..')'..'" '..skill_duration..' down '..icon
            windower.send_command(timer_commnad)
        end
    end
end)

使ってみる

"☆武士道とは"に行って動作確認をしてみましょう。
期待通り、アビリティのタイミングでタイマーが表示されました。
f:id:yyoshisaur:20190226084557p:plain f:id:yyoshisaur:20190226084608p:plain

今回作ったNPCの行動をトリガーにする方法は色々応用ができそうです。
今回作ったアドオン"tenzentimer"のソースコードGitHubにあります。
エリアの情報を取得して、"武士道とは"の戦闘エリア"海獅子の巣窟"でのみ動作するようにしています。
また、戦闘不能などでエリアチェンジをしてタイマーが残っている場合はタイマーを削除するようにしています。
github.com