【レジェンズZA自動化02】ワイルドゾーン色厳選(ファストトラベル自動化)

こんにちは。ますたーです。

 

今回は、レジェンズZA自動化第2弾の記事として、ファストトラベルによる色厳選を自動化しました(第1弾はベンチ色厳選)。

 

なお、Arduino Leonardo自動化の導入・機材構成については導入記事を参考にしてください。

導入記事:【Arduino自動化01】Arduino開発環境の導入

※本ブログに初めてお越しの方は「本ブログについて」もぜひ、ご覧ください。

 

概要

ポケモンレジェンズZAでは、ファストトラベルで画面を切り替えることで色厳選ができます。これをArduino Leonardoで自動化しました。ワイルドゾーン1~20すべてに対応できるように、プログラム上で「ローリング」の有無を切り替えられるようにしました。

ポケモンZAでは、ファストトラベルをし続ければ色厳選ができる。
ワイルドゾーン2と5以外では、ローリングが必要になる

目次です。今回もあっさり!

 

1.レジェンズZAの色違い厳選は「画面切り替え」がキー

前回(ベンチ色厳選)に記載の通り、ポケモンレジェンズZAでは「画面を切り替える」ことで主人公の半径50マスのポケモンが色違いかどうか再抽選されます*1。具体的には、ベンチで時間を潰すことで昼夜を切り替えたり、建物に出入りしたりなど、画面全体を暗転させることで再抽選を能動的に行うことができます。

ベンチで昼夜を切り替えたり建物から出入りしたり、「画面切り替え」で色厳選ができる

 

2.ファストトラベルを使えばすべてのワイルドゾーンで色厳選が可能

画面の切り替えを行うことで色厳選ができるため、ベンチさえあればどこでも色違いの厳正ができるのですが、今作で野生ポケモンが出現するワイルドゾーンには、ベンチがないところもあります。すなわち、ベンチ厳選ができないということです。

このような、ベンチがないワイルドゾーンでは「ファストトラベル」を使うことで色違い厳選が可能になります*2。言い換えれば、ファストトラベルを使えば、ベンチの有無に関わらずすべてのワイルドゾーンで色厳選が可能になる、ということです。

ファストトラベルを使った色厳選の方法はシンプルで、下記の通りです。

  1. ワイルドゾーンの入口に立つ
  2. ワイルドゾーンに入る
  3. MAPを開いて、入ったワイルドゾーンにファストトラベルを行う
  4. 手順1に戻る

「ファストトラベル」なら、ベンチがないワイルドゾーンでも色違い厳選が可能


3.ワイルドゾーン2・ワイルドゾーン5以外はローリングが必須

さて、前述の通り、「ファストトラベル」を使うことですべてのワイルドゾーンでの色厳選が可能となりましたが、実はワイルドゾーンによって多少コントローラーの操作が異なります。というのも、「ファストトラベル」でワイルドゾーンに移動すると入口の前には到着するのですが、ワイルドゾーン2,5以外では「A」を押してそのまま入れる距離に主人公が立ってくれません。

言い換えると、2番・5番以外のワイルドゾーンではファストトラベル後にスティックを上に倒すかYで1回ローリングするかして、入口に近づかなければならないのです。

ワイルドゾーン2,5以外ではローリングしないとAボタンで中に入れないのだ
左:ワイルドゾーン2(ローリング不要)/右:ワイルドゾーン11(ローリング必要)

ワイルドゾーン1,3,4,6~20では、ファストトラベル後にローリングが必須なのだ

ゆえに、コントローラーの操作で表現すると、ファストトラベルによる色厳選の操作は下記手順のようになります。

【ファストトラベル色厳選の手順】

  1. ワイルドゾーンの前からスタート
  2. 「A」を押してワイルドゾーンに入る
  3. 「+」を押してMAPを開く
  4. 「A」を2回押して、ワイルドゾーンにファストトラベルを行う
  5. ワイルドゾーン2,5以外の場合は「Y」を押してローリングを行う
  6. 手順2に戻る

