Mote-libsを使ってみる その2

前回、Mote-libsをset_language('japanese')の環境で使用できるようにしました。
今回は、Mote-libsを使用したGearSwapのスクリプトについてです。

サンプルやウィキが用意されているようなので参考にします。
サンプルは最終更新日がかなり前なので、ジョブによっては現在の仕様とは異なる部分があるかもしれません。
サンプル(GitHub - Kinematics/GearSwap-Jobs: Repository for GearSwap lua files for various jobs)
ウィキ(Home · Kinematics/GearSwap-Jobs Wiki · GitHub)

初期化

テンプレート(https://github.com/Kinematics/GearSwap-Jobs/blob/master/Template.lua)を参考にジョブの初期化の関数をみていきます。

インクルード
function get_sets()
    mote_include_version = 2
    include('Mote-Include.lua')

    set_language('japanese') -- 日本語で使用する
end

mote_include_version = 2としないと、古いバージョン(GearSwap/libs/rev1/)のMote-libsが使用されるようです。(mote_include_versionが未定義の場合も同様)

セットアップ

監視したいバフやモードを定義します。
job_setup()を実行した直後にuser_setup()が実行されるので、どちらに何を記述しても問題ないと思います。
init_gear_sets()には使用する装備セットを定義します。

function job_setup()
    state.Buff['hoge'] = buffactive['hoge'] or false
end

function user_setup()
    state.OffenseMode:options('Normal')
    state.RangedMode:options('Normal')
    state.HybridMode:options('Normal')
    state.WeaponskillMode:options('Normal')
    state.CastingMode:options('Normal')
    state.IdleMode:options('Normal')
    state.RestingMode:options('Normal')
    state.PhysicalDefenseMode:options('PDT')
    state.MagicalDefenseMode:options('MDT')

    select_default_macro_book()
end

function init_gear_sets()
-- 装備セットを定義
end

user-globals.lua, <charactername>-globals.luaサイドカーファイルを用意すると、キャラクター毎に設定を共通化することもできるようです。
サイドカーファイルは自動で読み込まれますが、以下のようなフォルダ構成、ファイル名で保存しておく必要があります。

-- サイドカーファイルの命名規則
local filenames = {
    player.name..'_'..job..'_gear.lua',
    job..'_gear.lua',
    'gear/'..player.name..'_'..job..'_gear.lua',
    'gear/'..job..'_gear.lua',
    'gear/'..player.name..'_'..job..'.lua',
    'gear/'..job..'.lua'
    }

装備セット

Mote-libsは装備セットを定義するだけで、着替えを行ってくれます。
装備セットの定義はモードとも関係し少し複雑になるので、モードを考慮しない場合をみていきます。

ファストキャストを例に装備セットの定義をみていきます。

function init_gear_sets()
    sets.precast.FC = {} -- spell.action_typeが'Magic'の場合
    sets.precast.FC.BardSong = {} -- spell.typeがBardSongの場合
    sets.precast.FC['暗黒魔法'] = {} -- spell.skillが暗黒魔法の場合
    sets.precast.FC['インパクト'] = {} -- spell.nameがインパクトの場合
    sets.precast.FC['暗黒魔法']['デス'] = {} -- spell.skillが暗黒魔法でspell.nameがデスの場合
    sets.precast.FC['ElementalNinjitsu'] = {} -- spell_mapsがElementalNinjitsuの場合
end

sets.precast.FCはすべての魔法で最初に候補になる装備セットです。
特定の魔法ではファストキャストではなく、"○○魔法の詠唱時間-"の装備を使用する場合があります。
呪歌の場合は、sets.precast.FC.BardSongというようにsets.precast.FCの下にspell.typeで装備セットを定義すると、sets.precast.FCより優先して選択されます。
同様にspell.skillやspell.nameでも定義ができます。
sets.precast.FC['暗黒魔法']['デス']のように、spell.skill(またはspell.type)とspell.nameの2つを指定して、定義することもできます。
また、Mote-Mappings.luaにあるspell_mapsに記述された魔法のグループ名でも指定することができます。

アビリティの場合、ジョブアビリティはsets.precast.JA、ウェポンスキルはsets.precast.WSとなります。
クイックドローなどspell.typeが"JobAbility"でないアビリティは、以下のように定義するこができます。
spell.typeの指定がない場合は、sets.precast.JA以下が候補になります。

sets.precast.CorsairShot = {} -- クイックドロー
sets.precast.Ward['ヴァリエンス'] = {} -- または、sets.precast.JA['ヴァリエンス'] = {}

装備セットの選択については、こちらのブログ記事がとても参考になりました。
yamamikan.blogspot.com

モード

モードを変更することで選択される装備セットを変化させることができます。
モードは予めいくつかMote-Include.luaで定義されています。これらのモードは選択されたモードによって装備を変更する処理がMote-libs内に組み込まれています。
この他にも自分でモードを追加することができ、モードによる装備選択の処理を追加することもできます。

抜刀時の装備セットを制御するモード
-- Mote-Include.lua
state.OffenseMode         = M{['description'] = 'Offense Mode'}
state.HybridMode          = M{['description'] = 'Hybrid Mode'}
state.CombatWeapon        = M{['description']='Combat Weapon', ['string']=''} 
state.CombatForm          = M{['description']='Combat Form', ['string']=''}

抜刀時の装備は、sets.engagedに定義します。
上記の4つのモードは、sets.engaged[CombatForm][CombatWeapon][OffenseMode][HybridMode]で参照されます。(参考 Mote-Include.lua get_melee_set)
すべてのモードを定義する必要はありませんが、装備選択の自由度は高そうです。

例として、OffenseModeに'Normal', 'Stp'、HybridModeに'Normal', 'DT'を設定した場合、sets.engagedには以下の4つを定義します。

state.OffenseMode:options('Normal', 'Stp')
state.HybridMode:options('Normal', 'DT')

sets.engaged = {} -- OffenseMode='Normal', HybridMode='Normal'で選択される装備セット
sets.engaged.Stp = {} -- OffenseMode='Stp', HybridMode='Normal'
sets.engaged.DT = {} -- OffenseMode='Normal', HybridMode='DT'
sets.engaged.Stp.Dt = {} -- OffenseMode='Stp', HybridMode='DT'

抜刀時の装備セットは、上記4つのモード以外にもClasses.CustomMeleeGropusやstate.DefenseMode、state.Kitingによっても変更されます。(参考 Mote-Include.lua get_melee_set)

モードの変更

モードの変更は、selfcommandで行うことができます。
デフォルトのキーバインドではF9にOffenseModeの変更、Ctrl+F9にHybridModeの変更がアサインされています。

send_command('bind f9 gs c cycle OffenseMode')
send_command('bind ^f9 gs c cycle HybridMode')

Input Commands :: Windower Documentation

モードの追加

Mote-Include.luaで定義されてる以外のモードも定義することができます。
例としてルザフリングを使用する、しないの設定を行うモードを作ってみます。

state.LuzafRing = M(false, "Luzaf's Ring")
sets.LuzafRing = {on = {right_ring="ルザフリング",}, off = {}}

function job_post_pretarget(spell, action, spellMap, eventArgs)
    if spell.type == 'CorsairRoll' or spell.name == 'ダブルアップ' then
        equip(sets.LuzafRing[state.LuzafRing.current])
    end
end

-- gs c toggle LuzafRingでモードを変更します。

モードはModes.luaにあるM()で定義します。
ルザフリングの場合、モードの状態は"使用する"、"使用しない"の2つしかないので、ブーリアン(true, false)のモードで定義しました。
(モードはブーリアン、文字列、リストのいずれかで定義できます。Commands · Kinematics/GearSwap-Jobs Wiki · GitHub)
追加したモードによる装備変更はMote-libsが行ってくれないので、自身で実装する必要があります。
ブリーアンのモードの場合、モードの状態はstate.LuzafRing.current = 'on'または、'off'になります。(state.LuzafRing.valueブーリアン)

ファントルロール、ダブルアップの効果範囲を確認したいので、job_post_pretargetに実装しました。

precastやmidcastなどの各アクションではdefault_<action>で装備セットの選択が行われます。(参考 Mote-Include.lua handle_action)
job_<action>やjob_post_<action>, user_<action>, user_post_<action>を実装することでdefault_<action>の前後で任意の処理を実行できるようになっています。

また、M()で定義したモードは、Mote-SelfCommands.luaでモード名を指定して各種コマンド(gs c toggle <モード名>など)が使用できます。

TreasureMode

Mote-TreasureHunter.luaで定義してあるモードです。
メインシーフ以外はトレジャーハンター(トレハン)は4が上限で、上昇の判定もありません。
そのため、一度だけトレハン装備で攻撃し、トレハンを付与するといった行動をよく行ないます。
このTreasureModeはそういった行動を自動化してくれます。

include('Mote-TreasureHunter')
sets.TreasureHunter = {} -- トレハン装備
-- gs c cycle TreasureMode

TreasureModeを"Tag"にすると、まだトレハンを付与していない敵には抜刀時にトレハン装備に変更し、1度オートアタックをすると通常の装備に戻ります。
メインシーフの場合は、"Tag"の他に"SATA"(不意打ち、だまし討ち時にトレハン装備)、"Fulltime"(常時トレハン装備)のモードがあるようです。