【Arduino Leonardo】タマゴ回収~孵化自動化【ポケモンSV】
はじめに
Arduino Leonardoでタマゴ回収から孵化するまでを自動化しました。検証回数が少ないのですが動作確認はできたのでとりあえず公開しておきます。
ライブラリはNintendoSwitchControll-masterを使用しています。導入方法などはこちらでは説明しませんのでまだの方は上記リンクや他サイトを参考にしてください。
またポケモンSVは処理落ちやエラー落ちすることがあるため長時間放置は自己責任でお願いいたします。
プログラムについて
以下の動作を行います。
スター団アジトでピクニックを開始
タマゴ回収位置に移動
指定回数タマゴパワー2のサンドウィッチを作りタマゴ回収×3回を繰り返した後ピクニックを終了
ピクニック開始位置に戻る
レポートを書く
コライドンorミライドンに乗って指定ボックス数孵化する
わりと安定していますが入力漏れが発生してうまく行かない場合があるので完全放置は非推奨です。
大体1ボックス分で1時間程掛かります。
事前準備
設定
以下で設定してください。
話のはやさ→はやい
ニックネーム登録→つけない
技覚えスキップ→する
メッセージ送りとニックネームは定番ですが、技覚えスキップはピクニック終了時に経験値が入り孵化親がレベルアップして技を覚えるのを防ぐためです。
また図鑑登録が表示されるとズレる可能性があるため、孵化するポケモンは捕獲済みの状態にしておきましょう。
食材
ベーカリー オルノでバター、ピーナッツバター、ピック、缶の大将でバナナスライスを各々買います。サンドウィッチ1個につき各1個使います。ピックは何でもいいんですが一番上のを消費するのでシルバーピック推奨です。安いし。
次にサンドウィッチを作る際にバナナスライスが一番下、バター、ピーナッツバターが一番上に来るようにそれ以外の食材を売ります。
バナナスライスも一番上にした方がボタン1入力分時短できますが売る食材が多くなるのでこれで。(ちょっとでも時短したい人はバナナスライスも一番上にして該当部分を書き換えてください)
手持ち
孵化親2匹のみにしてください。必要に応じてかわらずのいしやあかいいと等のアイテムを持たせてください。
ボックス
タマゴを回収する1ボックス目の左隣ボックスの左上に孵化歩数を半減する特性のポケモン(ほのおのからだ等)を置き、その1つ下を空にしておきます。それ以外は指定ないですが沢山入れていると読み込みに時間が掛かると思うので詰め込みすぎない方がいいです。
左隣の準備ができたらボックスを開いた時にタマゴを回収する1ボックス目になるようにしてください。4ボックス回収する場合は1ボックス目+右3ボックス分を空にしておきます。
立ち位置
スター団アジトの開けた場所で背を向けた状態でプログラムを実行します。かくとう組は広いスペースがないのでそれ以外で行ってください。
アジト敷地内に野生のポケモンは発生しませんが敷地外から入ってくる可能性があるため出入り口付近は避けた方がいいです。あとストーリークリア後ボスに話しかけると再戦してしまうのでその辺も注意して立ち位置を決めてください。(再戦1日1回なので不安なら先に倒しといてもいい)
プログラム(コード)
以下コピペしてください。サンドウィッチを作る回数、孵化するボックス数、共に4としています。また孵化はサイクル40用にしています。必要に応じて変更してください。待機時間は余裕を持っているつもりですがうまく動かなかったら調整してください。タマゴ孵化はライブラリ内のプログラムをほぼ転用させていただいています。
#include <auto_command_util.h>
/*
* 設定はメッセージ送り速い、ニックネームつけない、技覚えスキップする
* サンドウィッチを作る時バナナスライスが一番下、バター・ピーナツバターが一番上
* 手持ちは孵化親2匹のみ
* タマゴ回収1ボックス目の左隣の左上に孵化歩数半減ポケモン、その1つ下は空にする
* ボックスを開いた時にタマゴ回収1ボックス目になるようにする
* スター団アジトの開けた場所で背を向けた状態でプログラム実行
*/
int i,j;
int box_line,egg_num;
int cook_set = 4;//サンドウィッチを作る回数
int box_set = cook_set;//孵化するボックス数
int run_time_sec = 130;//走る時間
//剣盾でのサイクル数毎の目安:40→130(SV確認済)、30→100、20→70(SV確認済)、15→55、10→40
int sleepGAMEset = 1;//プログラム終了後スリープする場合は1、しない場合は0
void setup() {
pushButton(Button::ZL, 500, 5);//最初の数回の入力はswitchが認識しないので無駄打ちをしておく
}
//メニューを開きピクニックを開始
void PicnicOpen(bool first_time = false){
pushButton(Button::X, 1200);
if(first_time){
pushHatButton(Hat::RIGHT, 500);
pushHatButtonContinuous(Hat::UP, 1500);
pushHatButton(Hat::DOWN, 500, 2);
}
pushButton(Button::A, 8000);
}
//バスケットの方まで移動
void walktoBasket(){
//しゃがんで1歩ずつ進む
pushButton(Button::B, 500);
for(i=0;i<3;i++){//右に3歩
tiltJoystick(100,0,0,0,100);
delay(500);
}
for(i=0;i<5;i++){//上に5歩
tiltJoystick(0,-100,0,0,100);
delay(500);
}
for(i=0;i<3;i++){//左に3歩
tiltJoystick(-100,0,0,0,100);
delay(500);
}
//立ってテーブルに密着
pushButton(Button::B, 500);
tiltJoystick(0,100,0,0,1000);//下
}
//指定回数サンドウィッチを作りタマゴを回収しピクニックを終了する
void EegGet(){
for(i=0;i<cook_set;i++){
//料理選択
pushButton(Button::A, 1000);
pushButton(Button::A, 4500);
//フリーモードでバナナスライス、バター、ピーナツバター、ピックを選ぶ
pushButton(Button::X, 300);
pushHatButton(Hat::UP, 300);
pushButton(Button::A, 300);
pushButton(Button::PLUS, 300);
pushButton(Button::A, 300);
pushHatButton(Hat::DOWN, 300);
pushButton(Button::A, 300);
pushButton(Button::PLUS, 300);
pushButton(Button::A, 8000);
//バナナスライスを乗せる
tiltJoystick(0,-100,0,0,700);//上
SwitchController().pressButton(Button::A);
delay(100);
tiltJoystick(0,100,0,0,700);//下
SwitchController().releaseButton(Button::A);
delay(100);
tiltJoystick(0,-100,0,0,700);//上
SwitchController().pressButton(Button::A);
delay(100);
tiltJoystick(-20,100,0,0,700);//下
SwitchController().releaseButton(Button::A);
delay(100);
tiltJoystick(20,-100,0,0,700);//上
SwitchController().pressButton(Button::A);
delay(100);
tiltJoystick(20,100,0,0,700);//下
SwitchController().releaseButton(Button::A);
delay(100);
tiltJoystick(0,-100,0,0,700);//上
delay(1000);
pushButton(Button::A, 2000);//上のパンを捨てる
pushButton(Button::A, 10000);//ピックを挿す
pushButton(Button::A, 24000);//完成図送り
pushButton(Button::A, 1000);//効果送り
tiltJoystick(0,-100,0,0,50);//バスケットの方を向く
//卵受け取り処理
for(j=0;j<3;j++){
pushButton(Button::B, 10000, 42);//スリープ回避のため10秒間隔でスクワットして7分待機
pushButton(Button::A, 400);//タマゴ受け取り
pushButton(Button::B, 400, 90);//タマゴ受け取り後その場でスクワット
}
delay(500);
pushButton(Button::PLUS, 50, 3);//立たせるためにコラミラ出し入れ、念のため多めに押しておく
delay(8000);
tiltJoystick(0,100,0,0,1000);//テーブルの方を向く
}
//指定回数終了後ピクニックを終了する
pushButton(Button::Y, 1000);
pushButton(Button::A, 400, 15);
}
//開始位置に戻る処理
void walk4steps(){
pushButton(Button::B, 500);
for(i=0;i<4;i++){//下に4歩
tiltJoystick(0,100,0,0,100);
delay(500);
}
pushButton(Button::B, 500);
tiltJoystick(0,-100,0,0,50);
delay(300);
}
//メニューを開きレポートを書く
void svSave(){
pushButton(Button::X, 1200);
pushButton(Button::R, 1200);
pushButton(Button::A, 2800);
pushButton(Button::B, 800, 2);
}
//メニューを開きボックスを開く
void BoxOpen(bool first_time = false){
pushButton(Button::X, 1200);
if(first_time){
pushHatButton(Hat::RIGHT, 500);
pushHatButtonContinuous(Hat::UP, 1500);
pushHatButton(Hat::DOWN, 500);
}
pushButton(Button::A, 4000);
}
//孵化するまで走る
void RunAround(){
// delayの秒数がintの最大値を越えないように30秒ごとに実行する
for(int i=0; i<run_time_sec/30; i++){
tiltJoystick(100, 0, -100, 0, 30000);
}
tiltJoystick(100, 0, -100, 0, (run_time_sec%30)*1000);
}
//孵化するまで待つ
void waitEggHatching(){
pushButton(Button::A, 500, 55);
//話しかけてしまうようなら以下に変更。空き時間ジャンプしまくるけど
//pushButton(Button::B, 500, 55);
//delay(1000);//着地まで待つ
}
//2~5個目の孵化
void RunAroundandwaitEggHatching(){
for(egg_num=0; egg_num<4; egg_num++){
tiltJoystick(100, 0, -100, 0, 8000);
waitEggHatching();
}
}
//指定ボックス数孵化する
void EggHatching(){
pushButton(Button::PLUS, 50, 3);//コラミラに乗る。念のため多めに押しておく
delay(6000);
BoxOpen(true);//ボックスを開く
//左のボックスに移動し孵化歩数半減ポケモンを手持ちに入れ親個体を預ける
pushButton(Button::L, 1500);
pushButton(Button::Y, 500);
pushHatButton(Hat::LEFT, 500);
pushHatButton(Hat::DOWN, 500, 2);
pushButton(Button::Y, 500);
pushHatButton(Hat::UP, 500);
pushButton(Button::MINUS, 500);
pushHatButton(Hat::UP, 500);
pushButton(Button::A, 500);
pushHatButton(Hat::RIGHT, 500);
pushButton(Button::A, 500);
pushButton(Button::R, 1500);
//ここまでで1ボックス目の左上にカーソルがくる
for(i=0;i<box_set;i++){
for(box_line=0; box_line<6; box_line++){
//タマゴを引き取る
//ボックスから移動させる
pushButton(Button::MINUS, 500);
pushHatButtonContinuous(Hat::DOWN, 1000);
pushButton(Button::A, 500);
pushHatButton(Hat::LEFT, 500, box_line+1);
pushHatButton(Hat::DOWN, 500);
pushButton(Button::A, 500);
//ボックスを閉じる
pushButton(Button::B, 50, 3);
delay(2500);
pushButton(Button::B, 2000);
RunAround();//孵化するまで走る
waitEggHatching();//孵化を待つ
RunAroundandwaitEggHatching();//2~5個目の孵化
//手持ちを預ける
BoxOpen();//ボックスを開く
//手持ちのポケモンを範囲選択
pushHatButton(Hat::LEFT, 500);
pushHatButton(Hat::DOWN, 500);
pushButton(Button::MINUS, 500);
pushHatButtonContinuous(Hat::DOWN, 1000);
pushButton(Button::A, 500);
//ボックスに移動させる
pushHatButton(Hat::RIGHT, 500, box_line+1);
pushHatButton(Hat::UP, 500);
pushButton(Button::A, 500);
//右隣受け取る準備
pushHatButton(Hat::RIGHT, 500);
}
//6回終わったら次のボックスに移動させる
pushHatButton(Hat::RIGHT, 500);
pushButton(Button::R, 1500);
}
}
//本体スリープ
void sleepGAME(){
SwitchController().pressButton(Button::HOME);
delay(1500);
SwitchController().releaseButton(Button::HOME);
delay(200);
pushButton(Button::A, 500);
}
void loop() {
pushButton(Button::L, 200, 3);//カメラ位置初期化
PicnicOpen(true);//ピクニック開始
walktoBasket();//タマゴ回収位置に移動
EegGet();//タマゴ回収~ピクニック終了
walk4steps();//ピクニック開始位置に戻る
svSave();//レポートを書く
EggHatching();//孵化する
if(sleepGAMEset){ sleepGAME(); }//本体スリープ
while(1){ delay(10000); }
}
その他(解説など)
タマゴパワー2だとタマゴ10個貯まるのに約5分と見たので7分にしてみました。「7分ならサンドウィッチ1個で4回タマゴ拾えるだろ」と言われそうですが1ループ40個より1ループ30個の方が孵化とのバランスがとれるので3回で。
孵化でぐるぐる回っていると徐々に位置がずれていきます。スティックの角度で改善できそうですが、毎回同じ様にずれるかもわからないので要検証。現状広めにスペース確保していれば大丈夫かと思います。