上記の手順5のように、ほとんどのワイルドゾーンでは、ローリングで入口に近づかないと入れないことには注意して、色厳選を行いましょう。

 

4.ソースコード

ファストトラベルを使ったワイルドゾーンの色厳選の自動化をArduinoで行いました。

前述の通り、ワイルドゾーン2およびワイルドゾーン5以外のワイルドゾーンでは、ファストトラベル後にローリングを行って入口に近づかないとAボタンで中に入れないので、その部分を切り替えて使えるようにしています。

したがって、冒頭のWILD_ZONEのカッコ内の数字を、使いたいワイルドゾーンの番号に合わせて書き換えてください。例えば、ワイルドゾーン5で使いたい場合は、下記のようになります。

const int WILD_ZONE =(5); // ←★★★カッコ()の中に、ワイルドゾーンの数字を入力してください★★★

 

プログラム全文はこちらです。

/*  ポケモンレジェンズZA ファストトラベル色違い厳選(ワイルドゾーン用)
 *   
 *   ★★★★★★★★【重要】★★★★★★★★★★★
 *   本プログラム40行目の「const int WILD_ZONE =(11);」の()の中に
 *   使いたいワイルドゾーンの番号を半角英数字で入れてください!
 *   例えば、ワイルドゾーン5で使いたかったらconst int WILD_ZONE =(5);です
 *   ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 *   
 *   【説明】
 *   ワイルドゾーン入っては、ファストトラベルを行う、というのを繰り返す。
 *   【!】ドックに差す際は、プロコントローラーなど、他のコントローラーとの接続を切っておきましょう。
 *   
 *   【準備】
 *   ・話のはやさを「はやい」にしておく
 *   ・ファストトラベル(空を飛ぶ)で、ワイルドゾーン5に飛んでおく。
 *   (Aを押したらそのままワイルドゾーン5に入れる状態)
 *   ・Arduinoをさすだけ。
 *   
 *   【挙動】
 *   ArduinoをSwitchにさすと、手持ちポケモンのカーソルが右に何回か動きます。
 *   その後、ループが開始されます。
 *   (ワイルドゾーンに入って、マップを開き、場所に移動するだけ)
 *   
 *   【メモ】
 *   昼夜が入れ替わったタイミングで、MAPを開きっぱなしになることもありますが、いずれ「+」ボタンでMAPが閉じられるので通常ループに戻ります
 *   
 *   ★野生ポケモンに見つかるなどした場合は、ループが破綻します。ワイルドゾーン19など。
 *   ★このプログラムは「ワイルドゾーン5」用に作成したものです(他の場所でも使えるかもしれませんが、あくまでもリーリングによるファストトラベルはおまけとして考えてください)
 *   ★Switch2でしか動作確認していません。必要に応じて、待機時間などを調整してください。
 *   特に「1800ミリ秒(Aを押してMAPを開けるようになるまでの時間)」「3100ミリ秒(ファストトラベルからの復帰時間)」はギリギリにしているので、もう少し余裕を持たせても良いかもしれません。
 *   
 *  (c) 2026 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
*/

#include <SwitchControlLibrary.h>
#define HOLDTIME (95) // 1回のキー入力の長押し時間
#define SWITCH_VER (20)

const int WILD_ZONE =(5); // ←★★★カッコ()の中に、ワイルドゾーンの数字を入力してください★★★

// ボタン押しラッパー関数
int PushKey(char* keyname, int holdtime, int delaytime);
void TiltLeftStick(int direction_deg, double power, int holdtime, int delaytime);
void TiltRightStick(int direction_deg, double power, int holdtime, int delaytime);


