【ポケモンSV】パソコン1台で自動化いろいろ

概要

【ポケモンSV】パソコン1台でテラピース自動収集 の記事で紹介した手法を用いて、他にも対戦に役立つ作業を自動化する。

準備

前述の記事を参照。
必須ではないが、Joycontrolを実行するコマンドが長いので、aliasを設定しておくと便利。
ターミナル(端末)を立ち上げて、適当なエディタで.bashrcを開く。

nano ~/.bashrc

末尾に以下を追記する。

alias joycon='sudo joycontrol-pluginloader -r 04:03:D6:21:42:93'

04:03:D6:21:42:93のところは自分のスイッチのMACアドレスに置き換える。
端末を再起動するか、ターミナルで

source ~/.bashrc

を実行して.bashrcを再度読み込むと、Joycontrolを実行する際、

sudo joycontrol-pluginloader -r 04:03:D6:21:42:93 hoge.py

と入力しなくとも、

joycon hoge.py

のように短いコマンドで実行できる。

自動化スクリプト

学校最強大会

Aボタンを連打するマクロは、Joycontrolのプリセットとして用意されている。 学校最強大会の受付で以下のコマンドを実行する。

sudo joycontrol-pluginloader -r 04:03:D6:21:42:93 ~/joycontrol-pluginloader/plugins/utils/RepeatA.py

テラレイド(オンライン)

【ポケモンSV】パソコン1台でテラピース自動収集 でも書いたが、ハピナスレイド等の期間中はボタン連打で簡単に周回できる。
新しくPythonスクリプトを作成する。

nano raid.py

raid.pyに以下をコピペする。

import logging
from JoycontrolPlugin import JoycontrolPlugin
class raid(JoycontrolPlugin):
    # 特定のボタンをt秒ごとにn回押す関数
    async def push(self, button, n=1, t=0.1):
        for _ in range(n):
            await self.button_push(button)
            await self.wait(t)

    async def run(self):
        while True:
            await self.push('x', t=1.0)
            await self.push('a', t=0.5)
            await self.push('r', t=0.5)                                                                                      
            await self.push('a', t=0.5)

インターネットに接続してオンラインのテラレイドのページに移動し、以下を実行する。

sudo joycontrol-pluginloader -r 04:03:D6:21:42:93 raid.py

ファイル名(raid.py)とクラス名(raid)が一致していないと動作しない点に注意。

競り

日付変更あり。
本体設定から"インターネットで時間をあわせる"をオフにする。
新しくPythonスクリプトを作成する。

nano auction.py

auction.pyに以下をコピペする。

import logging
from JoycontrolPlugin import JoycontrolPlugin

logger = logging.getLogger(__name__)

class auction(JoycontrolPlugin):
    # 特定のボタンをt秒ごとにn回押す関数
    async def push(self, button, n=1, t=0.1):
        for _ in range(n):
            await self.button_push(button)
            await self.wait(t)

    # セーブする関数
    async def save(self):
        logger.info('Saving.')
        await self.push('x', t=0.5)
        await self.push('r', t=1)
        await self.push('a', t=3)
        await self.push('b', n=2, t=0.5)

    # 日付を変更する関数
    async def change_date(self, d=1, m=0, y=0):
        logger.info('Changing date.')
        # Close game                                                                                                          
        await self.push('home', t=0.5)
        await self.push('x', t=0.5)
        await self.push('a', t=5)

        # Move to setting                                                                                                     
        await self.push('down')
        await self.push('right', n=5)
        await self.push('a', t=1)

        # Move to current date/time setting                                                                                   
        await self.push('down', n=15, t=0.07)
        await self.push('a')
        await self.push('down', n=9, t=0.07)
        await self.push('a', t=0.2)
        await self.push('down', n=2, t=0.07)
        await self.push('a')

        # Change date                                                                                                         
        cmd = 'up' if y >= 0 else 'down'
        for i in range(y):
            await self.push(cmd, n=y)
        await self.push('a')

        cmd = 'up' if m >= 0 else 'down'
        for i in range(m):
            await self.push(cmd, n=m)
        await self.push('a')

        cmd = 'up' if d >= 0 else 'down'
        for i in range(d):
            await self.push(cmd, n=d)
        await self.push('a')

        await self.push('a', n=3, t=0.2)
        await self.push('home', t=1)

        # Launch game                                                                                                         
        await self.push('a', t=1)
        await self.push('a', t=20)
        await self.push('a', t=25)

    # オークション自動化. Aボタン連打と日付変更を繰り返す
    async def run(self):
        count = 0
        while True:
            await self.push('a', n=120, t=0.5)
            await self.push('b', n=2, t=0.5)
            await self.save()
            await self.change_date()
            count += 1
            logger.info('%d finished.' % count)

マリナードタウンの販売員の前で以下を実行する。

