fix: 修复肉鸽CD干员识别及处理错误

This commit is contained in:
MistEO
2022-12-25 05:58:31 +08:00
parent 77c035045e
commit 644a263b08
5 changed files with 41 additions and 28 deletions

View File

@@ -29,12 +29,6 @@ namespace asst::battle
SkillUsage skill_usage = SkillUsage::NotUse;
};
struct BattlefieldOper // 战场上的干员
{
std::string name;
Point loc;
};
enum class DeployDirection
{
Right = 0,

View File

@@ -131,16 +131,31 @@ bool asst::BattleHelper::update_deployment(bool init)
}
m_cur_deployment_opers.clear();
MatchImageAnalyzer avatar_analyzer;
avatar_analyzer.set_task_info("BattleAvatarData");
const double threshold = Task.get<MatchTaskInfo>("BattleAvatarData")->templ_threshold;
auto cur_opers = oper_analyzer.get_opers();
std::vector<DeploymentOper> unknown_opers;
auto remove_cooling_from_battlefield = [&](const DeploymentOper& oper) {
if (!oper.cooling) {
return;
}
auto iter = m_battlefield_opers.find(oper.name);
if (iter == m_battlefield_opers.end()) {
return;
}
auto loc = iter->second;
m_used_tiles.erase(loc);
m_battlefield_opers.erase(iter);
};
for (auto& oper : cur_opers) {
MatchImageAnalyzer avatar_analyzer;
avatar_analyzer.set_threshold(threshold);
if (oper.cooling) {
// 把环去掉
avatar_analyzer.set_mask_range(50, 255, true);
avatar_analyzer.set_mask_range(0, 50, true);
}
else {
avatar_analyzer.set_mask_range(0, 0);
@@ -162,6 +177,7 @@ bool asst::BattleHelper::update_deployment(bool init)
if (max_socre) {
m_cur_deployment_opers.insert_or_assign(oper.name, oper);
remove_cooling_from_battlefield(oper);
}
else {
unknown_opers.emplace_back(oper);
@@ -196,10 +212,13 @@ bool asst::BattleHelper::update_deployment(bool init)
name_analyzer.sort_result_by_score();
const std::string& name = name_analyzer.get_result().front().text;
oper.name = name;
m_cur_deployment_opers.insert_or_assign(name, oper);
m_all_deployment_avatars.insert_or_assign(name, oper.avatar);
remove_cooling_from_battlefield(oper);
save_avatar_cache(name, oper.avatar);
}
pause();
cancel_oper_selection();
}
@@ -260,9 +279,8 @@ bool asst::BattleHelper::deploy_oper(const std::string& name, const Point& loc,
m_inst_helper.ctrler()->press_esc();
}
BattlefieldOper bf_oper { .name = name, .loc = loc };
m_battlefield_opers.emplace(name, bf_oper);
m_used_tiles.emplace(loc, bf_oper);
m_battlefield_opers.emplace(name, loc);
m_used_tiles.emplace(loc, name);
return true;
}
@@ -277,7 +295,7 @@ bool asst::BattleHelper::retreat_oper(const std::string& name)
return false;
}
if (!retreat_oper(oper_iter->second.loc, false)) {
if (!retreat_oper(oper_iter->second, false)) {
return false;
}
@@ -295,7 +313,7 @@ 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 == loc; });
std::erase_if(m_battlefield_opers, [&loc](const auto& pair) -> bool { return pair.second == loc; });
}
return true;
}
@@ -310,7 +328,7 @@ bool asst::BattleHelper::use_skill(const std::string& name)
return false;
}
return use_skill(oper_iter->second.loc);
return use_skill(oper_iter->second);
}
bool asst::BattleHelper::use_skill(const Point& loc)
@@ -352,7 +370,7 @@ bool asst::BattleHelper::wait_for_end()
bool asst::BattleHelper::use_all_ready_skill()
{
bool used = false;
for (const auto& [name, loc] : m_battlefield_opers | views::values) {
for (const auto& [name, loc] : m_battlefield_opers) {
auto& usage = m_skill_usage[name];
if (usage != SkillUsage::Possibly && usage != SkillUsage::Once) {
continue;
@@ -376,7 +394,7 @@ bool asst::BattleHelper::check_and_use_skill(const std::string& name)
Log.error("No oper", name);
return false;
}
return check_and_use_skill(oper_iter->second.loc);
return check_and_use_skill(oper_iter->second);
}
bool asst::BattleHelper::check_and_use_skill(const Point& loc)
@@ -446,7 +464,7 @@ bool asst::BattleHelper::click_oper_on_battlefiled(const std::string& name)
Log.error("No oper", name);
return false;
}
return click_oper_on_battlefiled(oper_iter->second.loc);
return click_oper_on_battlefiled(oper_iter->second);
}
bool asst::BattleHelper::click_oper_on_battlefiled(const Point& loc)

