羅盤(ジオ系風水魔法)の設置位置について

f:id:yyoshisaur:20200403023702j:plain
ジオ系の風水魔法はグラウンドターゲットを使うことで、羅盤を設置する位置を調整できます。
グラウンドターゲット/FF11用語辞典

Windowerのアドオンから制御したい場合、どのようにすればよいのか気になったので調べてみました。
だたアドオンから制御して何か便利になるのかというと、特に有用な使用方法は思いつきませんでした。


魔法のアクションに関係するパケットは、outgoing 0x01AのCategory = 0x03です。
このパケットの'X Offset', 'Y Offset', 'Z Offset'でジオ系風水魔法の設定位置を指定しています。
(グラウンドターゲットで位置を変更した場合にこのプロパティの値が変化します。)
ジオ系風水魔法の時のみこのプロパティは有効になるようです。

-- libs/fields.luaより抜粋

enums['action'] = {
    [0x03] = 'Magic cast',
}

-- Action
fields.outgoing[0x01A] = L{
    {ctype='unsigned int',      label='Target',             fn=id},             -- 04
    {ctype='unsigned short',    label='Target Index',       fn=index},          -- 08
    {ctype='unsigned short',    label='Category',           fn=e+{'action'}},   -- 0A
    {ctype='unsigned short',    label='Param'},                                 -- 0C
    {ctype='unsigned short',    label='_unknown1',          const=0},           -- 0E
    {ctype='float',             label='X Offset'},                              -- 10 -- non-zero values only observed for geo spells cast using a repositioned subtarget
    {ctype='float',             label='Z Offset'},                              -- 14
    {ctype='float',             label='Y Offset'},                              -- 18
}

名称がOffsetとなっているように、風水魔法のターゲットから羅盤を設置したい位置への相対距離を指定します。
'Z Offset'は高さですが、このプロパティの値を変化させても羅盤のZ軸の移動はできませんでした。

試してみる

羅盤の位置が制御できるのか試してみます。
風水魔法のターゲットがPC(強化系), NPC(弱体系)問わず、羅盤を常に風水士自身の位置に設置するようなサンプルを作ってみます。

require('luau')
local packets = require('packets')

-- 何かジオ系風水魔法のID
local something_geo_ids = L{798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827}

windower.register_event('outgoing chunk', function(id, original, modified, injected, blocked)
    if id == 0x01A then
        local p = packets.parse('outgoing', original)
        if p['Category'] == 0x03 then -- Magic cast
            if something_geo_ids:contains(p['Param']) then
                local t = windower.ffxi.get_mob_by_id(p['Target'])
                local me = windower.ffxi.get_mob_by_target('me')
                
                p['X Offset'] = me.x - t.x
                p['Z Offset'] = me.z - t.z
                p['Y Offset'] = me.y - t.y
                
                return packets.build(p)
            end
        end
    end
end)