mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-15 17:30:27 +08:00
feat: 合并 处于战斗中 检测, 增加倍速记忆, 支持战斗中 不带跳过按钮的 带头像对话教程 (#15706)
* rft: 合并 处于战斗中 检测, 增加倍速记忆 * feat: 支持战斗中 不带跳过按钮的 带头像对话教程 * perf: 增加重试次数上限 * perf: 2倍速检查一致化
This commit is contained in:
@@ -3577,6 +3577,13 @@
|
||||
"template": "SkipThePreBattlePlotConfirm.png",
|
||||
"next": ["EndOfPlot"]
|
||||
},
|
||||
"BattleAvatarDialog": {
|
||||
"doc": "战斗中带头像对话框, 类似于 SkipThePreBattlePlot(可见于画中人关卡) 的, 但是缺少 跳过 按钮",
|
||||
"action": "ClickSelf",
|
||||
"roi": [70, 30, 120, 30],
|
||||
"next": ["BattleAvatarDialog", "Stop"],
|
||||
"rectMove": [125, 20, 200, 60]
|
||||
},
|
||||
"EndOfPlot": {
|
||||
"roi": [520, 0, 243, 206],
|
||||
"action": "ClickRect",
|
||||
|
||||
BIN
resource/template/Battle/Plot/BattleAvatarDialog.png
Normal file
BIN
resource/template/Battle/Plot/BattleAvatarDialog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -618,7 +618,20 @@ bool asst::BattleHelper::check_skip_plot_button(const cv::Mat& reusable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::check_in_speed_up(const cv::Mat& reusable)
|
||||
bool asst::BattleHelper::check_avatar_dialog(const cv::Mat& reusable)
|
||||
{
|
||||
cv::Mat image = reusable.empty() ? m_inst_helper.ctrler()->get_image() : reusable;
|
||||
|
||||
Matcher battle_plot_analyzer(image);
|
||||
battle_plot_analyzer.set_task_info("BattleAvatarDialog");
|
||||
bool ret = battle_plot_analyzer.analyze().has_value();
|
||||
if (ret) {
|
||||
ProcessTask(this_task(), { "BattleAvatarDialog" }).run();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::check_in_speedup(const cv::Mat& reusable)
|
||||
{
|
||||
cv::Mat image = reusable.empty() ? m_inst_helper.ctrler()->get_image() : reusable;
|
||||
Matcher analyzer(image);
|
||||
@@ -631,7 +644,27 @@ bool asst::BattleHelper::check_in_battle(const cv::Mat& reusable, bool weak)
|
||||
cv::Mat image = reusable.empty() ? m_inst_helper.ctrler()->get_image() : reusable;
|
||||
if (weak) {
|
||||
BattlefieldMatcher analyzer(image);
|
||||
m_in_battle = analyzer.analyze().has_value();
|
||||
auto result = analyzer.analyze();
|
||||
m_in_battle = result.has_value();
|
||||
if (m_in_battle && !result->pause_button) {
|
||||
if (check_skip_plot_button(image)) {
|
||||
if (m_in_speedup && !check_in_speedup()) {
|
||||
speed_up(); // 跳过剧情会退出2倍速
|
||||
}
|
||||
}
|
||||
else if (check_avatar_dialog(image)) {
|
||||
if (m_in_speedup && !check_in_speedup()) {
|
||||
speed_up(); // 跳过剧情会退出2倍速
|
||||
m_inst_helper.sleep(Config.get_options().task_delay);
|
||||
int times = 0;
|
||||
while (times < 20 && !m_inst_helper.need_exit() && !check_in_speedup()) {
|
||||
speed_up(); // 跳过剧情会退出2倍速
|
||||
m_inst_helper.sleep(Config.get_options().task_delay);
|
||||
times++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
check_skip_plot_button(image);
|
||||
|
||||
@@ -67,7 +67,10 @@ protected:
|
||||
bool use_skill(const Point& loc, bool keep_waiting = true);
|
||||
bool check_pause_button(const cv::Mat& reusable = cv::Mat());
|
||||
bool check_skip_plot_button(const cv::Mat& reusable = cv::Mat());
|
||||
bool check_in_speed_up(const cv::Mat& reusable = cv::Mat());
|
||||
// 检查是否有战斗中带头像的对话框
|
||||
bool check_avatar_dialog(const cv::Mat& reusable = cv::Mat());
|
||||
// 检查是否处于二倍速
|
||||
bool check_in_speedup(const cv::Mat& reusable = cv::Mat());
|
||||
virtual bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true);
|
||||
virtual bool wait_until_start(bool weak = true);
|
||||
bool wait_until_end(bool weak = true);
|
||||
@@ -115,6 +118,7 @@ protected:
|
||||
std::unordered_map<std::string, int> m_skill_error_count;
|
||||
std::unordered_map<std::string, std::chrono::steady_clock::time_point> m_last_use_skill_time;
|
||||
int m_camera_count = 0;
|
||||
bool m_in_speedup = false; // 是否处于2倍速
|
||||
std::pair<double, double> m_camera_shift = { 0., 0. };
|
||||
|
||||
/* 实时更新的数据 */
|
||||
|
||||
@@ -238,6 +238,9 @@ bool asst::BattleProcessTask::do_action(const battle::copilot::Action& action, s
|
||||
|
||||
case ActionType::SwitchSpeed:
|
||||
ret = speed_up();
|
||||
if (ret) {
|
||||
m_in_speedup = !m_in_speedup;
|
||||
}
|
||||
break;
|
||||
|
||||
case ActionType::BulletTime:
|
||||
@@ -480,31 +483,12 @@ void asst::BattleProcessTask::sleep_and_do_strategy(unsigned millisecond)
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
const auto delay = millisecond * 1ms;
|
||||
|
||||
while (!need_exit() && std::chrono::steady_clock::now() - start < delay) {
|
||||
do_strategic_action();
|
||||
|
||||
cv::Mat image = ctrler()->get_image();
|
||||
while (!need_exit() && check_in_battle(image) && std::chrono::steady_clock::now() - start < delay) {
|
||||
do_strategic_action(image);
|
||||
std::this_thread::yield();
|
||||
|
||||
image = ctrler()->get_image();
|
||||
}
|
||||
}
|
||||
|
||||
bool asst::BattleProcessTask::check_in_battle(const cv::Mat& reusable, bool weak)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable;
|
||||
|
||||
if (weak) {
|
||||
BattlefieldMatcher analyzer(image);
|
||||
auto result = analyzer.analyze();
|
||||
m_in_battle = result.has_value();
|
||||
if (m_in_battle && !result->pause_button) {
|
||||
if (check_skip_plot_button(image) && check_in_speed_up(image)) {
|
||||
speed_up();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
check_skip_plot_button(image);
|
||||
m_in_battle = check_pause_button(image);
|
||||
}
|
||||
return m_in_battle;
|
||||
}
|
||||
|
||||
@@ -44,8 +44,6 @@ protected:
|
||||
bool enter_bullet_time(const std::string& name, const Point& location);
|
||||
void sleep_and_do_strategy(unsigned millisecond);
|
||||
|
||||
virtual bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true) override;
|
||||
|
||||
battle::copilot::CombatData m_combat_data;
|
||||
std::unordered_map</*group*/ std::string, /*oper*/ std::string> m_oper_in_group;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user