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

ジョブによっては特定の条件で着替えたい装備が変わることがあります。
Mote-libsでは自動で装備を選択してくれますが、バフの有無などの条件で装備を切り替えるには少し処理を追加する必要があります。
今回はMote-libsを使ってスクリプトを作ってみたので、その中から装備選択を制御する方法をいくつか書いてみたいと思います。
(方法は色々あると思いますので、参考程度にお読みください。)

震天動地の章

学者が震天動地の章で連携を作成する場合、累積魔法耐性に注意して連携作成時の精霊魔法のダメージを小さくします。
震天動地の章のバフがある場合、通常の精霊魔法装備とは異なる装備に変更するという動作を実現したいと思います。

連携作成には詠唱時間の短いI系の精霊魔法が使用されるので、midcastでは着替えを行わず、precastの装備を維持するようにします。
(midcastで着替えを行っても間に合いそうですが、ラグなどで着替えが間に合わないかもしれないので念のため)
装備の切り替えには、classes.CustomClassを使用してみます。

-- function job_setup()
state.Buff['震天動地の章'] = buffactive['震天動地の章'] or false

-- function init_gear_sets()
sets.precast.FC['震天動地の章'] = {} -- 連携作成時の精霊魔法装備(高ファストキャスト、低魔攻、低INT)

sets.midcast.FastRecast = {waist="ニヌルタサッシュ",} -- 計略時のリキャスト短縮装備

function job_precast(spell, action, spellMap, eventArgs)
    set_custom_class(spell)
end

function job_midcast(spell, action, spellMap, eventArgs)
    if classes.CustomClass == '震天動地の章' then
        eventArgs.handled = true
    end
end

function set_custom_class(spell)
    if spell.skill == '精霊魔法' then
        if state.Buff['震天動地の章'] then
            classes.CustomClass = '震天動地の章'
        end
    end
end

job_precastで精霊魔法かつ震天動地の章のバフがあればclasses.CustomClassの値を'震天動地の章'に変更して、default_precastの装備選択でsets.precast.FC['震天動地の章']が選択されるようにしています。
classes.CustomClassはaftercastのcleanup_aftercastによってnilに初期化されます。(classes.CustomClassの値は保持されず、アクション毎に初期化されます。)

job_midcastでeventArgs.handledをtrueにして、Mote-libsでの装備選択をスキップしています。
job_midcastでeventArgs.handledをtrueに設定すると後に実行されるdefault_midcastが実行されず、precastの装備を維持することができます。
しかし、user_post_midcastやjob_post_midcastは実行されるので、そのような関数で着替えを行っている場合は注意する必要があります。

もう1つ注意する点としてMote-Glocals.luaのuser_midcastを使用している場合、job_midcastのより先に実行されるのでsets.midcast.FastRecastに装備を定義しているとその装備に着替えが行われます。
(上記の場合では、midcastの着替えが確実に間に合うであろう計略時のリキャスト短縮目的で装備ヘイストが増加する装備を定義しています。)

強化魔法

赤魔道士では、自身と他者で強化魔法の装備が異なる場合があります。
(Mote-libsを使用しないGearSwapユーザースクリプトで実現する方法は以前記事にしました。)
yyoshisaur.hatenablog.com

アクションのターゲットによって装備を切り替えることは装備セットの記述だけでは実現できないので、追加で処理を実装する必要があります。
ここではSpellMapを変更することでこの動作を実現してみたいと思います。

-- function job_setup()
state.Buff['コンポージャー'] = buffactive['コンポージャー'] or false

-- function init_gear_sets()
sets.midcast['強化魔法'] = {} -- 自身への強化魔法
sets.midcast['強化魔法'].Others = {} -- 他者への強化魔法


sets.midcast['強化魔法'].Refresh = {} -- 自身へのリフレシュ装備
sets.midcast['強化魔法'].Refresh_Others = {} -- 他者へのリフレシュ装備

sets.midcast['強化魔法'].Phalanx = {} -- 自身へのファランクス装備
sets.midcast['強化魔法'].Phalanx_Others = {} -- 他者へのファランクス装備
-- etc.

function job_get_spell_map(spell, default_spell_map)
    local new_spell_map = default_spell_map

    if spell.skill == '強化魔法' then
        if spell.target.type ~= 'SELF' and state.Buff['コンポージャー'] then
            new_spell_map = 'Others'
            if S{'Phalanx', 'Refresh', 'Regen', 'Protect', 'Shell'}:contains(default_spell_map) then
                new_spell_map = default_spell_map..'_'..new_spell_map
            end
        end
    end

    return new_spell_map
end

job_get_spell_mapで任意のSpellMapを返すことで装備選択に使用されるSpellMapを変更することができます。
他者への強化魔法の場合、効果アップの装備があるSpellMapについてはSpellMapの後ろに"_Others"を追加して、その他は"Others'というSpellMapにしています。
sets.midcast["強化魔法"].Othersやsets.midcast["強化魔法"].Refresh_Othersで他者への強化魔法の装備は参照され、自身への強化魔法は、sets.midcast["強化魔法"]やsets.midcast["強化魔法"].Refreshで参照さえるようになります。

サンプル(GearSwap-Jobs/RDM.lua at master · Kinematics/GearSwap-Jobs · GitHub)にも強化魔法のターゲットについての実装があったので、参考にします。
サンプルでは、Mote-libsでの装備選択(default_midcast)で強化魔法装備(sets.midcast['Enhancing Magic'])をGearSwapに登録しておき、job_post_midcastでターゲットによる強化魔法装備の差分を登録(上書き)しているようです。

