Skip to content

Commit 52f8e86

Browse files
authored
update Autostory tools. added UnexpectedBattleException. (#493)
* update Autostory tools. added UnexpectedBattleException. add battle detection for functions that need to detect overworld * fix build * fix build * fix catch declaration
1 parent 4714ba0 commit 52f8e86

File tree

10 files changed

+867
-95
lines changed

10 files changed

+867
-95
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ file(GLOB MAIN_SOURCES
313313
Source/CommonFramework/Exceptions/ProgramFinishedException.h
314314
Source/CommonFramework/Exceptions/ScreenshotException.cpp
315315
Source/CommonFramework/Exceptions/ScreenshotException.h
316+
Source/CommonFramework/Exceptions/UnexpectedBattleException.cpp
317+
Source/CommonFramework/Exceptions/UnexpectedBattleException.h
316318
Source/CommonFramework/GlobalServices.cpp
317319
Source/CommonFramework/GlobalServices.h
318320
Source/CommonFramework/GlobalSettingsPanel.cpp

SerialPrograms/SerialPrograms.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ SOURCES += \
182182
Source/CommonFramework/Exceptions/OperationFailedException.cpp \
183183
Source/CommonFramework/Exceptions/ProgramFinishedException.cpp \
184184
Source/CommonFramework/Exceptions/ScreenshotException.cpp \
185+
Source/CommonFramework/Exceptions/UnexpectedBattleException.cpp \
185186
Source/CommonFramework/GlobalServices.cpp \
186187
Source/CommonFramework/GlobalSettingsPanel.cpp \
187188
Source/CommonFramework/Globals.cpp \
@@ -1230,6 +1231,7 @@ HEADERS += \
12301231
Source/CommonFramework/Exceptions/OperationFailedException.h \
12311232
Source/CommonFramework/Exceptions/ProgramFinishedException.h \
12321233
Source/CommonFramework/Exceptions/ScreenshotException.h \
1234+
Source/CommonFramework/Exceptions/UnexpectedBattleException.h \
12331235
Source/CommonFramework/GlobalServices.h \
12341236
Source/CommonFramework/GlobalSettingsPanel.h \
12351237
Source/CommonFramework/Globals.h \
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* Unexpected Battle Exception
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#include "CommonFramework/ImageTypes/ImageRGB32.h"
8+
#include "CommonFramework/Notifications/ProgramNotifications.h"
9+
#include "CommonFramework/Tools/ErrorDumper.h"
10+
#include "CommonFramework/Tools/ProgramEnvironment.h"
11+
#include "CommonFramework/Tools/ConsoleHandle.h"
12+
#include "UnexpectedBattleException.h"
13+
14+
namespace PokemonAutomation{
15+
16+
17+
UnexpectedBattleException::UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message)
18+
: ScreenshotException(error_report, std::move(message))
19+
{
20+
logger.log(std::string(UnexpectedBattleException::name()) + ": " + m_message, COLOR_RED);
21+
}
22+
UnexpectedBattleException::UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message, std::shared_ptr<const ImageRGB32> screenshot)
23+
: ScreenshotException(error_report, std::move(message), std::move(screenshot))
24+
{
25+
logger.log(std::string(UnexpectedBattleException::name()) + ": " + m_message, COLOR_RED);
26+
}
27+
UnexpectedBattleException::UnexpectedBattleException(ErrorReport error_report, ConsoleHandle& console, std::string message, bool take_screenshot)
28+
: ScreenshotException(error_report, console, std::move(message), take_screenshot)
29+
{
30+
console.log(std::string(UnexpectedBattleException::name()) + ": " + m_message, COLOR_RED);
31+
}
32+
33+
34+
void UnexpectedBattleException::send_notification(ProgramEnvironment& env, EventNotificationOption& notification) const{
35+
std::vector<std::pair<std::string, std::string>> embeds;
36+
if (!m_message.empty()){
37+
embeds.emplace_back(std::pair<std::string, std::string>("Message:", m_message));
38+
}
39+
if (m_send_error_report == ErrorReport::SEND_ERROR_REPORT && m_screenshot){
40+
std::string label = name();
41+
std::string filename = dump_image_alone(env.logger(), env.program_info(), label, *m_screenshot);
42+
send_program_telemetry(
43+
env.logger(), true, COLOR_RED,
44+
env.program_info(),
45+
label,
46+
embeds,
47+
filename
48+
);
49+
}
50+
send_program_notification(
51+
env, notification,
52+
COLOR_RED,
53+
"Program Error",
54+
std::move(embeds), "",
55+
screenshot()
56+
);
57+
}
58+
59+
60+
61+
62+
63+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* Unexpected Battle Exception
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_UnexpectedBattleException_H
8+
#define PokemonAutomation_UnexpectedBattleException_H
9+
10+
#include <memory>
11+
#include "ScreenshotException.h"
12+
13+
namespace PokemonAutomation{
14+
15+
class FatalProgramException;
16+
17+
18+
// Thrown by subroutines if caught in an wild battle in-game unexpectedly.
19+
// These include recoverable errors which can be consumed by the program.
20+
class UnexpectedBattleException : public ScreenshotException{
21+
public:
22+
explicit UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message);
23+
explicit UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message, std::shared_ptr<const ImageRGB32> screenshot);
24+
explicit UnexpectedBattleException(ErrorReport error_report, ConsoleHandle& console, std::string message, bool take_screenshot);
25+
26+
virtual const char* name() const override{ return "UnexpectedBattleException"; }
27+
virtual std::string message() const override{ return m_message; }
28+
29+
virtual void send_notification(ProgramEnvironment& env, EventNotificationOption& notification) const override;
30+
};
31+
32+
33+
34+
35+
36+
}
37+
#endif

SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,32 @@ class DestinationMarkerMatcher : public ImageMatch::WaterfillTemplateMatcher{
3939
}
4040
};
4141

42+
class DestinationMarkerYellowMatcher : public ImageMatch::WaterfillTemplateMatcher{
43+
public:
44+
45+
DestinationMarkerYellowMatcher() : WaterfillTemplateMatcher(
46+
"PokemonSV/Map/DestinationMarkerIcon-Yellow.png", Color(180,80,0), Color(255, 200, 50), 50
47+
){
48+
m_aspect_ratio_lower = 0.8;
49+
m_aspect_ratio_upper = 1.2;
50+
m_area_ratio_lower = 0.8;
51+
m_area_ratio_upper = 1.2;
52+
53+
}
54+
55+
static const ImageMatch::WaterfillTemplateMatcher& instance(){
56+
static DestinationMarkerYellowMatcher matcher;
57+
return matcher;
58+
}
59+
};
60+
4261

4362
DestinationMarkerDetector::~DestinationMarkerDetector() = default;
4463

45-
DestinationMarkerDetector::DestinationMarkerDetector(Color color, const ImageFloatBox& box)
64+
DestinationMarkerDetector::DestinationMarkerDetector(Color color, const ImageFloatBox& box, bool check_yellow)
4665
: m_color(color)
4766
, m_box(box)
67+
, m_check_yellow(check_yellow)
4868
{}
4969