void setup() {
  for(int i=0;i<7;i++)PushKey("RIGHT", HOLDTIME, 300); // 十字右ボタンを7回押してSwitchに認識されるのを待つ
  PushKey("B", HOLDTIME, 300); // とりあえず1回Bを押しておく。
  delay(1000);

  // しゃがむ
  SwitchControlLibrary().PressButtonLClick();
  delay(300);
  SwitchControlLibrary().ReleaseButtonLClick();
  delay(500);

  // たちあがる
  SwitchControlLibrary().PressButtonLClick();
  delay(300);
  SwitchControlLibrary().ReleaseButtonLClick();
  delay(500);
 
}

// ワイルドゾーンの前からスタート
void loop() {

  switch(WILD_ZONE){
    case 2: case 5:
      // 前進不要
      break;
    default:
      PushKey("Y", HOLDTIME, 1000); // ローリング
      break;
  }

  // ワイルドゾーンに入る
  PushKey("A", HOLDTIME, 2200); // 入る [最短1800]

  // 地図を開いてワイルドゾーン5へ飛ぶ
  PushKey("+", HOLDTIME, 700); // マップを開いて
  PushKey("A", HOLDTIME, 500); // ワイルドゾーンを選択
  PushKey("A", HOLDTIME, 3200); // この場所に移動しますか? >はい [最短3100]

}