-- function init_gear_sets()
sets.midcast['Enhancing Magic'] = {
    head="Atrophy Chapeau +1",neck="Colossus's Torque",
    body="Vitivation Tabard",hands="Atrophy Gloves +1",ring1="Prolix Ring",
    back="Estoqueur's Cape",waist="Olympus Sash",legs="Atrophy Tights",feet="Estoqueur's Houseaux +2"}

sets.midcast.EnhancingDuration = {hands="Atrophy Gloves +1",back="Estoqueur's Cape",feet="Estoqueur's Houseaux +2"}
        
sets.buff.ComposureOther = {head="Estoqueur's Chappel +2",
    body="Estoqueur's Sayon +2",hands="Estoqueur's Gantherots +2",
    legs="Estoqueur's Fuseau +2",feet="Estoqueur's Houseaux +2"}

-- Run after the default midcast() is done.
-- eventArgs is the same one used in job_midcast, in case information needs to be persisted.
function job_post_midcast(spell, action, spellMap, eventArgs)
    if spell.skill == 'Enfeebling Magic' and state.Buff.Saboteur then
        equip(sets.buff.Saboteur)
    elseif spell.skill == 'Enhancing Magic' then
        equip(sets.midcast.EnhancingDuration)
        if buffactive.composure and spell.target.type == 'PLAYER' then
            equip(sets.buff.ComposureOther)
        end
    elseif spellMap == 'Cure' and spell.target.type == 'SELF' then
        equip(sets.midcast.CureSelf)
    end
end

job_post_midcastはMote-libsの装備選択(defalut_midcast)の後に実行されるので、基本となる装備はMote-libsに選択させ、条件による装備(差分)で上書きする方法も良いですね。
job_post_midcastではすべての装備を上書きすることもできますが、それではMote-libsの装備選択が無駄になってしまうので一部装備を上書きする場合に採用するのが良さそうです。
(学者の'令狸執鼠の章'の場合に強化魔法延長の装備をMote-libsに選択させ、バフがあるときのみ両手装備をABブレーサー+1(エンピリアン装束)に上書きするなど)

ラストリゾート

暗黒騎士のラストリゾートやモンクのインピタスなどバフによってengagedの装備を変更したい場合があります。
state.CombatFormを使用してengagedの装備を切り替えをしてみたいと思います。

-- function job_setup()
state.Buff['ラストリゾート'] = buffactive['ラストリゾート'] or false

-- function init_gear_sets()
sets.engaged = {}
sets.engaged['ラストリゾート'] = {}

function job_aftercast(spell, action, spellMap, eventArgs)
    update_combat_form()
end

function job_buff_change(buff, gain)
    if buff == 'ラストリゾート' then
        update_combat_form()
        if not S{'precast', 'midcast'}:contains(_global.current_event) then -- precast, midcastの実行中は装備を変更しない
            handle_equipping_gear(player.status)
        end
    end
end

function update_combat_form()
    if state.Buff['ラストリゾート'] then
        state.CombatForm:set('ラストリゾート')
    else
        state.CombatForm:reset()
    end
end

state.CombatFormの値が'ラストリゾート'になると、sets.engaged['ラストリゾート']が選択されます。
job_buff_changeとjob_aftercastでラストリゾートのバフを確認し、モードの値を変更しています。

state.CombatFormは文字列タイプのモードなのでstate.OffenseModeのようなリストタイプのモードとは異なり、使用するモードの値は予め定義せず必要な時にset()を実行してモードの値を設定します。
reset()を実行すると、モードを定義したときのデフォルト値(state.CombatFormの場合は、空文字列 '' )になります。

-- Mote-Include.lua 
state.CombatForm = M{['description']='Combat Form', ['string']=''})

engagedの装備選択に複数の条件がある場合は、classes.CustomMeleeGroupsを使用して制御すると実現できると思います。
また、インピタスなどウェポンスキル時の装備がバフによって変化する場合は、get_custom_wsmodeでWSモードを変更して装備選択を制御すると良いと思います。

クイックドロー

ジョブアビリティの装備を制御する方法もMote-libsに用意されています。(ジョブアビリティの装備を制御したい場面は少ないかもしれません。)
ジョブアビリティの装備は、classes.JAModeで切り替えることができます。(前述したclasses.CustomClassを使用しても同様のことができます。また、JAModeとCustomClassは併用することもできます。)

あまり良い例がなく少し無理矢理な感じはありますが、クイックドローの装備をモードによって変化させてみたいと思います。
モードは、ダメージ重視の魔攻装備、CSブーツ+1(エンピリアン装束)の効果アップ装備、得TP重視のストアTP装備の3つにします。

-- function job_setup()
state.QDMode = M{['description']='QuickDraw Mode', 'Magic', 'En-QD', 'Stp'}

-- function init_gear_sets()
sets.precast.CorsairShot = {} -- 魔攻(Magic)
sets.precast.CorsairShot['En-QD'] = set_combine(sets.precast.CorsairShot, {feet="CSブーツ+1",}) --効果アップ(En-QD)
sets.precast.CorsairShot["Stp"] = {} -- ストアTP(Stp)

function job_precast(spell, action, spellMap, eventArgs)
    if spell.type == 'CorsairShot' then
        classes.JAMode = state.QDMode.value
    end
end

classes.JAModeもclasses.CustomClassと同様にアクション毎に初期化されます。

デバッグ

Mote-libsでは、GearSwapの_settings.debug_modeをフラグに選択された装備セット名を表示するデバッグモードがあります。

//gs debugmode

を実行すると_settings.debug_modeがtrueになりGearSwapを含めたデバッグモードが有効になります。
どの装備セットがMote-libsによって選択されたかが分かるため、デバッグするときに役に立ちます。

また、engagedの装備は以下のコマンドで任意のタイミングで着替えるここができます。

//gs c showtp