feat: calculate position of skill & retreat button

This commit is contained in:
Horror Proton
2024-03-14 23:05:15 +08:00
parent 2c31929bb9
commit 34bf1cfd9d
7 changed files with 362 additions and 132 deletions

View File

@@ -19,7 +19,10 @@
using namespace asst::battle;
asst::BattleHelper::BattleHelper(Assistant* inst) : m_inst_helper(inst) {}
asst::BattleHelper::BattleHelper(Assistant* inst)
: m_inst_helper(inst)
{
}
bool asst::BattleHelper::set_stage_name(const std::string& name)
{
@@ -50,7 +53,10 @@ void asst::BattleHelper::clear()
m_used_tiles.clear();
}
bool asst::BattleHelper::calc_tiles_info(const std::string& stage_name, double shift_x, double shift_y)
bool asst::BattleHelper::calc_tiles_info(
const std::string& stage_name,
double shift_x,
double shift_y)
{
LogTraceFunction;
@@ -58,8 +64,11 @@ bool asst::BattleHelper::calc_tiles_info(const std::string& stage_name, double s
return false;
}
m_normal_tile_info = Tile.calc(stage_name, false, shift_x, shift_y);
m_side_tile_info = Tile.calc(stage_name, true, shift_x, shift_y);
auto calc_result = Tile.calc(stage_name, shift_x, shift_y);
m_normal_tile_info = std::move(calc_result.normal_tile_info);
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;
return true;
}
@@ -144,12 +153,15 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable)
Log.trace("start matching cooling", oper.index);
static const double cooling_threshold =
Task.get<MatchTaskInfo>("BattleAvatarCoolingData")->templ_thresholds.front();
static const auto cooling_mask_range = Task.get<MatchTaskInfo>("BattleAvatarCoolingData")->mask_range;
static const auto cooling_mask_range =
Task.get<MatchTaskInfo>("BattleAvatarCoolingData")->mask_range;
avatar_analyzer.set_threshold(cooling_threshold);
avatar_analyzer.set_mask_range(cooling_mask_range.first, cooling_mask_range.second, true, true);
avatar_analyzer
.set_mask_range(cooling_mask_range.first, cooling_mask_range.second, true, true);
}
else {
static const double threshold = Task.get<MatchTaskInfo>("BattleAvatarData")->templ_thresholds.front();
static const double threshold =
Task.get<MatchTaskInfo>("BattleAvatarData")->templ_thresholds.front();
static const double drone_threshold =
Task.get<MatchTaskInfo>("BattleDroneAvatarData")->templ_thresholds.front();
avatar_analyzer.set_threshold(oper.role == Role::Drone ? drone_threshold : threshold);
@@ -193,7 +205,8 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable)
}
}
if (ranges::count_if(unknown_opers, [](const DeploymentOper& it) { return !it.cooling; }) > 0 || init) {
if (ranges::count_if(unknown_opers, [](const DeploymentOper& it) { return !it.cooling; }) > 0
|| init) {
// 一个都没匹配上的,挨个点开来看一下
LogTraceScope("rec unknown opers");
@@ -298,7 +311,10 @@ bool asst::BattleHelper::update_cost(const cv::Mat& reusable)
return true;
}
bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc, DeployDirection direction)
bool asst::BattleHelper::deploy_oper(
const std::string& name,
const Point& loc,
DeployDirection direction)
{
LogTraceFunction;
@@ -318,8 +334,9 @@ bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc,
}
Point target_point = target_iter->second.pos;
int dist = static_cast<int>(
Point::distance(target_point, { oper_rect.x + oper_rect.width / 2, oper_rect.y + oper_rect.height / 2 }));
int dist = static_cast<int>(Point::distance(
target_point,
{ oper_rect.x + oper_rect.width / 2, oper_rect.y + oper_rect.height / 2 }));
// 1000 是随便取的一个系数,把整数的 pre_delay 转成小数用的
int duration = static_cast<int>(dist / 1000.0 * swipe_oper_task_ptr->pre_delay);
@@ -327,11 +344,18 @@ bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc,
if (int min_duration = swipe_oper_task_ptr->special_params.at(4); duration < min_duration) {
duration = min_duration;
}
bool deploy_with_pause =
ControlFeat::support(m_inst_helper.ctrler()->support_features(), ControlFeat::SWIPE_WITH_PAUSE);
bool deploy_with_pause = ControlFeat::support(
m_inst_helper.ctrler()->support_features(),
ControlFeat::SWIPE_WITH_PAUSE);
Point oper_point(oper_rect.x + oper_rect.width / 2, oper_rect.y + oper_rect.height / 2);
m_inst_helper.ctrler()->swipe(oper_point, target_point, duration, false, swipe_oper_task_ptr->special_params.at(2),
swipe_oper_task_ptr->special_params.at(3), deploy_with_pause);
m_inst_helper.ctrler()->swipe(
oper_point,
target_point,
duration,
false,
swipe_oper_task_ptr->special_params.at(2),
swipe_oper_task_ptr->special_params.at(3),
deploy_with_pause);
// 拖动干员朝向
if (direction != DeployDirection::None) {
@@ -350,8 +374,12 @@ bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc,
static_cast<int>(swipe_oper_task_ptr->special_params.at(0) * scale_size.second / 720.0);
Point end_point = target_point + (direction_target * coeff);
fix_swipe_out_of_limit(target_point, end_point, scale_size.first, scale_size.second,
swipe_oper_task_ptr->special_params.at(1));
fix_swipe_out_of_limit(
target_point,
end_point,
scale_size.first,
scale_size.second,
swipe_oper_task_ptr->special_params.at(1));
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);
@@ -413,7 +441,9 @@ bool asst::BattleHelper::retreat_oper(const Point& loc, bool manually)
m_used_tiles.erase(loc);
if (manually) {
std::erase_if(m_battlefield_opers, [&loc](const auto& pair) -> bool { return pair.second == loc; });
std::erase_if(m_battlefield_opers, [&loc](const auto& pair) -> bool {
return pair.second == loc;
});
}
return true;
}
@@ -548,7 +578,9 @@ bool asst::BattleHelper::use_all_ready_skill(const cv::Mat& reusable)
if (usage == SkillUsage::Times) {
times--;
if (times == 0) usage = SkillUsage::TimesUsed;
if (times == 0) {
usage = SkillUsage::TimesUsed;
}
}
image = m_inst_helper.ctrler()->get_image();
}
@@ -556,7 +588,10 @@ bool asst::BattleHelper::use_all_ready_skill(const cv::Mat& reusable)
return used;
}
bool asst::BattleHelper::check_and_use_skill(const std::string& name, bool& has_error, const cv::Mat& reusable)
bool asst::BattleHelper::check_and_use_skill(
const std::string& name,
bool& has_error,
const cv::Mat& reusable)
{
auto oper_iter = m_battlefield_opers.find(name);
if (oper_iter == m_battlefield_opers.cend()) {
@@ -566,7 +601,10 @@ bool asst::BattleHelper::check_and_use_skill(const std::string& name, bool& has_
return check_and_use_skill(oper_iter->second, has_error, reusable);
}
bool asst::BattleHelper::check_and_use_skill(const Point& loc, bool& has_error, const cv::Mat& reusable)
bool asst::BattleHelper::check_and_use_skill(
const Point& loc,
bool& has_error,
const cv::Mat& reusable)
{
cv::Mat image = reusable.empty() ? m_inst_helper.ctrler()->get_image() : reusable;
BattlefieldClassifier skill_analyzer(image);
@@ -597,7 +635,14 @@ void asst::BattleHelper::save_map(const cv::Mat& image)
auto draw = image.clone();
for (const auto& [loc, info] : m_normal_tile_info) {
cv::circle(draw, cv::Point(info.pos.x, info.pos.y), 5, cv::Scalar(0, 255, 0), -1);
cv::putText(draw, loc.to_string(), cv::Point(info.pos.x - 30, info.pos.y), 1, 1.2, cv::Scalar(0, 0, 255), 2);
cv::putText(
draw,
loc.to_string(),
cv::Point(info.pos.x - 30, info.pos.y),
1,
1.2,
cv::Scalar(0, 0, 255),
2);
}
std::string suffix;
@@ -665,15 +710,21 @@ bool asst::BattleHelper::click_retreat()
{
LogTraceFunction;
return ProcessTask(this_task(), { "BattleOperRetreatJustClick" }).run();
// return ProcessTask(this_task(), { "BattleOperRetreatJustClick" }).run();
return m_inst_helper.ctrler()->click(m_retreat_button_pos);
}
// TODO: use m_skill_button_pos
bool asst::BattleHelper::click_skill(bool keep_waiting)
{
LogTraceFunction;
ProcessTask skill_task(this_task(), { "BattleSkillReadyOnClick", "BattleSkillReadyOnClick-SquareMap",
"BattleSkillStopOnClick", "BattleSkillStopOnClick-SquareMap" });
ProcessTask skill_task(
this_task(),
{ "BattleSkillReadyOnClick",
"BattleSkillReadyOnClick-SquareMap",
"BattleSkillStopOnClick",
"BattleSkillStopOnClick-SquareMap" });
skill_task.set_task_delay(0);
if (keep_waiting) {
@@ -693,8 +744,13 @@ 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, int max_distance,
double radian)
void asst::BattleHelper::fix_swipe_out_of_limit(
Point& p1,
Point& p2,
int width,
int height,
int max_distance,
double radian)
{
Point direct = Point::zero();
int distance = 0;
@@ -728,7 +784,8 @@ void asst::BattleHelper::fix_swipe_out_of_limit(Point& p1, Point& p2, int width,
};
// 旋转后偏移值会不够,计算补偿比例
double adjust_more = std::get<0>(adjust_scale) * direct.x + std::get<1>(adjust_scale) * direct.y;
double adjust_more =
std::get<0>(adjust_scale) * direct.x + std::get<1>(adjust_scale) * direct.y;
Point adjust = {
static_cast<int>(std::get<0>(adjust_scale) / adjust_more * distance),
@@ -742,7 +799,14 @@ void asst::BattleHelper::fix_swipe_out_of_limit(Point& p1, Point& p2, int width,
};
}
Log.info(__FUNCTION__, "swipe end_point out of limit, start:", p1, ", end:", p2, ", adjust:", adjust);
Log.info(
__FUNCTION__,
"swipe end_point out of limit, start:",
p1,
", end:",
p2,
", adjust:",
adjust);
p1 += adjust;
p2 += adjust;
}
@@ -797,11 +861,14 @@ std::string asst::BattleHelper::analyze_detail_page_oper_name(const cv::Mat& ima
return BattleData.is_name_invalid(det_name) ? std::string() : det_name;
}
std::optional<asst::Rect> asst::BattleHelper::get_oper_rect_on_deployment(const std::string& name) const
std::optional<asst::Rect>
asst::BattleHelper::get_oper_rect_on_deployment(const std::string& name) const
{
LogTraceFunction;
auto oper_iter = ranges::find_if(m_cur_deployment_opers, [&](const auto& oper) { return oper.name == name; });
auto oper_iter = ranges::find_if(m_cur_deployment_opers, [&](const auto& oper) {
return oper.name == name;
});
if (oper_iter == m_cur_deployment_opers.end()) {
Log.error("No oper", name);
return std::nullopt;