mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-18 18:20:39 +08:00
feat: 自动检测地图是否为多阶段地图, 判断是否需要使用 view[0].x 修正镜头 (#15371)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
std::unordered_map<Point, TileInfo> side_tile_info;
|
||||
Point retreat_button;
|
||||
Point skill_button;
|
||||
bool has_multi_stages = false;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@@ -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<cv::Point2f> 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 });
|
||||
|
||||
@@ -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<Point, TilePack::TileInfo> m_normal_tile_info; // 正常的坐标映射
|
||||
Point m_skill_button_pos;
|
||||
Point m_retreat_button_pos;
|
||||
bool m_has_multi_stages = false;
|
||||
std::unordered_map<std::string, battle::SkillUsage> m_skill_usage;
|
||||
std::unordered_map<std::string, int> m_skill_times;
|
||||
std::unordered_map<std::string, int> m_skill_error_count;
|
||||
|
||||
Reference in New Issue
Block a user