def _choose_action() -> str:
        """Chooses the next action to take for the current Arcarum expedition.

        Returns:
            (str): The action to take next.
        """
        from bot.game import Game

        # Determine what action to take.
        MessageLog.print_message(
            f"\n[ARCARUM] Now determining what action to take...")

        # Wait a second in case the "Do or Die" animation plays.
        Game.wait(1)

        tries = 3
        while tries > 0:
            # Prioritise any enemies/chests/thorns that are available on the current node.
            arcarum_actions = ImageUtils.find_all("arcarum_action")
            if len(arcarum_actions) > 0:
                MouseUtils.move_and_click_point(arcarum_actions[0][0],
                                                arcarum_actions[0][1],
                                                "arcarum_action")

                Game.wait(2)

                Game.check_for_captcha()

                if ImageUtils.confirm_location("arcarum_party_selection",
                                               tries=1):
                    return "Combat"
                elif Game.find_and_click_button("ok", tries=1):
                    return "Claimed Treasure/Keythorn"
                else:
                    return "Claimed Spirethorn/No Action"

            # Clear any detected Treasure popup after claiming a chest.
            MessageLog.print_message(
                f"[ARCARUM] No action found for the current node. Looking for Treasure popup..."
            )
            if ImageUtils.confirm_location("arcarum_treasure", tries=1):
                Game.find_and_click_button("ok")
                return "Claimed Treasure"

            # Next, determine if there is a available node to move to. Any bound monsters should have been destroyed by now.
            MessageLog.print_message(
                f"[ARCARUM] No Treasure popup detected. Looking for an available node to move to..."
            )
            if Game.find_and_click_button("arcarum_node", tries=1):
                Game.wait(1)
                return "Navigating"

            # Check if a Arcarum boss has appeared. This is after checking for available actions and before searching for a node to move to avoid false positives.
            if Arcarum._check_for_boss():
                return "Boss Detected"

            # Next, attempt to navigate to a node that is occupied by mob(s).
            MessageLog.print_message(
                f"[ARCARUM] No available node to move to. Looking for nodes with mobs on them..."
            )
            if Game.find_and_click_button(
                    "arcarum_mob", tries=1) or Game.find_and_click_button(
                        "arcarum_red_mob", tries=1):
                Game.wait(1)
                return "Navigating"

            # If all else fails, see if there are any unclaimed chests, like the ones spawned by a random special event that spawns chests on all nodes.
            MessageLog.print_message(
                f"[ARCARUM] No nodes with mobs on them. Looking for nodes with chests on them..."
            )
            if Game.find_and_click_button(
                    "arcarum_silver_chest",
                    tries=1) or Game.find_and_click_button(
                        "arcarum_gold_chest", tries=1):
                Game.wait(1)
                return "Navigating"

            tries -= 1

        MessageLog.print_message(
            f"[ARCARUM] No action can be taken. Defaulting to moving to the next area."
        )
        return "Next Area"
    def start() -> int:
        """Starts the process of completing Arcarum expeditions.

        Returns:
            (int): Number of runs completed.
        """
        from bot.game import Game

        runs_completed = 0
        while runs_completed < Settings.item_amount_to_farm:
            Arcarum._navigate_to_map()

            while True:
                action = Arcarum._choose_action()
                MessageLog.print_message(
                    f"[ARCARUM] Action to take will be: {action}")

                if action == "Combat":
                    # Start Combat Mode.
                    if Game.find_party_and_start_mission(
                            Settings.group_number, Settings.party_number):
                        if ImageUtils.confirm_location("elemental_damage",
                                                       tries=1):
                            raise ArcarumException(
                                "Encountered an important mob for Arcarum and the selected party does not conform to the enemy's weakness. Perhaps you would like to do this battle yourself?"
                            )
                        elif ImageUtils.confirm_location("arcarum_restriction",
                                                         tries=1):
                            raise ArcarumException(
                                "Encountered a party restriction for Arcarum. Perhaps you would like to complete this section by yourself?"
                            )

                        if CombatMode.start_combat_mode():
                            Game.collect_loot(is_completed=False,
                                              skip_info=True)
                            Game.find_and_click_button("expedition")
                elif action == "Navigating":
                    # Move to the next available node.
                    Game.find_and_click_button("move")
                elif action == "Next Area":
                    # Either navigate to the next area or confirm the expedition's conclusion.
                    if Game.find_and_click_button("arcarum_next_stage"):
                        Game.find_and_click_button("ok")
                        MessageLog.print_message(
                            f"[ARCARUM] Moving to the next area...")
                    elif Game.find_and_click_button("arcarum_checkpoint"):
                        Game.find_and_click_button("arcarum")
                        MessageLog.print_message(
                            f"[ARCARUM] Expedition is complete.")
                        runs_completed += 1

                        Game.wait(1)
                        Game.check_for_skyscope()
                        break
                elif action == "Boss Detected":
                    MessageLog.print_message(
                        f"[ARCARUM] Boss has been detected. Stopping the bot.")
                    raise ArcarumException(
                        "Boss has been detected. Stopping the bot.")

                Game.wait(1)

        return runs_completed
    def _navigate_to_map() -> bool:
        """Navigates to the specified Arcarum expedition.

        Returns:
            (bool): True if the bot was able to start/resume the expedition. False otherwise.
        """
        from bot.game import Game

        if Arcarum._first_run:
            MessageLog.print_message(
                f"\n[ARCARUM] Now beginning navigation to {Arcarum._expedition}."
            )
            Game.go_back_home()

            # Navigate to the Arcarum banner.
            tries = 5
            while tries > 0:
                if Game.find_and_click_button("arcarum_banner",
                                              tries=1) is False:
                    MouseUtils.scroll_screen_from_home_button(-300)
                    tries -= 1
                    if tries <= 0:
                        raise ArcarumException(
                            "Failed to navigate to Arcarum from the Home screen."
                        )
                else:
                    break

            Arcarum._first_run = False
        else:
            Game.wait(4)

        # Now make sure that the Extreme difficulty is selected.
        Game.wait(1)

        # Confirm the completion popup if it shows up.
        if ImageUtils.confirm_location("arcarum_expedition", tries=1):
            Game.find_and_click_button("ok")

        Game.find_and_click_button("arcarum_extreme")

        # Finally, navigate to the specified map to start it.
        MessageLog.print_message(
            f"[ARCARUM] Now starting the specified expedition: {Arcarum._expedition}."
        )
        formatted_map_name = Arcarum._expedition.lower().replace(" ", "_")

        if Game.find_and_click_button(f"arcarum_{formatted_map_name}",
                                      tries=5) is False:
            # Resume the expedition if it is already in-progress.
            Game.find_and_click_button("arcarum_exploring")
        elif ImageUtils.confirm_location("arcarum_departure_check"):
            MessageLog.print_message(
                f"[ARCARUM] Now using 1 Arcarum ticket to start this expedition..."
            )
            result_check = Game.find_and_click_button("start_expedition")
            Game.wait(6)
            return result_check
        elif Game.find_and_click_button("resume"):
            Game.wait(3)
            return True
        else:
            raise ArcarumException(
                "Failed to encounter the Departure Check to confirm starting the expedition."
            )
    def start(first_run: bool) -> int:
        """Starts the process to complete a run for Proving Grounds Farming Mode and returns the number of items detected.

        Args:
            first_run (bool): Flag that determines whether or not to run the navigation process again. Should be False if the Farming Mode supports the "Play Again" feature for repeated runs.

        Returns:
            (int): Number of runs completed.
        """
        from bot.game import Game

        runs_completed: int = 0

        # Start the navigation process.
        if first_run and ProvingGrounds._first_time:
            ProvingGrounds._navigate()
        elif ProvingGrounds._first_time and Game.find_and_click_button(
                "play_again"):
            MessageLog.print_message(
                "\n[PROVING.GROUNDS] Starting Proving Grounds Mission again..."
            )

        # Check for AP.
        Game.check_for_ap()

        # Check if the bot is at the Summon Selection screen.
        if (first_run
                or ProvingGrounds._first_time) and ImageUtils.confirm_location(
                    "proving_grounds_summon_selection", tries=30):
            summon_check = Game.select_summon(Settings.summon_list,
                                              Settings.summon_element_list)
            if summon_check:
                Game.wait(2.0)

                # No need to select a Party. Just click "OK" to start the mission and confirming the selected summon.
                Game.find_and_click_button("ok")

                Game.wait(2.0)

                MessageLog.print_message(
                    "\n[PROVING.GROUNDS] Now starting Mission for Proving Grounds..."
                )
                Game.find_and_click_button("proving_grounds_start")

                # Now start Combat Mode and detect any item drops.
                if CombatMode.start_combat_mode():
                    runs_completed = Game.collect_loot(is_completed=False)

                    # Click the "Next Battle" button if there are any battles left.
                    if Game.find_and_click_button(
                            "proving_grounds_next_battle"):
                        MessageLog.print_message(
                            "\n[PROVING.GROUNDS] Moving onto the next battle for Proving Grounds..."
                        )
                        Game.find_and_click_button("ok")
                        ProvingGrounds._first_time = False
        elif first_run is False and ProvingGrounds._first_time is False:
            # No need to select a Summon again as it is reused.
            if CombatMode.start_combat_mode():
                runs_completed = Game.collect_loot(is_completed=False)

                # Click the "Next Battle" button if there are any battles left.
                if Game.find_and_click_button("proving_grounds_next_battle"):
                    MessageLog.print_message(
                        "\n[PROVING.GROUNDS] Moving onto the next battle for Proving Grounds..."
                    )
                    Game.find_and_click_button("ok")
                else:
                    # Otherwise, all battles for the Mission has been completed. Collect the completion rewards at the end.
                    MessageLog.print_message(
                        "\n[PROVING.GROUNDS] Proving Grounds Mission has been completed."
                    )
                    Game.find_and_click_button("event")

                    # Check for friend request.
                    Game.find_and_click_button("cancel",
                                               tries=1,
                                               suppress_error=True)

                    # Check for trophy.
                    Game.find_and_click_button("close",
                                               tries=1,
                                               suppress_error=True)

                    Game.wait(2.0)
                    Game.find_and_click_button("proving_grounds_open_chest")

                    if ImageUtils.confirm_location(
                            "proving_grounds_completion_loot"):
                        MessageLog.print_message(
                            "\n[PROVING.GROUNDS] Completion rewards has been acquired."
                        )
                        runs_completed = Game.collect_loot(
                            is_completed=True, skip_popup_check=True)

                        # Reset the First Time flag so the bot can select a Summon and select the Mission again.
                        if Settings.item_amount_farmed < Settings.item_amount_to_farm:
                            ProvingGrounds._first_time = True
                    else:
                        raise ProvingGroundsException(
                            "Failed to detect the Completion Loot screen for completing this Proving Grounds mission."
                        )
        else:
            raise ProvingGroundsException(
                "Failed to arrive at the Summon Selection screen.")

        return runs_completed