sudo joycontrol-pluginloader -r 04:03:D6:21:42:93 auction.py

コレクレーのコイン集め

日付変更あり。
パルデア十景の看板にいる徒歩コレクレーを周回する。
新しくPythonスクリプトを作成する。

nano coin.py

coin.pyに以下をコピペする。

import logging
from JoycontrolPlugin import JoycontrolPlugin

logger = logging.getLogger(__name__)

class coin(JoycontrolPlugin):
    # 特定のボタンをt秒ごとにn回押す関数
    async def push(self, button, n=1, t=0.1):
        for _ in range(n):
            await self.button_push(button)
            await self.wait(t)

    # Lスティックをt秒間入力する関数
    async def l_stick(self, direction, t=0.1):
        await self.left_stick(direction)
        await self.wait(t)

    # セーブする関数
    async def save(self):
        await self.push('x', t=0.5)
        await self.push('r', t=1)
        await self.push('a', t=3)
        await self.push('b', n=2, t=0.5)

    # 日付を変更する関数
    async def change_date(self, d=1, m=0, y=0):
        # Close game                                                                                                          
        await self.push('home', t=0.5)
        await self.push('x', t=0.5)
        await self.push('a', t=5)

        # Move to setting                                                                                                     
        await self.push('down')
        await self.push('right', n=5, t=0.05)
        await self.push('a', t=1)

        # Move to current date/time setting                                                                                   
        await self.push('down', n=15, t=0.07)
        await self.push('a')
        await self.push('down', n=9, t=0.07)
        await self.push('a', t=0.2)
        await self.push('down', n=2, t=0.07)
        await self.push('a')

        # Change date                                                                                                         
        cmd = 'up' if y >= 0 else 'down'
        for i in range(y):
            await self.push(cmd, n=y)
        await self.push('a')

        cmd = 'up' if m >= 0 else 'down'
        for i in range(m):
            await self.push(cmd, n=m)
        await self.push('a')

        cmd = 'up' if d >= 0 else 'down'
        for i in range(d):
            await self.push(cmd, n=d)
        await self.push('a')

        await self.push('a', n=3, t=0.2)
        await self.push('home', t=1)

        # Launch game                                                                                                         
        await self.push('a', t=1)
        await self.push('a', t=20)
        await self.push('a', t=25)

    # Lスティックで移動する関数
    async def move(self, x=0, y=0):
        if x > 0:
            await self.l_stick('right', t=x)
        elif x < 0:
            await self.l_stick('left', t=-x)
        if y > 0:
            await self.l_stick('up', t=y)
        elif y < 0:
            await self.l_stick('down', t=-y)
        await self.l_stick('center', t=0.5)

    # マップ移動する関数
    async def map_move(self, x=0, y=0):
        await self.push('y', t=2)
        await self.move(x, y)
        await self.push('a', t=0.5)
        await self.push('a', t=1)
        await self.push('a', t=10)

    # パルデア十景巡り
    async def run(self):
        count = 0
        while True:
            # マップ上で一番左下に移動                                                                                           
            await self.push('y', t=2)
            await self.move(x=-10, y=-10)

            # オリーブ農園                                                                                                      
            await self.move(x=2.73, y=2.08)
            await self.push('a', t=0.5)
            await self.push('a', t=1)
            await self.push('a', t=10)

            await self.push('l', t=0.5)
            await self.move(x=-0.7, y=0.3)
            await self.move(x=-0.05)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

           # ビシャビシャの斜塔                                                                                                      
            await self.map_move(x=-1.25, y=-0.8)
            await self.move(x=0.95, y=0.5)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

            # ありがた岩                                                                                        
            await self.map_move(x=-0.31, y=4.88)
            await self.push('l', t=0.5)
            await self.move(x=1)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

            # オージャの大滝                                                                                                  
            await self.map_move(x=1.74, y=-0.46)
            await self.move(x=-0.7, y=0.45)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

            # ナッペの手                                                                                                      
            await self.map_move(x=0.45, y=-0.23)
            await self.push('l', t=0.5)
            await self.move(x=-0.8, y=0.18)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

           # パルデア最高峰                                                                                                   
            await self.map_move(x=1.27, y=-0.23)
            await self.move(x=-0.45, y=0.7)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

            # 100万ボルトの夜景                                                                                                     
            await self.map_move(x=1.46, y=-1.76)
            await self.move(x=0.42, y=0.5)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

            # ひそやかビーチ                                                                                                
            await self.map_move(x=-0.46, y=-2.48)
            await self.move(y=1)
            await self.push('a', t=0.5)
            await self.push('a', t=1)

            await self.save()

            count += 1
            logger.info('%dth' % count)

            await self.change_date()

マップ移動ができる場所で以下を実行する。

sudo joycontrol-pluginloader -r 04:03:D6:21:42:93 coin.py