diff --git a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp index cec6e827ca..2245d55684 100644 --- a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp @@ -348,6 +348,14 @@ bool asst::AutoRecruitTask::recruit_one(const Rect& button) return false; } + if (calc_result.for_special_tags_skip || calc_result.for_robot_tags_skip) { + // Mark the slot as completed and return + // without incrementing the count + m_force_skipped.emplace(slot_index_from_rect(button)); + click_return_button(); + return false; + } + if (calc_result.force_skip) { // mark the slot as completed and return m_force_skipped.emplace(slot_index_from_rect(button)); @@ -404,6 +412,21 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc continue; } +#ifdef ASST_DEBUG + // mock_test_001: 1/5/6 Star Operators appear when first recruited. + static bool RunRecruitMockTest_001 = true; + if (RunRecruitMockTest_001) { + static int skip_once = 0; + if (skip_once == 0) { + // image_analyzer.mock_set_special(asst::RecruitImageAnalyzer::operator_type::robot); + image_analyzer.mock_set_special(asst::RecruitImageAnalyzer::operator_type::senior); + // image_analyzer.mock_set_special(asst::RecruitImageAnalyzer::operator_type::top); + // image_analyzer.mock_set_special(asst::RecruitImageAnalyzer::operator_type::highvalue); + skip_once++; + } + } +#endif + const std::vector& tags = image_analyzer.get_tags_result(); m_has_refresh = !image_analyzer.get_refresh_rect().empty(); m_has_permit = image_analyzer.get_permit_rect().empty(); @@ -566,8 +589,8 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc } // refresh - if (m_need_refresh && m_has_refresh && !has_special_tag && - (final_combination.min_level == 3 && !has_preferred_tag) && !(m_skip_robot && has_robot_tag)) { + if (m_need_refresh && m_has_refresh && !has_special_tag && !(m_skip_robot && has_robot_tag) && + (final_combination.min_level == 3 && !has_preferred_tag)) { if (refresh_count > refresh_limit) [[unlikely]] { json::value cb_info = basic_info(); cb_info["what"] = "RecruitError"; @@ -615,26 +638,28 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc callback(AsstMsg::SubTaskExtraInfo, cb_info); Log.trace("No recruit permit"); - calc_task_result_type result; - result.success = true; - result.force_skip = true; + calc_task_result_type result(calc_task_result::no_permit); return result; } if (!is_calc_only_task()) { - // do not confirm, force skip - if (!(final_combination.min_level == 3 && has_preferred_tag) && - ranges::none_of(m_confirm_level, [&](const auto& i) { return i == final_combination.min_level; })) { - calc_task_result_type result; - result.success = true; - result.force_skip = true; + if (!(has_robot_tag || has_special_tag)) { + // do not confirm, force skip + if (!(final_combination.min_level == 3 && has_preferred_tag) && + is_recruitment_level_invalid(final_combination.min_level)) { + calc_task_result_type result(calc_task_result::force_skip); + return result; + } + } + + // "Automatically recruit 5/6 Star operators" is not checked. + if (has_special_tag && is_recruitment_level_invalid(final_combination.min_level)) { + calc_task_result_type result(calc_task_result::special_tag_skip); return result; } - if (m_skip_robot && has_robot_tag) { - calc_task_result_type result; - result.success = true; - result.force_skip = true; + if (has_robot_tag && m_skip_robot) { + calc_task_result_type result(calc_task_result::robot_tag_skip); return result; } } @@ -662,12 +687,8 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc // nothing to select, leave the selection empty if (!(final_combination.min_level == 3 && has_preferred_tag) && - ranges::none_of(m_select_level, [&](const auto& i) { return i == final_combination.min_level; })) { - calc_task_result_type result; - result.success = true; - result.force_skip = false; - result.recruitment_time = recruitment_time; - result.tags_selected = 0; + is_recruitment_level_invalid(final_combination.min_level)) { + calc_task_result_type result(calc_task_result::nothing_to_select, recruitment_time); return result; } @@ -689,11 +710,10 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc callback(AsstMsg::SubTaskExtraInfo, cb_info); } - calc_task_result_type result; - result.success = true; - result.force_skip = false; - result.recruitment_time = recruitment_time; - result.tags_selected = static_cast(final_combination.tags.size()); + calc_task_result_type result( + calc_task_result::success, + recruitment_time, + static_cast(final_combination.tags.size())); return result; } diff --git a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h index 01ce28e9db..505eb9adc8 100644 --- a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h +++ b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h @@ -8,6 +8,8 @@ #include "Common/AsstTypes.h" #include "Config/Miscellaneous/RecruitConfig.h" +#include + namespace asst { class ReportDataTask; @@ -66,14 +68,83 @@ protected: using slot_index = size_t; + enum calc_task_result + { + init = 0, + no_permit = 1, + force_skip = 2, + special_tag_skip = 3, + nothing_to_select = 4, + success = 5, + robot_tag_skip = 6 + }; + struct calc_task_result_type { bool success = false; bool force_skip = false; + bool for_special_tags_skip = false; // Get the definition by searching for "SpecialTags". + bool for_robot_tags_skip = false; int recruitment_time = 60; [[maybe_unused]] int tags_selected = 0; + + calc_task_result_type(calc_task_result res, const int _recruitment_time = 60, const int _tag_selected = 0) + { + switch (res) { + case calc_task_result::init: + success = false; + force_skip = false; + for_special_tags_skip = false; + for_robot_tags_skip = false; + recruitment_time = _recruitment_time; + tags_selected = _tag_selected; + break; + case calc_task_result::special_tag_skip: + success = true; + force_skip = true; + for_special_tags_skip = true; + for_robot_tags_skip = false; + recruitment_time = _recruitment_time; + tags_selected = _tag_selected; + break; + case calc_task_result::no_permit: + case calc_task_result::force_skip: + success = true; + force_skip = true; + for_special_tags_skip = false; + for_robot_tags_skip = false; + recruitment_time = _recruitment_time; + tags_selected = _tag_selected; + break; + case calc_task_result::nothing_to_select: + case calc_task_result::success: + success = true; + force_skip = false; + for_special_tags_skip = false; + for_robot_tags_skip = false; + recruitment_time = _recruitment_time; + tags_selected = _tag_selected; + break; + case calc_task_result::robot_tag_skip: + success = true; + force_skip = true; + for_special_tags_skip = false; + for_robot_tags_skip = true; + recruitment_time = _recruitment_time; + tags_selected = _tag_selected; + break; + } + }; + + calc_task_result_type() : + calc_task_result_type(init) {}; }; + bool is_recruitment_level_invalid(int opr_level) + { + return std::ranges::none_of(this->m_confirm_level, [&](const int& i) { return i == opr_level; }); + } + calc_task_result_type recruit_calc_task(slot_index = 0); std::vector m_select_level; diff --git a/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h index 6110c84109..ad7df810a0 100644 --- a/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h @@ -24,6 +24,34 @@ public: Rect get_permit_rect() const noexcept { return m_permit_rect; } +#ifdef ASST_DEBUG + // mock function + enum operator_type + { + top = 6, + senior = 5, + robot = 1, + highvalue = 11 + }; + + void mock_set_special(operator_type type) + { + if (type == top) { + m_tags_result[0].text = "高级资深干员"; + } + if (type == senior) { + m_tags_result[0].text = "资深干员"; + } + if (type == robot) { + m_tags_result[0].text = "支援机械"; + } + if (type == highvalue) { + m_tags_result[0].text = "资深干员"; + m_tags_result[1].text = "高级资深干员"; + } + } +#endif // ASST_DEBUG + private: // 该分析器不支持外部设置ROI using VisionHelper::set_roi;