diff --git a/resource/tasks.json b/resource/tasks.json index 9de9a065af..8ccbb76ce6 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -8125,7 +8125,7 @@ "postDelay": 100, "Doc": "pre 是将干员滑动到场上的 duration 系数;post 是设置干员朝向滑动的 duration", "specialParams": [ - 400, + 200, 2, 0, 100 diff --git a/src/MaaCore/Task/BattleHelper.cpp b/src/MaaCore/Task/BattleHelper.cpp index d848043e64..6b5fb012dd 100644 --- a/src/MaaCore/Task/BattleHelper.cpp +++ b/src/MaaCore/Task/BattleHelper.cpp @@ -287,7 +287,7 @@ bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc, Log.error("No loc", loc); return false; } - const Point& target_point = target_iter->second.pos; + Point target_point = target_iter->second.pos; int dist = static_cast( Point::distance(target_point, { oper_rect.x + oper_rect.width / 2, oper_rect.y + oper_rect.height / 2 })); @@ -307,18 +307,24 @@ bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc, // 拖动干员朝向 if (direction != DeployDirection::None) { static const std::unordered_map DirectionMap = { - { DeployDirection::Right, Point(1, 0) }, { DeployDirection::Down, Point(0, 1) }, - { DeployDirection::Left, Point(-1, 0) }, { DeployDirection::Up, Point(0, -1) }, - { DeployDirection::None, Point(0, 0) }, + { DeployDirection::Right, Point::right() }, { DeployDirection::Down, Point::down() }, + { DeployDirection::Left, Point::left() }, { DeployDirection::Up, Point::up() }, + { DeployDirection::None, Point::zero() }, }; // 计算往哪边拖动 const Point& direction_target = DirectionMap.at(direction); - // 将方向转换为实际的 swipe end 坐标点 - static const int coeff = swipe_oper_task_ptr->special_params.at(0); + // 将方向转换为实际的 swipe end 坐标点,并对滑动距离进行缩放 + static const auto scale_size = m_inst_helper.ctrler()->get_scale_size(); + static const int coeff = + static_cast(swipe_oper_task_ptr->special_params.at(0) * scale_size.second / 720.0); Point end_point = target_point + (direction_target * coeff); + // 经粗略测算,方向区域倾泻大概是 1/5 + const static auto radian = -std::atan(0.2); + fix_swipe_out_of_limit(target_point, end_point, scale_size.first, scale_size.second, radian); + m_inst_helper.sleep(use_oper_task_ptr->post_delay); m_inst_helper.ctrler()->swipe(target_point, end_point, swipe_oper_task_ptr->post_delay); m_inst_helper.sleep(use_oper_task_ptr->pre_delay); @@ -642,6 +648,52 @@ bool asst::BattleHelper::cancel_oper_selection() return ProcessTask(this_task(), { "BattleCancelSelection" }).run(); } +void asst::BattleHelper::fix_swipe_out_of_limit(Point& p1, Point& p2, int width, int height, double radian) +{ + Point direct = Point::zero(); + int distance = 0; + if (p2.y > height) { + // 下边界超限 + direct = Point::up(); + distance = p2.y - height; + } + else if (p2.x > width) { + // 右边界超限 + direct = Point::left(); + distance = p2.x - width; + } + else if (p2.y < 0) { + // 上边界超限 + direct = Point::down(); + distance = -p2.y; + } + else if (p2.x < 0) { + // 左边界超限 + direct = Point::right(); + distance = -p2.x; + } + else { + return; + } + + std::tuple adjust_scale = { + direct.x * std::cos(radian) + direct.y * std::sin(radian), + direct.y * std::cos(radian) - direct.x * std::sin(radian), + }; + + // 旋转后偏移值会不够,计算补偿比例 + double adjust_more = std::get<0>(adjust_scale) * direct.x + std::get<1>(adjust_scale) * direct.y; + + Point adjust = { + static_cast(std::get<0>(adjust_scale) / adjust_more * distance), + static_cast(std::get<1>(adjust_scale) / adjust_more * distance), + }; + + Log.info(__FUNCTION__, "swipe end_point out of limit, start:", p1, ", end:", p2, ", adjust:", adjust); + p1 += adjust; + p2 += adjust; +} + bool asst::BattleHelper::move_camera(const std::pair& delta) { LogTraceFunction; diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index 625ce3850e..186a2ba675 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -61,6 +61,8 @@ namespace asst bool click_retreat(); // 这个是不带识别的,直接点 bool click_skill(bool keep_waiting = true); // 这个是带识别的,转好了才点 bool cancel_oper_selection(); + // 修正终点超出范围的滑动,纠正时是否需要顺时针旋转 + void fix_swipe_out_of_limit(Point& p1, Point& p2, int width, int height, double radian = 0); bool move_camera(const std::pair& delta); std::string analyze_detail_page_oper_name(const cv::Mat& image);