View File

@@ -72,8 +72,8 @@ namespace asst
std::map<std::string, cv::Mat> m_all_deployment_avatars;
std::map<std::string, battle::DeploymentOper> m_cur_deployment_opers;
std::map<std::string, battle::BattlefieldOper> m_battlefield_opers;
std::map<Point, battle::BattlefieldOper> m_used_tiles;
std::map<std::string, Point> m_battlefield_opers;
std::map<Point, std::string> m_used_tiles;
private:
virtual AbstractTask& this_task() = 0;

View File

@@ -473,16 +473,17 @@ void asst::RoguelikeBattleTaskPlugin::check_drone_tiles()
if (auto iter = m_used_tiles.find(placed_loc); iter != m_used_tiles.end()) {
Log.info("Drone at location (", placed_loc.x, ",", placed_loc.y, ") is recognized as retreated");
set_position_full(placed_loc, false);
m_battlefield_opers.erase(iter->second.name);
m_battlefield_opers.erase(iter->second);
m_used_tiles.erase(iter);
}
m_need_clear_tiles.pop();
}
}
std::optional<size_t> asst::RoguelikeBattleTaskPlugin::check_urgent(
const std::unordered_set<std::string>& pre_cooling, const std::unordered_set<std::string>& cur_cooling,
const std::map<std::string, battle::BattlefieldOper>& pre_bf_opers, bool& deploy_dice_now)
std::optional<size_t> asst::RoguelikeBattleTaskPlugin::check_urgent(const std::unordered_set<std::string>& pre_cooling,
const std::unordered_set<std::string>& cur_cooling,
const std::map<std::string, Point>& pre_bf_opers,
bool& deploy_dice_now)
{
if (m_first_deploy) {
// No emergency
@@ -500,7 +501,7 @@ std::optional<size_t> asst::RoguelikeBattleTaskPlugin::check_urgent(
Log.error("the oper", name, "was not on the battlefield before");
continue;
}
Point pre_loc = pre_loc_iter->second.loc;
Point pre_loc = pre_loc_iter->second;
if (auto del_loc_blocking = m_blocking_for_home_index.find(pre_loc);
del_loc_blocking != m_blocking_for_home_index.end()) {
@@ -906,7 +907,7 @@ asst::RoguelikeBattleTaskPlugin::DirectionAndScore asst::RoguelikeBattleTaskPlug
case battle::Role::Medic:
if (auto iter = m_used_tiles.find(absolute_pos);
iter != m_used_tiles.cend() &&
BattleData.get_role(iter->second.name) != battle::Role::Drone) // 根据哪个方向上人多决定朝向哪
BattleData.get_role(iter->second) != battle::Role::Drone) // 根据哪个方向上人多决定朝向哪
score += 10000;
if (auto iter = m_side_tile_info.find(absolute_pos); iter != m_side_tile_info.end())
score += TileKeyMedicWeights.at(iter->second.key);

View File

@@ -59,8 +59,8 @@ namespace asst
std::optional<size_t> check_urgent(const std::unordered_set<std::string>& pre_cooling,
const std::unordered_set<std::string>& cur_cooling,
const std::map<std::string, battle::BattlefieldOper>& pre_bf_opers,
bool& deploy_dice_now);
const std::map<std::string, Point>& pre_bf_opers, bool& deploy_dice_now);
std::optional<battle::DeploymentOper> calc_best_oper() const;
struct DeployInfo