5070
void DestinationMarkerDetector::make_overlays(VideoOverlaySet& items) const{
@@ -53,7 +73,12 @@ void DestinationMarkerDetector::make_overlays(VideoOverlaySet& items) const{
5373

5474
bool DestinationMarkerDetector::detect(const ImageViewRGB32& screen) const{
5575
std::vector<ImageFloatBox> hits = detect_all(screen);
56-
return !hits.empty();
76+
if (!m_check_yellow){
77+
return !hits.empty();
78+
}else{
79+
std::vector<ImageFloatBox> hits_yellow = detect_all_yellow(screen);
80+
return !hits.empty() || !hits_yellow.empty();
81+
}
5782
}
5883

5984
std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all(const ImageViewRGB32& screen) const{
@@ -64,7 +89,6 @@ std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all(const ImageView
6489

6590

6691
const double rmsd_threshold = 80.0; // from my testing: RMSD is 15 at 1080p, 60 at 720p
67-
6892
const double min_object_size = 150.0;
6993

7094
const double screen_rel_size = (screen.height() / 1080.0);
@@ -93,6 +117,48 @@ std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all(const ImageView
93117

94118

95119

120+
std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all_yellow(const ImageViewRGB32& screen) const{
121+
const std::vector<std::pair<uint32_t, uint32_t>> filters = {
122+
{combine_rgb(180, 100, 0), combine_rgb(255, 190, 50)}, // to detect the marker within the minimap, when the radar beam is covering the marker
123+
};
124+
125+
126+
const double rmsd_threshold = 80.0; // from my testing, RMSD ranges from 15-50, even at 720p
127+
/*
128+
- min object size restrictions also helps to filter out false positives
129+
at pokemon centers
130+
*/
131+
const double min_object_size = 150.0;
132+
133+
const double screen_rel_size = (screen.height() / 1080.0);
134+
const size_t min_size = size_t(screen_rel_size * screen_rel_size * min_object_size);
135+
136+
std::vector<ImageFloatBox> found_locations;
137+
138+
ImagePixelBox pixel_search_area = floatbox_to_pixelbox(screen.width(), screen.height(), m_box);
139+
match_template_by_waterfill(
140+
extract_box_reference(screen, m_box),
141+
DestinationMarkerYellowMatcher::instance(),
142+
filters,
143+
{min_size, SIZE_MAX},
144+
rmsd_threshold,
145+
[&](Kernels::Waterfill::WaterfillObject& object) -> bool {
146+
ImagePixelBox found_box(
147+
object.min_x + pixel_search_area.min_x, object.min_y + pixel_search_area.min_y,
148+
object.max_x + pixel_search_area.min_x, object.max_y + pixel_search_area.min_y);
149+
found_locations.emplace_back(pixelbox_to_floatbox(screen.width(), screen.height(), found_box));
150+
return true;
151+
}
152+
);
153+
154+
return found_locations;
155+
}
156+
157+
158+
159+
160+
161+
96162
}
97163
}
98164
}

SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,22 @@ namespace PokemonSV{
2525

2626
class DestinationMarkerDetector : public StaticScreenDetector{
2727
public:
28-
DestinationMarkerDetector(Color color, const ImageFloatBox& box);
28+
DestinationMarkerDetector(Color color, const ImageFloatBox& box, bool check_yellow);
2929
virtual ~DestinationMarkerDetector();
3030

3131
virtual void make_overlays(VideoOverlaySet& items) const override;
3232
virtual bool detect(const ImageViewRGB32& screen) const override;
3333

3434
std::vector<ImageFloatBox> detect_all(const ImageViewRGB32& screen) const;
3535

36+
// for detecting the marker within the minimap
37+
// ImageFloatBox for detecting within the minimap {0.815, 0.645, 0.180, 0.320}. needs to be slightly higher up than the minimap since the marker will stick up past the minimap
38+
std::vector<ImageFloatBox> detect_all_yellow(const ImageViewRGB32& screen) const;
39+
3640
protected:
3741
Color m_color;
3842
ImageFloatBox m_box;
43+
bool m_check_yellow;
3944
};
4045

4146

@@ -45,9 +50,10 @@ class DestinationMarkerWatcher : public DetectorToFinder<DestinationMarkerDetect
4550
DestinationMarkerWatcher(
4651
Color color,
4752
const ImageFloatBox& box,
53+
bool check_yellow = false,
4854
std::chrono::milliseconds duration = std::chrono::milliseconds(250)
4955
)
50-
: DetectorToFinder("DestinationMarkerWatcher", std::chrono::milliseconds(250), color, box)
56+
: DetectorToFinder("DestinationMarkerWatcher", std::chrono::milliseconds(250), color, box, check_yellow)
5157
{}
5258
};
5359

0 commit comments

Comments
 (0)