diff --git a/3rdparty/include/Arknights-Tile-Pos/TileCalc2.hpp b/3rdparty/include/Arknights-Tile-Pos/TileCalc2.hpp index 9a69639e12..a12addaa5f 100644 --- a/3rdparty/include/Arknights-Tile-Pos/TileCalc2.hpp +++ b/3rdparty/include/Arknights-Tile-Pos/TileCalc2.hpp @@ -115,15 +115,15 @@ static constexpr double rel_pos_x = 1.3143386840820312; static constexpr double rel_pos_y = 1.314337134361267; static constexpr double rel_pos_z = -0.3967874050140381; -inline auto get_retreat_screen_pos(const Level& level) +inline auto get_retreat_screen_pos(const Level& level, bool has_multi_stages = false) { - const vec3d relative_pos = { -rel_pos_x + level.view[0].x, +rel_pos_y, rel_pos_z }; + const vec3d relative_pos = { -rel_pos_x + (has_multi_stages ? level.view[0].x : 0), +rel_pos_y, rel_pos_z }; return world_to_screen(level, relative_pos, true); } -inline auto get_skill_screen_pos(const Level& level) +inline auto get_skill_screen_pos(const Level& level, bool has_multi_stages = false) { - const vec3d relative_pos = { +rel_pos_x + level.view[0].x, -rel_pos_y, rel_pos_z }; + const vec3d relative_pos = { +rel_pos_x + (has_multi_stages ? level.view[0].x : 0), -rel_pos_y, rel_pos_z }; return world_to_screen(level, relative_pos, true); } diff --git a/src/MaaCore/Config/Miscellaneous/TilePack.cpp b/src/MaaCore/Config/Miscellaneous/TilePack.cpp index 1e2f0df5bf..532503bf85 100644 --- a/src/MaaCore/Config/Miscellaneous/TilePack.cpp +++ b/src/MaaCore/Config/Miscellaneous/TilePack.cpp @@ -105,14 +105,37 @@ asst::TilePack::result_type asst::TilePack::calc_(const Map::Level& level, doubl const bool ret = proc_data(result.normal_tile_info, loc, screen_pos, tile); const bool ret_side = proc_data(result.side_tile_info, loc, screen_pos_side, tile); + if (tile.tileKey == "tile_start" || tile.tileKey == "tile_end") { + // 检查 screen_pos 是否在允许的范围内(带5%容差) + constexpr double MIN_X = 0.0; + constexpr double MAX_X = 1280.0; + constexpr double MIN_Y = 0.0; + constexpr double MAX_Y = 720.0; + constexpr double TOLERANCE = 0.05; + + constexpr double x_tolerance = MAX_X * TOLERANCE; + constexpr double y_tolerance = MAX_Y * TOLERANCE; + + constexpr double min_x_bound = MIN_X - x_tolerance; + constexpr double max_x_bound = MAX_X + x_tolerance; + constexpr double min_y_bound = MIN_Y - y_tolerance; + constexpr double max_y_bound = MAX_Y + y_tolerance; + + if (screen_pos.x < min_x_bound || screen_pos.x > max_x_bound || screen_pos.y < min_y_bound || + screen_pos.y > max_y_bound) { + LogInfo << "Tile" << tile.tileKey << "at" << loc << ", screen position:" << screen_pos + << ", map has multi stages"; + result.has_multi_stages = true; + } + } if (!ret || !ret_side) { Log.info("Tiles calc error!"); return {}; } } } - auto retreat = Map::TileCalc2::get_retreat_screen_pos(level); - auto skill = Map::TileCalc2::get_skill_screen_pos(level); + auto retreat = Map::TileCalc2::get_retreat_screen_pos(level, result.has_multi_stages); + auto skill = Map::TileCalc2::get_skill_screen_pos(level, result.has_multi_stages); result.retreat_button = { retreat.x, retreat.y }; result.skill_button = { skill.x, skill.y }; diff --git a/src/MaaCore/Config/Miscellaneous/TilePack.h b/src/MaaCore/Config/Miscellaneous/TilePack.h index dd79227441..1101932559 100644 --- a/src/MaaCore/Config/Miscellaneous/TilePack.h +++ b/src/MaaCore/Config/Miscellaneous/TilePack.h @@ -60,6 +60,7 @@ public: std::unordered_map side_tile_info; Point retreat_button; Point skill_button; + bool has_multi_stages = false; }; public: diff --git a/src/MaaCore/Task/BattleHelper.cpp b/src/MaaCore/Task/BattleHelper.cpp index 4cfbeb84ab..92a0388ca9 100644 --- a/src/MaaCore/Task/BattleHelper.cpp +++ b/src/MaaCore/Task/BattleHelper.cpp @@ -74,6 +74,7 @@ bool asst::BattleHelper::calc_tiles_info(const std::string& stage_name, double s m_side_tile_info = std::move(calc_result.side_tile_info); m_retreat_button_pos = calc_result.retreat_button; m_skill_button_pos = calc_result.skill_button; + m_has_multi_stages = calc_result.has_multi_stages; return true; } @@ -335,7 +336,8 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable, b } // if side = true, get top view of the selected operator, tile size is 5x5 -cv::Mat asst::BattleHelper::get_top_view(const cv::Mat& cam_img, bool side) +// has_multi_stages: does map have multi stages, e.g. TN-1 ~ TN-4 +cv::Mat asst::BattleHelper::get_top_view(const cv::Mat& cam_img, bool side, bool has_multi_stages) { if (!side) { return cv::Mat {}; // TODO @@ -355,7 +357,7 @@ cv::Mat asst::BattleHelper::get_top_view(const cv::Mat& cam_img, bool side) }; std::vector screen_points; for (const auto& point : world_points) { - cv::Vec3d temp { point.x + m_map_data.view[0].x, -point.y, Map::TileCalc2::rel_pos_z }; + cv::Vec3d temp { point.x + (has_multi_stages ? m_map_data.view[0].x : 0), -point.y, Map::TileCalc2::rel_pos_z }; auto screen_pt = Map::TileCalc2::world_to_screen(m_map_data, temp, true); screen_points.push_back(screen_pt); } @@ -872,7 +874,7 @@ bool asst::BattleHelper::click_skill(bool keep_waiting) if (keep_waiting && retry > 0 && (retry % 10 == 0) && !check_in_battle(image)) { return false; } - top_view = get_top_view(image, true); + top_view = get_top_view(image, true, m_has_multi_stages); Matcher skill_analyzer { top_view }; skill_analyzer.set_task_info("BattleSkillReadyOnClick-TopView"); skill_analyzer.set_roi({ 250, 250, 250, 250 }); diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index ee84e3d0dd..955c8dd626 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -56,7 +56,7 @@ protected: bool update_kills(const cv::Mat& image, const cv::Mat& image_prev = cv::Mat()); bool update_cost(const cv::Mat& image, const cv::Mat& image_prev = cv::Mat()); - cv::Mat get_top_view(const cv::Mat& cam_img, bool side = true); + cv::Mat get_top_view(const cv::Mat& cam_img, bool side = true, bool has_multi_stages = false); bool deploy_oper(const std::string& name, const Point& loc, battle::DeployDirection direction); bool retreat_oper(const std::string& name); @@ -109,6 +109,7 @@ protected: std::unordered_map m_normal_tile_info; // 正常的坐标映射 Point m_skill_button_pos; Point m_retreat_button_pos; + bool m_has_multi_stages = false; std::unordered_map m_skill_usage; std::unordered_map m_skill_times; std::unordered_map m_skill_error_count;