サムネ画像
どうも。あずきです。
ポケモンの自動化のためにArduinoを購入しましたが、ポケモン以外にも使えるよな?と思い、大好きなMHXXの自動化に手を出し始めました。
今回はそんなお話です。
世間ではMHWが熱いようですが、僕は古きを愛するハンターなので、未だにMHXXを楽しんでいます。正直MHWより面白い
MHXXではスキルとスロットだけついている装備『護石』が特に重要です。護石がなくても装備は組めますが、強い護石があると装備の幅が一気に広がります。
強い護石を手に入れるために、ハンターの皆さんは日々火山を駆け巡ったり、カマキリを絶滅させたり、粘菌野郎をシバき倒したりしていると思いますが、モンハンには太古から伝わる伝統的な方法があります。
それが『ケルビの角の納品』、いわゆるケルビマラソンです。
ケルビマラソンの詳しい歴史についてはwikiでも見てもらえればと思いますが、ざっくり言えばケルビの角を爆速納品してクエストをいっぱい回したる!wwwというのがケルビマラソンです。簡単ですね。
MHXXでは『マカ錬金』という機能を使って、要らない護石から別の護石を生み出すことができます。そのマカ錬金がクエストクリア時に処理が進むので、ケルビマラソンでさっさと回そう!ということです。わかりやすい説明ですね(自画自賛)
で、このケルビマラソンがマクロで自動化組んだら楽じゃね?と気付いたので、Arduinoで自動化を組んだよ、というのが本筋になります。前置きが長くて申し訳ない
ちなみにケルビマラソンの詳しいやり方や、Arduinoの事前準備は、読者が全員知ってる前提で話を進めますのでご了承ください。
はじめに
・一度にケルビの角を30個消費します。仕入れておいてください。
・ケルビマラソン中にHRが上がらないことを前提に組んでいます。マラソン中にHRが上がりそうなら、実行前に調整してください。
・DL版を本体保存したMHXXで検証しています。パッケージ版やSD保存の場合は、実行コードのロード時間(delay)を調整してください。
・コントローラーの+と-の挙動を入れ替えています(特殊モーションを+で出すため)。設定で入れ替えておいてください。
実行コード
今回はボタンの同時押しに対応できる『Switch Controll Library』のv2系を利用しました。
もっとスマートなコードを書けるようになりたいですね(願望)
#include <SwitchControlLibrary.h> // Aを0.1秒押して離す短縮コマンド void PushA(){ SwitchControlLibrary().pressButton(Button::A); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::A); SwitchControlLibrary().sendReport(); delay(100); } // Bを0.1秒押して離す短縮コマンド void PushB(){ SwitchControlLibrary().pressButton(Button::B); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::B); SwitchControlLibrary().sendReport(); delay(100); } // Xを0.1秒押して離す短縮コマンド void PushX(){ SwitchControlLibrary().pressButton(Button::X); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::X); SwitchControlLibrary().sendReport(); delay(100); } // マイナスを0.1秒押して離す短縮コマンド void PushMINUS(){ SwitchControlLibrary().pressButton(Button::MINUS); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::MINUS); SwitchControlLibrary().sendReport(); delay(100); } // 上を0.1秒押して離す短縮コマンド void PushUP(){ SwitchControlLibrary().pressHatButton(HatButton::UP); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseHatButton(HatButton::UP); SwitchControlLibrary().sendReport(); delay(100); } // 下を0.1秒押して離す短縮コマンド void PushDOWN(){ SwitchControlLibrary().pressHatButton(HatButton::DOWN); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseHatButton(HatButton::DOWN); SwitchControlLibrary().sendReport(); delay(100); } // 右を0.1秒押して離す短縮コマンド void PushRIGHT(){ SwitchControlLibrary().pressHatButton(HatButton::RIGHT); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseHatButton(HatButton::RIGHT); SwitchControlLibrary().sendReport(); delay(100); } // 左を0.1秒押して離す短縮コマンド void PushLEFT(){ SwitchControlLibrary().pressHatButton(HatButton::LEFT); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseHatButton(HatButton::LEFT); SwitchControlLibrary().sendReport(); delay(100); } // ↓無線コントローラーから切替える場合のセットアップ↓ // HOME→コントローラー→持ちかた/順番を変える の画面から実行 // HOMEを0.1秒押して離す短縮コマンド void PushHOME(){ SwitchControlLibrary().pressButton(Button::HOME); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::HOME); SwitchControlLibrary().sendReport(); delay(100); } void WirelessControllerSetup(){ // for内を5回繰り返す for(int i=0; i<5; i++){ // LRを0.1秒押して離す SwitchControlLibrary().pressButton(Button::L); SwitchControlLibrary().pressButton(Button::R); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::L); SwitchControlLibrary().releaseButton(Button::R); SwitchControlLibrary().sendReport(); // 0.5秒待機 delay(500); } // 1秒待機してAを0.1秒押して離す delay(500); PushA(); // 1秒待機してHOMEを0.1秒押して離す delay(900); PushHOME(); // 1秒待機してHOMEを0.1秒押して離す delay(900); PushHOME(); // 4秒待機 delay(2900); } // ↑ここまで無線コントローラーから切替える場合のセットアップ↑ // ↓有線コントローラーから切替える場合のセットアップ↓ // 有線コントローラーの本体接続を解除してから実行 void ControllerSetup(){ // for内を5回繰り返す for(int i=0; i<5; i++){ // Lを0.1秒押して離す SwitchControlLibrary().pressButton(Button::L); SwitchControlLibrary().sendReport(); delay(100); SwitchControlLibrary().releaseButton(Button::L); SwitchControlLibrary().sendReport(); // 0.5秒待機 delay(500); } // 2秒待機 delay(1500); } // 初期セットアップ void Setup(){ PushX(); PushUP(); PushA(); PushA(); delay(6900); PushX(); PushDOWN(); PushA(); PushA(); delay(6900); } // 初期位置から受付嬢まで移動する void GotoCounter(){ // Rを押しながら受付嬢まで移動 SwitchControlLibrary().pressButton(Button::R); SwitchControlLibrary().moveLeftStick(128, 0); SwitchControlLibrary().sendReport(); delay(3000); SwitchControlLibrary().releaseButton(Button::R); SwitchControlLibrary().moveLeftStick(128, 128); SwitchControlLibrary().sendReport(); } // クエストを受注する void Quest(){ // 受付嬢に話しかける PushA(); delay(900); PushB(); delay(700); PushA(); delay(400); // 下位選択 PushUP(); PushA(); // 星1選択 PushDOWN(); PushA(); // ケルビ選択 PushDOWN(); PushDOWN(); PushDOWN(); PushA(); delay(200); PushA(); delay(1400); PushA(); } // クエストに出撃する void GotoQuest(){ SwitchControlLibrary().pressButton(Button::R); SwitchControlLibrary().moveLeftStick(170, 0); SwitchControlLibrary().sendReport(); delay(1000); SwitchControlLibrary().moveLeftStick(64, 0); SwitchControlLibrary().sendReport(); delay(3000); PushA(); SwitchControlLibrary().releaseButton(Button::R); SwitchControlLibrary().moveLeftStick(128, 128); SwitchControlLibrary().sendReport(); } // 角を納品する void Horn(){ PushMINUS(); PushA(); PushA(); PushUP(); PushUP(); PushA(); PushRIGHT(); PushA(); PushA(); } // 報酬画面処理 void Result(){ PushUP(); PushA(); PushLEFT(); PushA(); delay(400); // 精算画面 PushA(); delay(400); PushA(); delay(400); PushA(); delay(400); PushA(); delay(400); // セーブキャンセル PushB(); delay(400); PushB(); } // 自宅に移動 void GotoHouse(){ PushX(); PushA(); PushA(); } void setup() { // 有線コントローラーからArduinoに切替える // 無線コントローラーの場合は関数の『 /* */ 』を消す /*Wireless*/ControllerSetup(); Setup(); } void loop() { // for内を10回繰り返す for(int i=0; i<10; i++){ GotoCounter(); Quest(); GotoQuest(); // クエストロード画面 delay(12000); Horn(); // クリア後20秒 delay(20000); // 報酬画面までのロード delay(18000); Result(); // 村までのロード画面 delay(10000); } GotoHouse(); exit(0); }
動作解説
1.事前準備
ベルナ村を拠点として実行します。起点はベルナ村の自宅です。
ポーチの一番最初にケルビの角を30個以上入れ、マカ錬金の予約をすべて終えスロットが空になった状態で、自宅のベッドでセーブします。
2.セットアップ
マカ錬金に10回分の予約を入れるところまで手動で行い、ArduinoをSwitchに接続します。
上記コードをコピペした場合は、有線コントローラーをSwitchから接続解除して、ArduinoをSwitchに接続してください。
無線コントローラーからArduinoに切り替える場合は、
void setup(){ /*Wireless*/ControllerSetup(); Setup(); }
を、
void setup(){ WirelessControllerSetup(); Setup(); }
に書き換えて実行してください。無線コントローラーの場合、『Switchのホーム画面→コントローラー→持ちかた/順番を変える』を選択し、ArduinoをSwitchに接続してください。
開始位置を固定するため、『ベルナ村の自宅→ココット村→ベルナ村』の順で自動で移動します。
3.クエストを受注して納品する
あとは勝手にクエストを受注して、ケルビの角を納品してベルナ村に帰ってきます。これを10回繰り返します。
上手くいかない場合は、実行コードのクエストロード時間を調整してみてください。
4.自室に戻る
10回納品したら、勝手に自宅に戻り、コードの実行を終了します。
コントローラーを切り替えて、手動でルームサービスに話しかけ、マカ錬金を確認してください。
神おまが出たらセーブ、出なければセーブせずにMHXXを終了し、再び 2.からやり直します。
効率について
単純な効率の良さで言えば、ブラキ炭鉱には敵わないです。というかアレが壊れすぎ。異常です。
この自動化によって、別の作業のついでに錬金ガシャを進めることが目的なので、あくまで補助的な作業と捉えてください。
あとマカ錬金の素材集めは別途必要なので、頑張って集めましょう。
神おま、ゲットだぜ!!!
おしまい