int PushKey(char* keyname, int holdtime, int delaytime){
  // ホームボタン・方向キーはRight, Left, Up, Down, Homeなど2文字以上で入力。
  // その他ボタン入力は1文字(A,B,X,Y,R,L,+,-)ZR・ZLにも対応
  // 同時押しは非対応
  
  if(strlen(keyname)==1){
    switch(keyname[0]){
      case 'A': case 'a': // A
        SwitchControlLibrary().PressButtonA(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonA(); delay(delaytime);
      break;
      case 'B': case 'b': // B
        SwitchControlLibrary().PressButtonB(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonB(); delay(delaytime);
      break;
      case 'X': case 'x': // X
        SwitchControlLibrary().PressButtonX(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonX(); delay(delaytime);
      break;
      case 'Y': case 'y': // Y
        SwitchControlLibrary().PressButtonY(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonY(); delay(delaytime);
      break;
      case 'L': case 'l': // L
        SwitchControlLibrary().PressButtonL(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonL(); delay(delaytime);
      break;
      case 'R': case 'r': // R
        SwitchControlLibrary().PressButtonR(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonR(); delay(delaytime);
      break;
      case 'H': case 'h': // Home
        SwitchControlLibrary().PressButtonHome(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonHome(); delay(delaytime);
      break;
      case '+': case 'p': case 'P': // Plus
        SwitchControlLibrary().PressButtonPlus(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonPlus(); delay(delaytime);
      break;
      case '-': case 'm': case 'M': // Minus
        SwitchControlLibrary().PressButtonMinus(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonMinus(); delay(delaytime);
      break;
      default:
      break;
    }
  }else if(strlen(keyname)>=2){
    switch(keyname[0]){
      case 'z': case 'Z': // ZR/ZL
        if(keyname[1]=='R'||keyname[1]=='r'){
          SwitchControlLibrary().PressButtonZR(); delay(holdtime);
          if(holdtime>0)SwitchControlLibrary().ReleaseButtonZR(); delay(delaytime);
        }
        if(keyname[1]=='L'||keyname[1]=='l'){
          SwitchControlLibrary().PressButtonZL(); delay(holdtime);
          if(holdtime>0)SwitchControlLibrary().ReleaseButtonZL(); delay(delaytime);
        }
      break;
      case 'r': case 'R': // right
        SwitchControlLibrary().MoveHat(2); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'l': case 'L': // left
        SwitchControlLibrary().MoveHat(6); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'u': case 'U': // up
        SwitchControlLibrary().MoveHat(0); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'd': case 'D': // down
        SwitchControlLibrary().MoveHat(4); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'H': case 'h': // Home
        SwitchControlLibrary().PressButtonHome(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonHome(); delay(delaytime);
      default:
      break;  
    }
  }else{
    return -1;
  }
  return strlen(keyname);
}

void TiltLeftStick(int direction_deg, double power, int holdtime, int delaytime){
  double rad = (double)direction_deg*PI/180.0; // 弧度法(ラジアン)変換
  int x, y;
  x = (double)128*sin(rad)*power;
  y = (double)-128*cos(rad)*power;
  x += 128; y += 128;
  if(x >= 255) x=255; if(x <= 0) x=0;
  if(y >= 255) y=255; if(y <= 0) y=0;

  SwitchControlLibrary().MoveLeftStick(x,y);
  if(holdtime> 0){ // holdtime=0のときは押しっぱなし。
    delay(holdtime);
    SwitchControlLibrary().MoveLeftStick(128,128); // 傾きを直す
  }
  if(delaytime>0) delay(delaytime);
  return;
}

void TiltRightStick(int direction_deg, double power, int holdtime, int delaytime){
  double rad = (double)direction_deg*PI/180.0; // 弧度法(ラジアン)変換
  int x, y;
  x = (double)128*sin(rad)*power;
  y = (double)-128*cos(rad)*power;
  x += 128; y += 128;
  if(x >= 255) x=255; if(x <= 0) x=0;
  if(y >= 255) y=255; if(y <= 0) y=0;

  SwitchControlLibrary().MoveRightStick(x,y);
  if(holdtime> 0){ // holdtime=0のときは押しっぱなし。
    delay(holdtime);
    SwitchControlLibrary().MoveRightStick(128,128); // 傾きを直す
  }
  if(delaytime>0) delay(delaytime);
  return;
}

 

5.おわりに

世間はDLCで遊んでいたり、Switch2の「ぽこ・あ・ポケモン」を予約したりしている頃でしょうか。私も、ついにZAのエンドロールを見るところまで進めることができました。

さて、仕事もプライベートも大きな転機を迎えている中、無事にレジェンズZA自動化で2件目の更新をなんとか行うことができ、一安心です。というのも、2月中旬に引っ越し結婚をしたため、本当に平日も土日祝もバタバタとしており、未だSwitch2を遊ぶ環境はおろか、パソコンのモニタすらない状態で、かなりパニックな毎日を送っております(まだ段ボールと一緒に過ごす生活…笑)。

筆者・ますたーは、2026年2月11日に結婚しました!わーい!

このブログを書くための環境すらままならない状況でしたが、なんとか気合で書き上げることができました。もう少し片付けが進んで、プライベートが落ち着いたら、DLCを購入して遊びたいです。

なお、本ブログは折を見て更新したいと想いますし、まだまだマイペースながらも継続する気マンマンですので、引き続き応援をよろしくお願いいたします。

 

今後とも、よろしくお願いいたします。

 

ではではc⌒っ.ω.)っ

 

--

本ブログについて:本ブログについて

 

Arduino導入記事:【Arduino自動化01】Arduino開発環境の導入

ポケモン剣盾の記事:ポケモン剣盾Arduino自動化 カテゴリーの記事一覧

ポケモンBDSPの記事:ダイパリメイクArduino自動化 カテゴリーの記事一覧

レジェンズアルセウスの記事:レジェンズアルセウスArduino自動化 カテゴリーの記事一覧

スカーレット・バイオレットの記事:スカーレットバイオレットArduino自動化 カテゴリーの記事一覧

レジェンズZ-Aの記事:レジェンズZA自動化 カテゴリーの記事一覧

 

YouTubeチャンネル:ますたーの忘備録 - YouTube

www.youtube.com

 

*1:より厳密には、再生成(リポップ)されるのは50マスとのことですが、そのポケモンが消えるのは70マス~80マスと言われています

*2:ワイルドゾーン16やワイルドゾーン19のように、一部、ベンチがないにも関わらずファストトラベルでの色厳選が適さないワイルドゾーンもあります