diff --git a/resource/tasks.json b/resource/tasks.json index 031ae3e8c9..7ad57a231e 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -5771,11 +5771,21 @@ ], "rearDelay": 500, "next": [ - "BattleQuickFormationCollapseRole", + "BattleQuickFormationExpandRole", "Stop" ] }, - "BattleQuickFormationCollapseRole": { + "BattleQuickFormationExpandRole": { + "action": "ClickSelf", + "roi": [ + 1152, + 0, + 128, + 138 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-All": { "action": "ClickSelf", "roi": [ 1163, @@ -5783,6 +5793,131 @@ 117, 133 ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Pioneer": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Warrior": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Tank": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Caster": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Medic": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Sniper": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Special": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], + "rearDelay": 500 + }, + "BattleQuickFormationRole-Support": { + "action": "ClickSelf", + "roi": [ + 1155, + 41, + 125, + 679 + ], + "templThreshold": 0.7, + "maskRange": [ + 100, + 255 + ], "rearDelay": 500 }, "BattleQuickFormation-OperNameFlag": { diff --git a/resource/template/BattleQuickFormationExpandRole.png b/resource/template/BattleQuickFormationExpandRole.png new file mode 100644 index 0000000000..45d36e8b6f Binary files /dev/null and b/resource/template/BattleQuickFormationExpandRole.png differ diff --git a/resource/template/BattleQuickFormationRole-All.png b/resource/template/BattleQuickFormationRole-All.png new file mode 100644 index 0000000000..485e2b9489 Binary files /dev/null and b/resource/template/BattleQuickFormationRole-All.png differ diff --git a/resource/template/BattleQuickFormationRole-Caster.png b/resource/template/BattleQuickFormationRole-Caster.png new file mode 100644 index 0000000000..7ac313d98f Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Caster.png differ diff --git a/resource/template/BattleQuickFormationRole-Medic.png b/resource/template/BattleQuickFormationRole-Medic.png new file mode 100644 index 0000000000..306d13d852 Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Medic.png differ diff --git a/resource/template/BattleQuickFormationRole-Pioneer.png b/resource/template/BattleQuickFormationRole-Pioneer.png new file mode 100644 index 0000000000..3e81bdda24 Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Pioneer.png differ diff --git a/resource/template/BattleQuickFormationRole-Sniper.png b/resource/template/BattleQuickFormationRole-Sniper.png new file mode 100644 index 0000000000..1127ee6b40 Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Sniper.png differ diff --git a/resource/template/BattleQuickFormationRole-Special.png b/resource/template/BattleQuickFormationRole-Special.png new file mode 100644 index 0000000000..7ea84d010c Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Special.png differ diff --git a/resource/template/BattleQuickFormationRole-Support.png b/resource/template/BattleQuickFormationRole-Support.png new file mode 100644 index 0000000000..cfd334238d Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Support.png differ diff --git a/resource/template/BattleQuickFormationRole-Tank.png b/resource/template/BattleQuickFormationRole-Tank.png new file mode 100644 index 0000000000..c9f4845b40 Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Tank.png differ diff --git a/resource/template/BattleQuickFormationRole-Warrior.png b/resource/template/BattleQuickFormationRole-Warrior.png new file mode 100644 index 0000000000..791be3170b Binary files /dev/null and b/resource/template/BattleQuickFormationRole-Warrior.png differ diff --git a/src/MeoAssistant/BattleFormationTask.cpp b/src/MeoAssistant/BattleFormationTask.cpp index 99f9d53f76..132f6a3235 100644 --- a/src/MeoAssistant/BattleFormationTask.cpp +++ b/src/MeoAssistant/BattleFormationTask.cpp @@ -3,12 +3,11 @@ #include "AsstRanges.hpp" #include "Controller.h" +#include "Logger.hpp" #include "OcrWithFlagTemplImageAnalyzer.h" #include "ProcessTask.h" #include "Resource.h" -#include "AsstRanges.hpp" - void asst::BattleFormationTask::set_stage_name(std::string name) { m_stage_name = std::move(name); @@ -16,35 +15,26 @@ void asst::BattleFormationTask::set_stage_name(std::string name) bool asst::BattleFormationTask::_run() { - const auto& copilot = Resrc.copilot(); - if (!copilot.contains_actions(m_stage_name)) { - return false; - } + LogTraceFunction; - m_groups = copilot.get_actions(m_stage_name).groups; - if (m_groups.empty()) { - return true; + if (!parse_formation()) { + return false; } if (!enter_selection_page()) { return false; } - json::value info = basic_info_with_what("BattleFormation"); - auto& details = info["details"]; - auto& formation = details["formation"]; - for (const auto& name : m_groups | views::keys) { - formation.array_emplace(name); - } - callback(AsstMsg::SubTaskExtraInfo, info); - - // TODO: 需要加一个滑到头了的检测 - while (!need_exit()) { - select_opers_in_cur_page(); - if (m_groups.empty()) { - break; + for (auto& [role, oper_groups] : m_formation) { + click_role_table(role); + // TODO: 需要加一个滑到头了的检测 + while (!need_exit()) { + select_opers_in_cur_page(oper_groups); + if (oper_groups.empty()) { + break; + } + swipe_page(); } - swipe_page(); } confirm_selection(); return true; @@ -55,7 +45,7 @@ bool asst::BattleFormationTask::enter_selection_page() return ProcessTask(*this, { "BattleQuickFormation" }).run(); } -bool asst::BattleFormationTask::select_opers_in_cur_page() +bool asst::BattleFormationTask::select_opers_in_cur_page(std::vector& groups) { auto formation_task_ptr = Task.get("BattleQuickFormationOCR"); auto image = m_ctrler->get_image(); @@ -98,11 +88,10 @@ bool asst::BattleFormationTask::select_opers_in_cur_page() int skill = 1; for (const auto& res : opers_result) { const std::string& name = res.text; - auto iter = m_groups.begin(); + auto iter = groups.begin(); bool found = false; - for (; iter != m_groups.end(); ++iter) { - const auto& [_, opers_vec] = *iter; - for (const auto& oper : opers_vec) { + for (; iter != groups.end(); ++iter) { + for (const auto& oper : *iter) { if (oper.name == name) { found = true; skill = oper.skill; @@ -114,7 +103,7 @@ bool asst::BattleFormationTask::select_opers_in_cur_page() } } - if (iter == m_groups.end()) { + if (iter == groups.end()) { continue; } m_ctrler->click(res.rect); @@ -122,7 +111,7 @@ bool asst::BattleFormationTask::select_opers_in_cur_page() if (1 <= skill && skill <= 3) { m_ctrler->click(SkillRectArray.at(skill - 1ULL)); } - m_groups.erase(iter); + groups.erase(iter); json::value info = basic_info_with_what("BattleFormationSelected"); auto& details = info["details"]; @@ -146,3 +135,48 @@ bool asst::BattleFormationTask::confirm_selection() { return ProcessTask(*this, { "BattleQuickFormationConfirm" }).run(); } + +bool asst::BattleFormationTask::click_role_table(BattleRole role) +{ + static const std::unordered_map RoleNameType = { + { BattleRole::Caster, "Caster" }, { BattleRole::Medic, "Medic" }, { BattleRole::Pioneer, "Pioneer" }, + { BattleRole::Sniper, "Sniper" }, { BattleRole::Special, "Special" }, { BattleRole::Support, "Support" }, + { BattleRole::Tank, "Tank" }, { BattleRole::Warrior, "Warrior" }, + }; + + auto role_iter = RoleNameType.find(role); + if (role_iter == RoleNameType.cend()) { + return ProcessTask(*this, { "BattleQuickFormationRole-All" }).set_retry_times(0).run(); + } + else { + return ProcessTask(*this, { "BattleQuickFormationRole-" + role_iter->second }).set_retry_times(0).run(); + } +} + +bool asst::BattleFormationTask::parse_formation() +{ + if (!Resrc.copilot().contains_actions(m_stage_name)) { + Log.error("Unknown stage name", m_stage_name); + return false; + } + + const auto& group = Resrc.copilot().get_actions(m_stage_name).groups; + const auto& battle_data = Resrc.battle_data(); + + json::value info = basic_info_with_what("BattleFormation"); + auto& details = info["details"]; + auto& formation = details["formation"]; + + for (const auto& [name, opers_vec] : group) { + if (opers_vec.empty()) { + continue; + } + formation.array_emplace(name); + + BattleRole role = battle_data.get_role(opers_vec.front().name); + m_formation[role].emplace_back(opers_vec); + } + + callback(AsstMsg::SubTaskExtraInfo, info); + return true; +} diff --git a/src/MeoAssistant/BattleFormationTask.h b/src/MeoAssistant/BattleFormationTask.h index b99f8f37c2..ec2301c3b5 100644 --- a/src/MeoAssistant/BattleFormationTask.h +++ b/src/MeoAssistant/BattleFormationTask.h @@ -13,14 +13,17 @@ namespace asst void set_stage_name(std::string name); protected: + using OperGroup = std::vector; virtual bool _run() override; bool enter_selection_page(); - bool select_opers_in_cur_page(); + bool select_opers_in_cur_page(std::vector& groups); void swipe_page(); bool confirm_selection(); + bool click_role_table(BattleRole role); + bool parse_formation(); std::string m_stage_name; - std::unordered_map> m_groups; + std::unordered_map> m_formation; }; }