GearSwapで着替えの順番を指定する[FF11]

f:id:yyoshisaur:20190415021029p:plain
HPの多い盾ジョブや消費したMPでダメージが変化するデスを使用する黒魔道士では、
着替えによるHPやMPの減少を気にします。
標準のマクロでは、効果アップなどの装備セットに着替える前に
"/equip"コマンドでHP, MPが増えるアクセサリーを装備して最大HP, MPを増やし、着替えによる減少を緩和します。
標準の装備セットでの防具の着替え順番が頭、胴装備などの主要5部位→アクセサリーとなっているため、減少を緩和するためにはアクセサリーで最大値を増やしておく必要があります。

今回は、GearSwapで装備セットの着替え順番を制御する方法を紹介してみます。
(着替え順番を制御する方法はGearSwapに付属しているbeata_examples_and_informagion/Advanced sets tables.txtのPrioritizing gear changesに記述されています。)

priority

GearSwapでは装備セットの各装備にpriority(優先度)というメンバーを追加することで着替えの順番を制御することができます。

標準の装備セットと同様にGearSwapでも特に指定がない場合は、res/slots.luaに定義されている"id=0"の部位から順番に着替えが行われます。

-- res/slots.lua
return {
    [0] = {id=0,en="Main"},
    [1] = {id=1,en="Sub"},
    [2] = {id=2,en="Range"},
    [3] = {id=3,en="Ammo"},
    [4] = {id=4,en="Head"},
    [5] = {id=5,en="Body"},
    [6] = {id=6,en="Hands"},
    [7] = {id=7,en="Legs"},
    [8] = {id=8,en="Feet"},
    [9] = {id=9,en="Neck"},
    [10] = {id=10,en="Waist"},
    [11] = {id=11,en="Left Ear"},
    [12] = {id=12,en="Right Ear"},
    [13] = {id=13,en="Left Ring"},
    [14] = {id=14,en="Right Ring"},
    [15] = {id=15,en="Back"},
}, {"id", "en"}
priorityの決まり事
  • 正, 負の値を設定できる
  • 値の大きい部位が優先される
  • 何も設定していない場合は"priority=0"となる
  • 同じ値の部位がある場合は、res/slots.luaに定義されている順番となる

例として魔導剣士で試してみます。
ここでは簡略化して、魔法を使ったときに待機装備(被ダメージ-装備)からファストキャスト装備に着替える場合を考えます。

id 待機装備 HP+ FC装備 HP+ ΔHP
0 エピオラトリー 0
1 メンシストラップ+1 0
3 ストンチタスラム+1 0
4 トゥルムキャップ+1 94 RNバンド+3 109 15
5 FUコート+3 119
6 トゥルムミトン+1 74 レイライングローブ 25 -49
7 ERレグガード+1 80
8 トゥルムレギンス+1 76
9 フサルクトルク+2 60
10 エングレイブベルト 0
11 クリプティックピアス 40
12 オノワイヤリング+1 110
13 守りの指輪 0
14 VC+1 0
15 オーグマケープ 60 月光の羽衣 275 215

上記の場合で待機装備からファストキャスト装備に着替えを行なった場合、
最大HPは15+(-49)+215=181増加しますが、両手装備を着替えた時に15+(-49)=-34となり減少します。
HPが全快で着替えを行った場合、完了時にHPが34減った状態になります。

この場合、両手装備より先に背装備を着替えることで解決できます。
GearSwapの装備セットでpriorityを設定して記述します。

sets.precast.fc = {
    head="RNバンド+3",
    hands={ name="レイライングローブ", augments={'Accuracy+15','Mag. Acc.+15','"Mag.Atk.Bns."+15','"Fast Cast"+3',}},
    back={name="月光の羽衣", priority=1}
}

