Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/

#include "Common/Cpp/Exceptions.h"
#include "CommonFramework/GlobalAutoPaths.h"
#include "CommonFramework/ImageTypes/ImageRGB32.h"
#include "CommonTools/ImageMatch/WaterfillTemplateMatcher.h"
#include "CommonTools/Images/WaterfillUtilities.h"
#include "VideoGames/PokemonFRLG/PokemonFRLG_Settings.h"
Expand Down Expand Up @@ -65,6 +67,21 @@ ImageFloatBox BattleSelectionArrowDetector::box_for_option(SafariBattleMenuOptio
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid FRLG Safari Battle Menu Option");
}
ImageFloatBox BattleSelectionArrowDetector::box_for_option(BattleMoveOption option){
switch (option){
case BattleMoveOption::MOVE_1:
return ImageFloatBox(0.028, 0.765, 0.040, 0.080);
case BattleMoveOption::MOVE_2:
return ImageFloatBox(0.328, 0.765, 0.040, 0.080);
case BattleMoveOption::MOVE_3:
return ImageFloatBox(0.028, 0.865, 0.040, 0.080);
case BattleMoveOption::MOVE_4:
return ImageFloatBox(0.328, 0.865, 0.040, 0.080);
default:
break;
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid FRLG Battle Move Option");
}
ImageFloatBox BattleSelectionArrowDetector::box_for_option(BattleConfirmationOption option){
switch (option){
case BattleConfirmationOption::YES:
Expand Down Expand Up @@ -104,6 +121,15 @@ BattleSelectionArrowDetector::BattleSelectionArrowDetector(
, m_overlay(overlay)
, m_arrow_box(box_for_option(option))
{}
BattleSelectionArrowDetector::BattleSelectionArrowDetector(
Color color,
VideoOverlay* overlay,
BattleMoveOption option
)
: m_color(color)
, m_overlay(overlay)
, m_arrow_box(box_for_option(option))
{}
BattleSelectionArrowDetector::BattleSelectionArrowDetector(
Color color,
VideoOverlay* overlay
Expand Down Expand Up @@ -166,6 +192,57 @@ bool BattleSelectionArrowDetector::detect(const ImageViewRGB32& screen){
}



// Each image shows the FIGHT move list with the arrow on one move. The arrow
// must be found in that move's box and in none of the other three. Searching
// the whole move list (as the cursor navigation does) must also find it in
// the right place, not on the move names.
class Test_BattleMoveSelectionArrow : public UnitTest{
public:
Test_BattleMoveSelectionArrow(
const std::string& image,
BattleMoveOption expected
)
: UnitTest("PokemonFRLG::BattleMoveSelectionArrow - " + image)
, m_image(UNIT_TEST_RESOURCE_PATH() + image)
, m_expected(expected)
{}

virtual UnitTestResult run(Logger& logger, CancellableScope& scope) const override{
ImageRGB32 image(m_image);
for (int i = 0; i < BATTLE_MOVE_OPTION_COUNT; i++){
BattleMoveOption option = static_cast<BattleMoveOption>(i);
BattleSelectionArrowDetector detector(COLOR_RED, nullptr, option);
if (detector.detect(image) != (option == m_expected)){
return false;
}
}

BattleSelectionArrowDetector whole_list(COLOR_RED, nullptr, BATTLE_MOVE_ARROW_BOX);
if (!whole_list.detect(image)){
return false;
}
const ImageFloatBox& found = whole_list.last_detected();
const ImageFloatBox expected = BattleSelectionArrowDetector::box_for_option(m_expected);
double cx = found.x + found.width / 2;
double cy = found.y + found.height / 2;
return expected.x <= cx && cx <= expected.x + expected.width
&& expected.y <= cy && cy <= expected.y + expected.height;
};

private:
std::string m_image;
BattleMoveOption m_expected;
};

void add_tests_BattleMoveSelectionArrow(UnitTestDatabase& database){
database.add<Test_BattleMoveSelectionArrow>("PokemonFRLG/BattleMoveSelectionArrow/MoveArrow-TopLeft.png", BattleMoveOption::MOVE_1);
database.add<Test_BattleMoveSelectionArrow>("PokemonFRLG/BattleMoveSelectionArrow/MoveArrow-TopRight.png", BattleMoveOption::MOVE_2);
database.add<Test_BattleMoveSelectionArrow>("PokemonFRLG/BattleMoveSelectionArrow/MoveArrow-BottomLeft.png", BattleMoveOption::MOVE_3);
database.add<Test_BattleMoveSelectionArrow>("PokemonFRLG/BattleMoveSelectionArrow/MoveArrow-BottomRight.png", BattleMoveOption::MOVE_4);
}


}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef PokemonAutomation_PokemonFRLG_BattleSelectionArrowDetector_H
#define PokemonAutomation_PokemonFRLG_BattleSelectionArrowDetector_H

#include "Common/Cpp/TestRunners/UnitTestDatabase.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "CommonTools/VisualDetector.h"

Expand All @@ -32,12 +33,22 @@ enum class SafariBattleMenuOption{
RUN,
};

// The four moves in the FIGHT move list, in the same row-major order.
const int BATTLE_MOVE_OPTION_COUNT = 4;
enum class BattleMoveOption{
MOVE_1, // top left
MOVE_2, // top right
MOVE_3, // bottom left
MOVE_4, // bottom right
};

enum class BattleConfirmationOption{
YES,
NO,
};

const ImageFloatBox BATTLE_MENU_ARROW_BOX(0.525, 0.741, 0.273, 0.212);
const ImageFloatBox BATTLE_MOVE_ARROW_BOX(0.025, 0.741, 0.373, 0.212);

class BattleSelectionArrowDetector : public StaticScreenDetector{
public:
Expand All @@ -56,6 +67,11 @@ class BattleSelectionArrowDetector : public StaticScreenDetector{
VideoOverlay* overlay,
SafariBattleMenuOption option
);
BattleSelectionArrowDetector(
Color color,
VideoOverlay* overlay,
BattleMoveOption option
);
BattleSelectionArrowDetector(
Color color,
VideoOverlay* overlay
Expand All @@ -68,6 +84,7 @@ class BattleSelectionArrowDetector : public StaticScreenDetector{

static ImageFloatBox box_for_option(BattleMenuOption option);
static ImageFloatBox box_for_option(SafariBattleMenuOption option);
static ImageFloatBox box_for_option(BattleMoveOption option);
static ImageFloatBox box_for_option(BattleConfirmationOption option);

const ImageFloatBox& last_detected() const { return m_last_detected; }
Expand Down Expand Up @@ -113,6 +130,14 @@ class BattleSelectionArrowWatcher : public DetectorToFinder<BattleSelectionArrow
)
: DetectorToFinder("BattleSelectionArrowWatcher", hold_duration, color, overlay, box_for_option(option))
{}
BattleSelectionArrowWatcher(
Color color,
VideoOverlay* overlay,
BattleMoveOption option,
std::chrono::milliseconds hold_duration = std::chrono::milliseconds(250)
)
: DetectorToFinder("BattleSelectionArrowWatcher", hold_duration, color, overlay, box_for_option(option))
{}
BattleSelectionArrowWatcher(
Color color,
VideoOverlay* overlay,
Expand All @@ -131,6 +156,9 @@ class BattleSelectionArrowWatcher : public DetectorToFinder<BattleSelectionArrow
};


void add_tests_BattleMoveSelectionArrow(UnitTestDatabase& database);


}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Inference/Map/PokemonFRLG_PokemonLeagueDetectors.h"
#include "Inference/Menus/PokemonFRLG_PartyMenuDetector.h"
#include "Inference/PokemonFRLG_BattleLevelUpReader.h"
#include "Inference/PokemonFRLG_BattleSelectionArrowDetector.h"
#include "Inference/PokemonFRLG_PartyLevelUpReader.h"
#include "Inference/PokemonFRLG_ShinySymbolDetector.h"
#include "Inference/PokemonFRLG_StatsReader.h"
Expand Down Expand Up @@ -44,6 +45,7 @@ void add_tests(UnitTestDatabase& database){
add_tests_PartySlotDetector(database);
add_tests_EliteFourRoomDetector(database);
add_tests_HallOfFameSavingDetector(database);
add_tests_BattleMoveSelectionArrow(database);
}


Expand Down
Loading
Loading