「暁月のフィナーレ」がリリースされてから新エリアは混雑回避のため複数インスタンスが用意されています。
同じマップでもインスタンス①~③までの3つのインスタンス(サーバー)が存在している状態で、ユーザーは任意のインスタンスを選ぶか、システムにお任せでその時最も空いているインスタンスへ移動させられるか、のいずれかになります。
そして、同じマップでインスタンスが3個あると言う事は、モブハンツアーで3倍のモブを狩れるという事になります。
ようやく復活してきたモブハンツアーでは、暁月で追加されたエリアマップ6個x3インスタンスを周るのが最も効率が良いツアーとなっています。
1マップにつき2体のモブが湧きますので、フルで周ると36体ものモブを狩ることができます。
モブは一瞬で溶けるがインスタンス移動が長蛇の列
インスタンスがエリアマップ毎に1個しか無い場合、モブハンツアーと言えばエリアマップ6個xモブ2体の合計12体のモブを狩っていました。
「暁月のフィナーレ」がリリースされる直前、漆黒エリアのAモブを狩るツアーがまさにそうですね。
この状態でもテレポでエリアマップを移動しようとすると、移動先のマップが「封鎖」されていてテレポできない、という事がかなり高確率で発生していました。
モブハンツアーに参加しているせいぜい200人程度のユーザーが一斉に移動すると、移動先サーバーに受け入れられた1部のユーザー以外は「移動先が混雑しています。しばらく待ってからリトライして下さい」と弾かれます。
現在、暁月エリアはインスタンス制になっていてエリアマップ毎に3つのインスタンスが存在していますが、モブハンツアー参加者がインスタンスを一斉に移動しようとすると、やはり1部のユーザー以外はサーバーに弾かれて「封鎖が解けるまで」何度もリトライする羽目になります。
この、次のエリアマップにツアー参加者全員が移動するまでの時間が圧倒的に長いです。
たかだか200人程度のユーザーが移動するのに3~5分かかっているような状態ですね。
インスタンス移動をLogicoolのマクロで自動化しよう
サーバースペックだかサーバーコードだかがしょぼいのはユーザー側ではどうしようも無いんですが、インスタンス移動で弾かれると成功するまで何度もリトライしなければいけないのが非常に疲れます。
Logicoolのマウスやキーボードを購入すると、これらのデバイス制御のためにインストールするロジクールゲーミングソフトウェアのスクリプト機能で自動化できますというのが今回の記事です。
私はこのインスタンス移動メニュー連打にうんざりしてスクリプトを組んだのですが、結果としてインスタンス移動が非常に楽になりました。
自動インスタンス移動スクリプトを使うとどうなるか
どんな感じかというと、エリアマップに湧いている2体目のモブを倒すと、パーティの誰かが速攻でエーテライトにテレポし、他のPTメンは基本それに便乗するかと思います。
あるいはモブを狩る前にわざと同じエーテライトにテレポして「テレポの勧誘」を保留しておき、インスタンス移動の際には速攻で保留しておいた「テレポ勧誘」を承諾するという、1秒でも早くテレポしてインスタンス移動のキューに乗ろうという何とも世知辛い技を使ったりしますね。
とにかく、チャットで示されたエーテライトにテレポした後、移動先の3つのインスタンスに対応したマウスボタン(Gボタン)を押してスクリプトを起動します。
後はスクリプトによって勝手にマウスカーソルが動き、エーテライトをクリックして「インスタンス移動」メニューを開きます。
その後も自動で「移動先のインスタンス番号」にカーソルが移動し、クリックします。
「移動先が混雑しています」と弾かれても、スクリプトが延々と同じ動作を繰り返すので、移動に成功するまで後は放置です。
その間他に好きな事ができるし、何よりこの面倒くさい単純作業を手で行うという苦行から解放されます。
必要な物
ロジクールのゲーミングマウスやキーボードと、ロジクールゲーミングソフトウェア。
以上です。
デバイスに関してはGボタンが付いている物なら何でも使えます。
例えばG300とかでも大丈夫です。
ただ、ロジクールのマウスを購入したけれどロジクールゲーミングソフトウェアはインストールしていない、という方もいるかと思います。
その場合はロジクールゲーミングソフトウェアを公式サイトからダウンロードしてインストールしておいて下さい。
今回はMMO向け多ボタンマウスのG600での実装例を紹介します。
スクリプトを設定する
ロジクールゲーミングソフトウェアを起動します。
起動したら、スクリプトを起動するためのデバイスを選択します。
①でG600を選び、②でサイドボタンをクリックします。
キーアサイン画面に移行しますので、プロファイルのFF14アイコンの下矢印をクリックします。
ドロップダウンメニューから「スクリプト」を選択します。
こんな感じのスクリプトエディタが起動します。
上のスクショでは既にスクリプトが入力済ですが、初めて起動した場合は3行程度のサンプル用スクリプトが記述されている状態かと思います。
最初から記述されているサンプルスクリプトはCtrl + Aで全選択して削除し、替わりに以下のテキストをコピペします。
SCREEN_WIDTH = 3840 SCREEN_HEIGHT = 1600 AETHRIGHT_X = 1920 AETHRIGHT_Y = 400 INS1_BTN = 10 INS2_BTN = 13 INS3_BTN = 16 INS_X = 1960 INS_Y = 833 INS1_Y = 820 INS2_Y = 840 INS3_Y = 865 WAIT_MENU_MSEC = 500 WAIT_MOUSECLICK_MSEC = 200 function OnEvent(event, arg) if( arg ~= INS1_BTN and arg ~= INS2_BTN and arg ~= INS3_BTN ) then return end if( event == "MOUSE_BUTTON_PRESSED" and IsModifierPressed( "alt" ) ) then while not IsModifierPressed( "ctrl" ) do PressKey("x") MoveMouseTo( 65535 * AETHRIGHT_X/SCREEN_WIDTH, 65535 * AETHRIGHT_Y/SCREEN_HEIGHT ) Sleep( WAIT_MOUSECLICK_MSEC ) PressMouseButton( 3 ) Sleep( WAIT_MOUSECLICK_MSEC ) ReleaseMouseButton( 3 ) Sleep( WAIT_MENU_MSEC ) -- インスタンス移動 MoveMouseTo( 65535 * INS_X/SCREEN_WIDTH, 65535 * INS_Y/SCREEN_HEIGHT ) Sleep( WAIT_MOUSECLICK_MSEC ) PressMouseButton( 1 ) Sleep( WAIT_MOUSECLICK_MSEC ) ReleaseMouseButton( 1 ) Sleep( WAIT_MENU_MSEC ) -- インスタンス選択 local ins_y = INS1_Y if(arg == INS2_BTN) then ins_y = INS2_Y elseif(arg == INS3_BTN) then ins_y = INS3_Y end MoveMouseTo( 65535 * INS_X/SCREEN_WIDTH, 65535 * ins_y/SCREEN_HEIGHT ) Sleep( WAIT_MOUSECLICK_MSEC ) PressMouseButton( 1 ) Sleep( WAIT_MOUSECLICK_MSEC ) ReleaseMouseButton( 1 ) ReleaseKey("x") Sleep( WAIT_MOUSECLICK_MSEC ) end end end
ひとまずこの状態で保存します。
スクリプト>保存を選んで下さい。
このエディタは保存する際にスクリプトをコンパイルしてエラーが無いかどうかをチェックしてくれます。
画面下部にScript Loaded(FF14)というログが出力されたら、そのスクリプトにはエラーが無いという事になります。
ここに別の文言が表示された場合はコンパイルエラーという事なので、コピペの際に何らかのミスが発生しています。
クリック座標を自身の環境に合わせて修正する
上のスクリプトは私のPC環境でのマウスクリック座標が書かれています。
なので、私のPC環境と全く同じ人はそのまま使えますが、そうでない場合はご自身の環境に合わせて座標を修正する必要があります。
私のPC環境とは具体的には、
- モニターの解像度が3840×1600
- フルスクリーンでFF14をプレイしている
- 結果として、FF14のクライアントの解像度は3840×1600である
以上です。
これと同じ条件の場合、上のスクリプトは修正無しでそのまま使えます。
つまり、FF14のクライアントの解像度と、デスクトップ上の位置が重要という事になります。
スクリプトの修正が必要な部分について説明します。
赤枠で囲った①~⑤の部分の数値を、お使いのPC環境に合わせて修正する必要があります。
①モニターの解像度
SCREEN_WIDTH = 3840 SCREEN_HEIGHT = 1600
この解像度の中でマウスカーソルが動くので、お使いのモニターの解像度をここに記述して下さい。
これはFF14のクライアントの解像度では無く、あくまでマウスが動く範囲としてのモニターの解像度である点に注意して下さい。
私の場合は3840×1600のゲーミングモニターを使っていますので、SCREEN_WIDTHに3840、SCREEN_HEIGHTに1600と書いています。
②エーテライトをクリックするための座標
AETHRIGHT_X = 1920 AETHRIGHT_Y = 400
テレポ後何をするかというと、まずエーテライトに近づいてエーテライトを右クリックしますね。
この際にクリックする座標値をここに記述します。
テレポ後、大体このような位置関係でフェードが明けます。
テレポ直後のエーテライトは、キャラやカメラを操作しない限りFF14のクライアントの中で水平方向おおよそ中心に位置しています。
もちろんこの位置からエーテライトをクリックしても「距離が遠すぎます」と冷たく拒否られるので、エーテライトが画面中心からなるべく離れないように直進して近づきます。
おおよそ、このような位置関係でスクリプトを起動する事になります。
つまり、エーテライトをクリックするための座標は、水平方向=クライアントの横サイズx0.5、垂直方向=クライアントの縦サイズ上半分ぐらい、という事になります。
③どのマウスボタンを押すと、どのインスタンスへ移動するか
INS1_BTN = 10 INS2_BTN = 13 INS3_BTN = 16
これは何かというと、マウスのGボタンの何番を押すとインスタンス①に移動し、何番を押すとインスタンス②に移動するかというアサインを書いています。
私の場合、赤丸で囲ったボタンを押す事でインスタンス移動しています。
つまり、
G10 = インスタンス1
G13 = インスタンス2
G16 = インスタンス3
というアサインですね。
なのでINS1_BTN = 10、INS2_BTN = 13、INS3_BTN = 16という記述になります。
Gモードについて
ロジクールのマウスにはGモードという仕様があり、3つのモードを切り替える事でGボタンの数が実質3倍になるという仕組みになっています。
上のSSではLEDが白色なので、Gモード的にはモード3の状態です。
ですが、ふざけた事に、ロジクールのスクリプトは現在ではマウスのGモードを判別する事ができなくなっています。
なので、Gモードは気にする必要がありません、というか、気にする事ができません。
ボタンアサインの注意
このGボタンはお好きなボタンの番号を書いてもらえば良い、と言いたいところですが、一つ注意点があります。
それは「インスタンス移動時にそのGボタンを押す事になるので、非戦闘時に有効なアクションをアサインしているとそれが発動する」という点です。
私はG600のサイドボタンの各モードを以下のようにアサインしています。
先に述べたように、Logicoolのスクリプトは現在、Gモードを判別する事ができません。
なので、G10~G13のボタンを押すと、現在どのGモードであろうと、インスタンス移動のスクリプトが起動してしまいます。
これでは戦闘中にWSを撃つたびにスクリプトが起動し、マウスカーソルが勝手に動いてクリックをしてしまう、というどエライ事になってしまいます。
これを回避するために「Altキーを押しながらGボタンを押した場合のみ、インスタンス移動を行う」ようにスクリプトを書いています。
これで、普段はGボタンをホットバーにアサインしたアクション実行用に使いつつ、Altキーと同時に押した時だけインスタンス移動操作を自動入力するようにする事が可能です。
ですが、Altキーを押しながらとはいえ実際にGボタンを押すので、そこにアサインされたアクションが起動してしまいます。
戦闘中にしか実行できないWS等がアサインされている場合は何も問題ありませんが、私の場合モード3にはテレポやマウント起動をアサインしています。
このような「非戦闘中でも起動するアクション」がアサインされているボタンに、インスタンス移動のスクリプト起動をアサインするのは避けた方が無難です。
私の場合は、マウスのGモードを1か2にした状態でGボタンを押せば問題ないのですが、Gモードを意識するのも面倒ですし、万一切り替え忘れたままGボタンを押し、メニューとか起動してしまうと面倒です。
なのでモード3のG10,G13,G16には何もアサインしていません。
まぁモブハンツアーの場合、基本的に次のモブ座標をチャット上でクリックしてマップから直接エーテライトへ飛ぶので、Gモードを「戦闘中以外」に切り替えるという事がそもそもありません。
なので問題になる事はまず無いはずです。
どのモードにも「非戦闘中でも起動するアクション」がアサインされていないという方は何も気にする必要はありませんが、そうでない場合は、一応この点に留意しておいて下さい。
④インスタンス移動メニューのクリック座標
INS_X = 1960 INS_Y = 833
ここには、エーテライトを右クリック後に表示されるメニューの「インスタンスエリアへ移動」をクリックするマウス座標を記述します。
このメニューは、FF14のクライアントの中心にメニューウィンドウの中心が来るように毎回表示され、位置も固定です。
なのでスクショを取ってペイントで開き、カーソル位置を調べる事で簡単に座標を求める事ができます。
⑤各インスタンスを選ぶY座標
INS1_Y = 820 INS2_Y = 840 INS3_Y = 865
インスタンス1~3をクリックするためのY座標のみを調べて記述します。
X座標は「インスタンスエリアへ移動」と同じなので、Y座標だけで構いません。
このメニューもFF14クライアントの中心に表示されますので、座標の調べ方は「インスタンスエリアへ移動」と同じです。
自分の環境に合わせた座標でスクリプトを修正する
ご自身の環境の①~⑤の値が決まったら、再度スクリプトエディタを開き、各数値を修正して保存します。
保存した際に画面下部にScript Loaded(FF14)というログが出力されるのを確認して下さい。
自動インスタンス移動スクリプトの使い方
ここまでで、キーボードのAltキーとアサインしたGボタンを同時に押すとスクリプトが起動し、エーテライトを右クリックして目的のインスタンスを選ぶ動作を自動で繰り返すようになります。
ここではこのスクリプトの具体的な使い方を説明します。
スクリプトの起動
エーテライトへテレポ後、エーテライトを画面中心に捉えたまま真っすぐ近づきます。
メニューが開けるぐらいの距離まで近づいたら、キーボードのAltと、移動したいインスタンスに応じたGボタンを同時に押します。
するとスクリプトが起動し、マウスカーソルが勝手に指定した座標へ動き、クリック動作も行いますので、それ以降はマウスもキーボードも触らず放置します。
スクリプトの停止
このスクリプトは同じ動作を永久に繰り返しますので、インスタンス移動に成功した後は、なるべくすぐに停止しなければいけません。
インスタンス移動後に多少放置していても、幸い移動後の座標系が微妙に変わっているため、再度同じインスタンスへ移動するという事はありません。
ですが、マウスカーソルが勝手に動いて自キャラをクリックしたりしますので、インスタンス移動に成功した後は可能な限り早くスクリプトを停止した方が良いでしょう。
スクリプトを停止するにはキーボードのCtrlをしばらく押し続けます。
インスタンス移動に成功して画面が暗転する音が聞こえたらCtrlを押しっぱなしにする感じです。
これで暗転明けごろにはスクリプトが停止しています。
スクリプトを停止するのにCtrlを押し続けなければいけない理由ですが、このスクリプトの動作は無限ループで繰り返されています。
このため、このループを抜ける判定が一連のマウス移動、クリック操作の周回毎に行われています。
なので、エーテライト右クリック>「インスタンスエリア移動」左クリック>「インスタンス番号」左クリックを行った後に「Ctrlキーが押されていたらこのループを抜ける」という処理になっています。
このタイミングでCtrlキーが押されていないとまた一連の動作が始まるので、Ctrlキーはある程度の長さ押し続ける必要があるという訳です。
スクリプトの解説とカスタマイズ方法
ここでは、少し詳しくスクリプトコードについて説明します。
(a)altキーを押しながらGボタンを押した時だけインスタンス移動
if( event == "MOUSE_BUTTON_PRESSED" and IsModifierPressed( "alt" ) ) then
and IsModifierPressed( “alt” )
の部分がAltキーを押しているか?の判定部分です。
Altキー以外では、shift(左右どちらかのシフト)、 ctrl(左右どちらかのコントロール)が指定できます。
また、lctrl(左コントロールキー)、rctrl(右コントロールキー)と言った左右限定の指定もできますので、Altキーは嫌だ、という方はここを変えて下さい。
この部分を丸ごと削除すると、Gボタンを押しただけでスクリプトが起動します。
Gボタンは普段は全く使わない、という方はこの判定部分を削除すればより簡単にインスタンス移動が行えます。
ロジクールのマウスを持っているがGボタンは普段使ってないので、ボタンを押すだけでインスタンス移動して欲しい、という人はこの判定部分を削除した方が良いでしょう。
(b)スクリプト中断キーの指定
while not IsModifierPressed( "ctrl" ) do
IsModifierPressed( “ctrl” )
の部分が「コントロールキーが押されているか?」の判定部分です。
コントロールキー以外に変えたければ、ここを修正して下さい。
コントロールキー以外では、shift(左右どちらかのシフト)、 alt(左右どちらかのAlt)が指定できます。
また、lshift(左シフト)、rshift(右シフト)と言った左右限定の指定もできますので、コントロールキーは嫌だ、という方はここを変えて下さい。
⑥マウスクリックの間隔調整
WAIT_MENU_MSEC = 500
これは何かというとマウスクリックの間隔をミリ秒で記述した値です。
500ミリ秒という事なので、0.5秒間隔でマウスをクリックしています。
この間隔が何故必要かというと、メニューウィンドウが開くよりも前にクリックしてしまうと、選択肢が選ばれず何の意味も無いからです。
0.5秒というのは60fpsでゲームが動いている場合32フレーム弱の長さなので、流石にメニューは開ききっているかと思いますが、もしメニューが開く前にマウスクリックが行われているようでしたら、ここの値を増やして調整して下さい。
エーテライトに近づくのも自動化できないの?
できるかできないか、で言うとできます。
デフォルトだとPC版のFF14はキーボードの”W”を押すとキャラの向いている方向へ前進しますので、一連のマウス動作の前に1秒未満ぐらいスクリプトでWキーを押しっぱなしにすれば「エーテライトに近づいてから右クリックする」という挙動になります。
PressKey, ReleaseKeyというAPIがLogicoolスクリプトには存在しており、Sleepと組み合わせる事で簡単に任意の時間キャラを移動させる事ができます。
実際試してみたのですが、事故った時に余計面倒な事になるので私は手動でエーテライトに近づいています。
事故るとは何かというと、エーテライトって地形なのでコリジョンがあります。
また、テレポ後のエーテライトと自キャラの距離は、エーテライトによって異なってたりします。
なのでテレポ先によっては、スクリプトで自動でキャラを近づけさせると地形に引っかかったり、後ろへ回り込んだりしてしまう事があるんですね。
移動して地形コリジョンにぶつかると、下手をすると画面内のエーテライトの位置が大幅にずれてしまいます。
そうなるとマウスクリック座標が有効範囲内から外れてしまったりするので、余計に面倒な事になるというわけです。
なので、できなくはないけどおススメはあまりしません。
より高みを目指す方はLogicoolスクリプトのAPIを調べて試行錯誤されてみるのも面白いかと思います。
なんでGモードの判別ができないの?
先に書いた「現在のLogicoolスクリプトではマウスのGモードを判別できない」件について補足しておきます。
Logicoolのスクリプトには、GetMKeyStateというAPIが存在します。
これはデバイスの現在のM Keyの状態を取得するAPIなんですが、
GetMKeyState( “kb” ) | キーボード |
GetMKeyState( “lhc” ) | Left Hand Controller(左手デバイス) |
GetMKeyState( “mouse” ) | マウス |
という風に、引数にデバイスファミリー名を指定するという仕様です。
実際、昔はGetMKeyState( “mouse” )でG600やG300のGモードの状態を取得できていました。
ところが実はG-series Lua APIというマニュアルを読むと、この“mouse”と言う指定は記載されていません。
つまり、公式にはサポートされていないというわけですね。
で、以下のようなデバッグ用のスクリプトを書いてみます。
function OnEvent(event, arg) if(event == "MOUSE_BUTTON_PRESSED") then local mks = GetMKeyState("mouse") OutputLogMessage( "MKS = %d\n", mks ) end end
このスクリプトをセットした上でマウスのGボタンを押すと、どのGモードだろうと
MKS = 1
という結果が表示されてしまいました。
つまり現在のLogicoolスクリプトではマウスデバイスのGモードを判別する事ができなくなっている、という事です。
ググると海外のフォーラムでもこの件については話題になっていましたが「そもそも”mouse”はマニュアルに記載されてないよね?」という事でレスも途絶えています。
つまり解決策無しです。
まぁね、確かにマニュアルはこうなってるんですよ。
API名の通り、M Keysの状態を返すAPIです。
生産終了した左手コントローラーのG13にはM1, M2, M3というボタンがあります。
でもマウスにはGモードはあってもMボタンはありません。
だからむしろ、GetMKeyStateで状態を取れるはずが無いと言えます。マニュアルにも記載されてませんし。
しかしそういう事じゃあないんですね、なら代替手段を用意しろやって話です。
以前はできていた事ができなくなっているのは何とも腹立たしい限りですし、とっくに生産終了したG13しか存在しない”lhc(左手コントローラー)”用のAPIは動作するのに、次から次へと発売しまくってる情弱騙しのボッタくり価格「ゲェェェェェェミィィィィィィングマーーーウス」でGモードを判別できないとか、いかにも拝金企業ロジクールらしい塩対応ですねぇ。