sets.aftercast.idle = {
    main="エピオラトリー",
    sub="メンシストラップ+1",
    ammo="ストンチタスラム+1",
    head="トゥルムキャップ+1",
    body={ name="FUコート+3", augments={'Enhances "Elemental Sforzo" effect',}},
    hands="トゥルムミトン+1",
    legs="ERレグガード+1",
    feet="トゥルムレギンス+1",
    neck="フサルクトルク+2",
    waist="エングレイブベルト",
    left_ear="クリプティクピアス",
    right_ear="オノワイヤリング+1",
    left_ring="守りの指輪",
    right_ring="VCリング+1",
    back={ name="オーグマケープ", augments={'HP+60','Eva.+20 /Mag. Eva.+20','Mag. Evasion+10','Enmity+10','Damage taken-5%',}},
}

priorityの設定がない部位は"priority=0"となるので、背装備(back)に"priority=1"を設定することで、
月光の羽衣が頭装備(head)、両手装備(hands)より先に着替えが実行され、HPの減少を防ぐことができます。
(この例では減少量が少ないのであまり実感できませんが、ファランクス効果アップ装備などで減少量が多い場合に有効かと思います)

動的にpriorityを設定する

前述の例ではpriorityを決め打ちで設定しました。
しかし、実際にはHPが減少しないようにすべての装備セットにpriorityを設定するのは大変です。
現在の装備と次に使用する装備からpriorityを設定できるようにしてみます。
(GearSwapに付属しているbeata_examples_and_informagionのユーザースクリプトのサンプルを参考にしています。)
前述の例からΔHP(次装備のHP-現装備のHP)が大きい部位から順番に着替えを行えば、HPの減少は緩和されます。
priorityは負の値も設定可能なので、ΔHPをそのままpriorityとして用いればうまくいきそうです。
装備セットに各部位のHPの値をプロパティとして追加し、priorityを動的に設定する処理を実装します。

function get_sets()
    sets.precast.fc = {
        head={ name="RNバンド+3", hp=109},
        hands={ name="レイライングローブ", augments={'Accuracy+15','Mag. Acc.+15','"Mag.Atk.Bns."+15','"Fast Cast"+3',}, hp=25},
        back={ name="月光の羽衣", hp=275}, 
    }

    sets.aftercast.idle = {
        main="エピオラトリー",
        sub="メンシストラップ+1",
        ammo="ストンチタスラム+1",
        head={ name="トゥルムキャップ+1", hp=94},
        body={ name="FUコート+3", augments={'Enhances "Elemental Sforzo" effect',}, hp=119},
        hands={ name="トゥルムミトン+1", hp=74},
        legs={ name="ERレグガード+1", hp=80},
        feet={ name="トゥルムレギンス+1", hp=76},
        neck={ name="フサルクトルク+2", hp=60},
        waist="エングレイブベルト",
        left_ear={ name="クリプティクピアス", hp=40},
        right_ear={ name="オノワイヤリング+1", hp=110},
        left_ring="守りの指輪",
        right_ring="VCリング+1",
        back={ name="オーグマケープ", augments={'HP+60','Eva.+20 /Mag. Eva.+20','Mag. Evasion+10','Enmity+10','Damage taken-5%',}, hp=60},
    }
end

function precast(spell)
    equip(sets.precast.fc)    -- なにかのアクション開始で装備セットを登録
    set_priorities_by_hp()     -- priorityを更新
end

function aftercast(spell)
    equip(sets.aftercast.idle)    -- なにかのアクション終了で装備セットを登録
    set_priorities_by_hp()     -- priorityを更新
end

-- 現装備のHPと次装備のHPからpriorityを設定する
function set_priorities_by_hp()
    local future,current = gearswap.equip_list,gearswap.equip_list_history
    function get_hp(piece)
        if piece and type(piece)=='table' and piece.hp and type(piece.hp)=='number' then
            return piece.hp
        end
        return 0
    end
    
    for i,v in pairs(future) do
        local priority = get_hp(future[i]) - get_hp(current[i])
        if type(v) == 'table' then
            future[i].priority = priority
        else
            future[i] = {name=v,priority=priority}
        end
    end
end

装備セットの各部位に手動でhpを追加する必要がありますが、
着替えの順番はアクションの実行時に自動で設定されるようになりました。
(装備名から自動で装備のHP+のプロパティを取得できれば良いのですが。。まだ改善の余地がありますね。)