From b758bf05c6846c513b42fd05c410418d2bc7dc00 Mon Sep 17 00:00:00 2001 From: MistEO Date: Tue, 17 Jan 2023 02:35:05 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BF=9D=E5=85=A8?= =?UTF-8?q?=E4=B8=80=E7=B3=BB=E5=88=97=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=88?= =?UTF-8?q?=E6=88=91=E5=BF=98=E4=BA=86=E5=85=B7=E4=BD=93=E6=9C=89=E5=93=AA?= =?UTF-8?q?=E4=BA=9B=E4=BA=86.jpg=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/3.7-保全派驻协议.md | 10 +-- resource/tasks.json | 41 +++++---- resource/template/SSSHalfTimeDropsCancel.png | Bin 0 -> 1433 bytes .../SSSHalfTimeDropsCancelConfirm.png | Bin 0 -> 21126 bytes resource/template/SSSHalfTimeDropsConfirm.png | Bin 0 -> 1305 bytes src/MaaCore/Common/AsstBattleDef.h | 45 +++++++--- .../Miscellaneous/AvatarCacheManager.cpp | 2 +- .../Config/Miscellaneous/CopilotConfig.cpp | 11 +-- src/MaaCore/Task/BattleHelper.cpp | 28 ++++-- src/MaaCore/Task/BattleHelper.h | 2 +- .../Task/Miscellaneous/BattleProcessTask.cpp | 23 +++-- .../Task/Miscellaneous/BattleProcessTask.h | 2 +- src/MaaCore/Task/ProcessTask.cpp | 9 +- src/MaaCore/Task/ProcessTask.h | 3 + src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp | 83 +++++++++++------- src/MaaCore/Task/SSS/SSSBattleProcessTask.h | 7 +- 16 files changed, 159 insertions(+), 107 deletions(-) create mode 100644 resource/template/SSSHalfTimeDropsCancel.png create mode 100644 resource/template/SSSHalfTimeDropsCancelConfirm.png create mode 100644 resource/template/SSSHalfTimeDropsConfirm.png diff --git a/docs/3.7-保全派驻协议.md b/docs/3.7-保全派驻协议.md index b57dbaf255..76b2a3afe5 100644 --- a/docs/3.7-保全派驻协议.md +++ b/docs/3.7-保全派驻协议.md @@ -42,7 +42,7 @@ "无需增调干员", // 不招人 "重整导能组件", // 支持装备名,全写一起.jpg "反制导能组件", - "战备激活阀", // 关卡中途的可选装备,也也放这里。需要配合 actions 中 type: GetDrops 使用 + "战备激活阀", // 关卡中途的可选装备,也也放这里 "改派发讯器", ], "blacklist": [ // 黑名单,可选。在 drops 里不会选这些人。 @@ -107,14 +107,6 @@ "type": "CheckIfStartOver", // 新 type,检查干员在不在,不在就退出重开 "name": "棘刺" }, - { - "type": "GetDrops", // 检查获取战斗中途的战利品,将按照 drops 字段的排序进行拿去 - // 若 drops 字段为空,或 drops 中的物品一个都没识别到,将会选择放弃战利品 - // 若执行动作时未识别到战利品获取,将会直接跳过该 action - "kills": 20, - "pre_delay": 3000 // 小技巧:一般来说都是打死了某个怪才会出,所以可以基于击杀数来触发 - // 但是从击杀数达到到选择界面跳出来可能有个延迟,所以建议价格 pre_delay - }, { "name": "桃金娘", "location": [ diff --git a/resource/tasks.json b/resource/tasks.json index 7467a3bfe1..56a2a837ad 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -9401,6 +9401,7 @@ }, "SSSDrawCard": { "action": "ClickSelf", + "templThreshold": 0.98, "roi": [ 1151, 319, @@ -9455,7 +9456,7 @@ 900, 112 ], - "postDelay": 5000, + "postDelay": 3000, "next": [ "SSSStartFighting2", "SSSDropRecruitmentFlag" @@ -9504,7 +9505,7 @@ "postDelay": 1000 }, "SSSHalfTimeDropsBegin": { - "algorithm": "JustReturn", + "template": "SSSHalfTimeDropsConfirm.png", "action": "DoNothing", "next": [ "SSSHalfTimeDrops", @@ -9526,29 +9527,33 @@ ] }, "SSSHalfTimeDropsConfirm": { - "algorithm": "OcrDetect", "action": "ClickSelf", - "text": [ - "确认" - ], "roi": [ - 1073, - 281, - 155, - 151 + 1034, + 283, + 148, + 148 ] }, "SSSHalfTimeDropsCancel": { - "algorithm": "OcrDetect", "action": "ClickSelf", - "text": [ - "放弃" - ], "roi": [ - 51, - 251, - 146, - 199 + 100, + 284, + 145, + 145 + ], + "next": [ + "SSSHalfTimeDropsCancelConfirm" + ] + }, + "SSSHalfTimeDropsCancelConfirm": { + "action": "ClickSelf", + "roi": [ + 716, + 410, + 254, + 163 ] }, "ClickCornerUntilStartButton": { diff --git a/resource/template/SSSHalfTimeDropsCancel.png b/resource/template/SSSHalfTimeDropsCancel.png new file mode 100644 index 0000000000000000000000000000000000000000..8ffc1adafc89bbb6fd4054b7be0669cc006fcfc6 GIT binary patch literal 1433 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK1SGdsl%8c^U`_CJaSVyzJbN(KTQpXL{lkB& z%bFZpuAJBvuxGC>4Ui?*>XGk?D5{RaEn|M+5aoU{cFb0tc2`?Z5c?Yu&#;o%M|~Bt@Ug zFen|mn3J2^Di9*7?slf9tC){L@L|TbZQGnUR&@z0r@0-qba%1Xw07-Ufu>cDj&#fn zEIcPD=(Sf!>hF(_kB@eXBUEYR=H#qdzkYGx{`>cD-aNP;XnR+2Uq^sem(uy-Kk+cF zu7OV~`5xTbn%&&o>^bQ{MBV>?e}8>_UAMpA?Z}xG7SB64mM+rxWW%1Y*7Vqe9Z5Zk zEP{^8K*!H1c4-L;6serYyy2QuazTvYF@dIz1%iggTIVd4oK|Xd*_>yL$nG^<@#S|d z!`d+J`b+P>Gj55}4Z&qZKxB0E>$2U~qW+wmZJwXhV{B}^;)sMZhf))!Ll^?ChOduX zyKdd8S4WN<`SPV?_gyzvmuuIq0Uc^!Y5DWP!Dbat20Xg^gsTIcJ}-G zYHtIB#>dxpY33{yPAx=00v)NQ6w3MmXhm-?FT=H{WFEfXpPrun^r>k5b!S!2Nh?>b zH1REr=rL?jP|9#Q)8n=KF57}t3?ZQ|44|O5@Cn^t`}^CQo5mqCex93a4UFCma9{O; z{35e$|Ni}Z_Wb$zIX%S9%`GiGot=%X0Air$qyWyPfB)8A5injnaqBgS=EL*s>;HXy z9UjVB@a)XY=4NIFV3PU#`LnoQjDs)O4d!`wX3UwRqQtQ3*OQaNaE+(#-Me?`(xqq5 z)Edfm*8qV>q@?5G&8jf#=I{uXTFt$9F;HeEG-M|$ zF7jJ$Y-QD@91QV8p^*zPAl=;E3say@@yn^G`0?iE<{#4c_t%5m1}g97FdaE#!P+si gkW0Y$vB(ep-eYswts?~20*hP*Pgg&ebxsLQ0F_9O(*OVf literal 0 HcmV?d00001 diff --git a/resource/template/SSSHalfTimeDropsCancelConfirm.png b/resource/template/SSSHalfTimeDropsCancelConfirm.png new file mode 100644 index 0000000000000000000000000000000000000000..5009758ae43dcfd577459119aae2c8967c09bfb0 GIT binary patch literal 21126 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 KW49dxF8&`iB~}jr literal 0 HcmV?d00001 diff --git a/resource/template/SSSHalfTimeDropsConfirm.png b/resource/template/SSSHalfTimeDropsConfirm.png new file mode 100644 index 0000000000000000000000000000000000000000..a46ac97c3fd768bcf5a95a5c886efd7dfacb8221 GIT binary patch literal 1305 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@H76a}`{(0Z0dG^H{bkpjoZr7k__fQu&QhiKN3156C(S)!z0vQwmXGZnMxQzbU0g$&%&UD@)wJ&X_u(e9@Z8lBaj zE}8`PGQ`;-f-jz#NqkmQDlDJfA9Qz>VX@uA{`lx!uGk%FEF^L4`)b!eMYG#i<{dfX z)AL4?UHw@Zvg0p${m=*nn=0Hr|IQ(WdOw48D_r;N_kEpvca32%%P;>omjzuHOugVI z+U*65o4*g^kHx6eeG~g$26FV=m=E2zZG2e2w0*m3?!&Y`$8CqK+@7^-XUy!@oNxOy z-~Ww~!DV=89TWcNeI&_v5iop>f84d+wfEqepDp`kZa;`B++P zJnz4grzRS#@#f0fpFGAr)9d~R2dcey0a*)-)HLm9bw{4b>65>GbOR6Lc^z%ldWx%lWM}j zHtb#a)qTds2Xi$hmoM^yMCK{CBkjDl9zf$O4IiFAUQ?JB{J46n(5;n87p0@>TO_&f zbsANwuMz<#z58L^1=cn`smG4Hf4gej^wAj{MlX2R+8^p+eeW_8?qThukE?SI0EuB{tBk)RH&bNGIvD~IK9{_rkNe;LXv!|OzH>WN zrONqrzd`arYfw;$Hh<;}ethedATa*!UHGMZCgOwNl#|vUm0uw_ZFRzjq(et4_BIRu z{=;J|229tV{MH;weX#!cH2dQ}9GgD2oIaop_HEe1q*ITTf#Ie}3|CPio%J!Ncja@n qa7g(Qp$;@yxKjOECsOhAlV44fBYy9@wLgGG9)qW=pUXO@geCwICxKf4 literal 0 HcmV?d00001 diff --git a/src/MaaCore/Common/AsstBattleDef.h b/src/MaaCore/Common/AsstBattleDef.h index 394ef2f6ad..a5ed808b88 100644 --- a/src/MaaCore/Common/AsstBattleDef.h +++ b/src/MaaCore/Common/AsstBattleDef.h @@ -95,18 +95,6 @@ namespace asst::battle return Role::Unknown; } - struct DeploymentOper - { - size_t index = 0; - Role role = Role::Unknown; - int cost = 0; - bool available = false; - bool cooling = false; - Rect rect; - cv::Mat avatar; - std::string name; - }; - enum class OperPosition { None, @@ -123,6 +111,38 @@ namespace asst::battle All = 3 }; + inline static LocationType get_role_usual_location(const Role& role) + { + switch (role) { + case Role::Warrior: + case Role::Pioneer: + case Role::Tank: + case Role::Special: + case Role::Drone: + return LocationType::Melee; + case Role::Medic: + case Role::Sniper: + case Role::Caster: + case Role::Support: + return LocationType::Ranged; + default: + return LocationType::None; + } + } + + struct DeploymentOper + { + size_t index = 0; + Role role = Role::Unknown; + int cost = 0; + bool available = false; + bool cooling = false; + Rect rect; + cv::Mat avatar; + std::string name; + LocationType location_type = LocationType::None; + bool is_unusual_location = false; // 地面辅助,高台先锋等 + }; struct OperProps { std::string name; @@ -157,7 +177,6 @@ namespace asst::battle /* for SSS */ DrawCard, // “调配干员” CheckIfStartOver, // 检查如果没有某干员则退出重开 - GetDrops, // 识别并获取战斗中途的掉落物 }; struct Action diff --git a/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp b/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp index c6f2736d84..5b6a92d9fd 100644 --- a/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp +++ b/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp @@ -16,7 +16,7 @@ bool asst::AvatarCacheManager::load(const std::filesystem::path& path) return true; } - const auto& [_, _, w, h] = Task.get("BattleOperAvatar")->rect_move; + const auto& [_1, _2, w, h] = Task.get("BattleOperAvatar")->rect_move; for (const auto& entry : std::filesystem::directory_iterator(path)) { if (!entry.is_regular_file()) { diff --git a/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp b/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp index 6063d6ecd3..54e1d14001 100644 --- a/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp +++ b/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp @@ -155,14 +155,6 @@ std::vector asst::CopilotConfig::parse_actions(co { "CHECKIFSTARTOVER", ActionType::CheckIfStartOver }, { "checkifstartover", ActionType::CheckIfStartOver }, { "检查重开", ActionType::CheckIfStartOver }, - - { "GetDrops", ActionType::GetDrops }, - { "Getdrops", ActionType::GetDrops }, - { "GETDROPS", ActionType::GetDrops }, - { "getdrops", ActionType::GetDrops }, - { "获取战利品", ActionType::GetDrops }, - { "获取掉落", ActionType::GetDrops }, - { "获取装备", ActionType::GetDrops }, }; std::string type_str = action_info.get("type", "Deploy"); @@ -171,7 +163,8 @@ std::vector asst::CopilotConfig::parse_actions(co action.type = iter->second; } else { - action.type = ActionType::Deploy; + Log.warn("Unknown action type:", type_str); + continue; } action.kills = action_info.get("kills", 0); action.cost_changes = action_info.get("cost_changes", 0); diff --git a/src/MaaCore/Task/BattleHelper.cpp b/src/MaaCore/Task/BattleHelper.cpp index ecded7e252..f6a847e95a 100644 --- a/src/MaaCore/Task/BattleHelper.cpp +++ b/src/MaaCore/Task/BattleHelper.cpp @@ -115,6 +115,12 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) m_battlefield_opers.erase(iter); }; + auto set_oper_name = [&](DeploymentOper& oper, const std::string& name) { + oper.name = name; + oper.location_type = BattleData.get_location_type(name); + oper.is_unusual_location = battle::get_role_usual_location(oper.role) == oper.location_type; + }; + auto cur_opers = oper_analyzer.get_opers(); std::vector unknown_opers; @@ -137,7 +143,7 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) avatar_analyzer.append_templ(name, avatar); } if (avatar_analyzer.analyze()) { - oper.name = avatar_analyzer.get_result_name(); + set_oper_name(oper, avatar_analyzer.get_result_name()); m_cur_deployment_opers.insert_or_assign(oper.name, oper); remove_cooling_from_battlefield(oper); } @@ -151,7 +157,8 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) } } - if (!unknown_opers.empty() || init) { + if (!unknown_opers.empty() || init) + { // 一个都没匹配上的,挨个点开来看一下 LogTraceScope("rec unknown opers"); @@ -166,11 +173,19 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) std::this_thread::yield(); } while (!m_inst_helper.need_exit()); + if (!check_in_battle(image)) { + return false; + } + for (auto& oper : unknown_opers) { LogTraceScope("rec unknown oper: " + std::to_string(oper.index)); click_oper_on_deployment(oper.rect); cv::Mat name_image = m_inst_helper.ctrler()->get_image(); + if (!check_in_battle(name_image)) { + return false; + } + auto analyze = [&](OcrImageAnalyzer& name_analyzer) { name_analyzer.set_image(name_image); name_analyzer.set_task_info(oper_name_ocr_task_name()); @@ -202,7 +217,7 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) Log.error("name is empty"); continue; } - oper.name = name; + set_oper_name(oper, name); remove_cooling_from_battlefield(oper); if (oper.cooling) { @@ -229,9 +244,8 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) if (init) { update_kills(image); } - check_in_battle(image); - return true; + return check_in_battle(image); } bool asst::BattleHelper::update_kills(const cv::Mat& reusable) @@ -610,9 +624,7 @@ bool asst::BattleHelper::move_camera(const std::pair& delta) m_camera_shift.second += delta.second; calc_tiles_info(m_stage_name, -m_camera_shift.first, m_camera_shift.second); - update_deployment(true); - - return true; + return update_deployment(true); } std::optional asst::BattleHelper::get_oper_rect_on_deployment(const std::string& name) const diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index 9c85e66b1c..69e0645575 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -45,7 +45,7 @@ namespace asst bool use_skill(const std::string& name, bool keep_waiting = true); bool use_skill(const Point& loc, bool keep_waiting = true); bool check_pause_button(const cv::Mat& reusable = cv::Mat()); - bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = false); + bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true); virtual bool wait_until_start(bool weak = true); bool wait_until_end(bool weak = true); bool use_all_ready_skill(const cv::Mat& reusable = cv::Mat()); diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp index 616ff6f7f8..0a095430d0 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp @@ -135,7 +135,7 @@ bool asst::BattleProcessTask::to_group() bool asst::BattleProcessTask::do_action(size_t action_index) { LogTraceFunction; - + const auto& action = get_combat_data().actions.at(action_index); notify_action(action); @@ -144,7 +144,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index) return false; } if (action.pre_delay > 0) { - sleep_and_do_not_urgent(action.pre_delay); + sleep_and_do_strategy(action.pre_delay); // 等待之后画面可能会变化,更新下干员信息 update_deployment(); } @@ -200,7 +200,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index) break; } - sleep_and_do_not_urgent(action.post_delay); + sleep_and_do_strategy(action.post_delay); return ret; } @@ -229,7 +229,6 @@ void asst::BattleProcessTask::notify_action(const battle::copilot::Action& actio { ActionType::MoveCamera, "MoveCamera" }, { ActionType::DrawCard, "DrawCard" }, { ActionType::CheckIfStartOver, "CheckIfStartOver" }, - { ActionType::GetDrops, "GetDrops" }, }; json::value info = basic_info_with_what("CopilotAction"); @@ -305,15 +304,14 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) if (action.cooling >= 0) { update_image_if_empty(); while (!need_exit() && m_in_battle) { - update_deployment(false, image); + if (!update_deployment(false, image)) { + return false; + } size_t cooling_count = ranges::count_if(m_cur_deployment_opers | views::values, [](const auto& oper) -> bool { return oper.cooling; }); if (cooling_count == action.cooling) { break; } - if (!check_in_battle(image)) { - return false; - } do_strategy_and_update_image(); } } @@ -323,14 +321,13 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) const std::string& name = get_name_from_group(action.name); update_image_if_empty(); while (!need_exit() && m_in_battle) { - update_deployment(false, image); + if (!update_deployment(false, image)) { + return false; + } if (auto iter = m_cur_deployment_opers.find(name); iter != m_cur_deployment_opers.cend() && iter->second.available) { break; } - if (!check_in_battle(image)) { - return false; - } do_strategy_and_update_image(); } } @@ -368,7 +365,7 @@ bool asst::BattleProcessTask::enter_bullet_time_for_next_action(size_t next_inde return ret; } -void asst::BattleProcessTask::sleep_and_do_not_urgent(unsigned millisecond) +void asst::BattleProcessTask::sleep_and_do_strategy(unsigned millisecond) { LogTraceScope(__FUNCTION__ + std::string(" ms: ") + std::to_string(millisecond)); diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h index 7f0c89a9f1..46e062866f 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h @@ -33,7 +33,7 @@ namespace asst void notify_action(const battle::copilot::Action& action); bool wait_condition(const battle::copilot::Action& action); bool enter_bullet_time_for_next_action(size_t next_index, const Point& location, const std::string& name); - void sleep_and_do_not_urgent(unsigned millisecond); + void sleep_and_do_strategy(unsigned millisecond); battle::copilot::CombatData m_combat_data; std::unordered_map m_oper_in_group; diff --git a/src/MaaCore/Task/ProcessTask.cpp b/src/MaaCore/Task/ProcessTask.cpp index 6cd6cef9ba..ad310a359f 100644 --- a/src/MaaCore/Task/ProcessTask.cpp +++ b/src/MaaCore/Task/ProcessTask.cpp @@ -79,6 +79,12 @@ ProcessTask& asst::ProcessTask::set_post_delay(std::string name, int delay) return *this; } +ProcessTask& asst::ProcessTask::set_reusable_image(const cv::Mat& reusable) +{ + m_reusable = reusable; + return *this; +} + bool ProcessTask::_run() { LogTraceFunction; @@ -112,7 +118,8 @@ bool ProcessTask::_run() m_cur_task_ptr = front_task_ptr; } else { - const auto image = ctrler()->get_image(); + cv::Mat image = m_reusable.empty() ? ctrler()->get_image() : m_reusable; + m_reusable = cv::Mat(); ProcessTaskImageAnalyzer analyzer(image, m_cur_task_name_list, m_inst); if (!analyzer.analyze()) { diff --git a/src/MaaCore/Task/ProcessTask.h b/src/MaaCore/Task/ProcessTask.h index 18e4406b6e..440723aa56 100644 --- a/src/MaaCore/Task/ProcessTask.h +++ b/src/MaaCore/Task/ProcessTask.h @@ -2,6 +2,7 @@ #include "AbstractTask.h" #include "Common/AsstTypes.h" +#include "Utils/NoWarningCVMat.h" namespace asst { @@ -34,6 +35,7 @@ namespace asst ProcessTask& set_tasks(std::vector tasks_name) noexcept; ProcessTask& set_times_limit(std::string name, int limit, TimesLimitType type = TimesLimitType::Pre); ProcessTask& set_post_delay(std::string name, int delay); + ProcessTask& set_reusable_image(const cv::Mat& reusable); const std::string& get_last_task_name() const noexcept { return m_last_task_name; } @@ -59,5 +61,6 @@ namespace asst std::unordered_map m_exec_times; static constexpr int TaskDelayUnsetted = -1; int m_task_delay = TaskDelayUnsetted; + cv::Mat m_reusable; }; } diff --git a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp index 84bc7c9bec..0760da873b 100644 --- a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp +++ b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp @@ -48,8 +48,6 @@ bool asst::SSSBattleProcessTask::do_derived_action(size_t action_index) return draw_card(); case battle::copilot::ActionType::CheckIfStartOver: return check_if_start_over(action); - case battle::copilot::ActionType::GetDrops: - return get_drops(); default: Log.error("unknown action type", static_cast(action.type)); return false; @@ -59,10 +57,39 @@ bool asst::SSSBattleProcessTask::do_derived_action(size_t action_index) bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) { LogTraceFunction; - cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable; - update_deployment(false, image); - if (!m_in_battle) { + + if (check_and_do_strategy(image)) { + return true; + } + + if (check_and_get_drops(image)) { + return true; + } + + if (use_all_ready_skill(image)) { + return true; + } + + if (m_sss_combat_data.draw_as_possible && draw_card(false, image)) { + return true; + } + + return true; +} + +bool asst::SSSBattleProcessTask::wait_until_start(bool weak) +{ + LogTraceFunction; + + return ProcessTask(*this, { "SSSFightDirectly" }).set_retry_times(300).run() && + BattleProcessTask::wait_until_start(weak); +} + +bool asst::SSSBattleProcessTask::check_and_do_strategy(const cv::Mat& reusable) +{ + cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable; + if (!update_deployment(false, image)) { return false; } @@ -72,7 +99,7 @@ bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) if (m_all_cores.contains(name)) { exist_core.emplace(name, oper); } - else if (!m_all_action_opers.contains(oper.name)) { + else if (oper.is_unusual_location && !m_all_action_opers.contains(oper.name)) { tool_men.emplace_back(oper); // 工具人的技能一概好了就用 m_skill_usage.try_emplace(name, SkillUsage::Possibly); @@ -124,21 +151,7 @@ bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) } } - if (m_sss_combat_data.draw_as_possible) { - draw_card(false); - } - - use_all_ready_skill(image); - - return true; -} - -bool asst::SSSBattleProcessTask::wait_until_start(bool weak) -{ - LogTraceFunction; - - return ProcessTask(*this, { "SSSFightDirectly" }).set_retry_times(300).run() && - BattleProcessTask::wait_until_start(weak); + return false; } bool asst::SSSBattleProcessTask::check_if_start_over(const battle::copilot::Action& action) @@ -172,29 +185,39 @@ bool asst::SSSBattleProcessTask::check_if_start_over(const battle::copilot::Acti return true; } -bool asst::SSSBattleProcessTask::draw_card(bool with_retry) +bool asst::SSSBattleProcessTask::draw_card(bool with_retry, const cv::Mat& reusable) { - LogTraceFunction; + cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable; ProcessTask task(*this, { "SSSDrawCard" }); if (!with_retry) { - task.set_retry_times(0); + task.set_task_delay(0).set_retry_times(0); } + task.set_reusable_image(image); return task.run(); } -bool asst::SSSBattleProcessTask::get_drops() +bool asst::SSSBattleProcessTask::check_and_get_drops(const cv::Mat& reusable) { - LogTraceFunction; + cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable; + if (!ProcessTask(*this, { "SSSHalfTimeDropsBegin" }) + .set_reusable_image(image) + .set_times_limit("SSSHalfTimeDropsBegin", 0) + .set_task_delay(0) + .set_retry_times(0) + .run()) { + return false; + } const auto& drops = m_sss_combat_data.order_of_drops; - - // 不一定就有掉落界面,有可能宝箱怪压根没被打掉。所以不重试 + std::string task_name; if (drops.empty()) { - return ProcessTask(*this, { inst_string() + "@SSSHalfTimeDropsCancel" }).set_retry_times(0).run(); + task_name = inst_string() + "@SSSHalfTimeDropsCancel"; } else { Task.get(inst_string() + "@SSSHalfTimeDrops")->text = { drops }; - return ProcessTask(*this, { inst_string() + "@SSSHalfTimeDropsBegin" }).set_retry_times(0).run(); + task_name = inst_string() + "@SSSHalfTimeDropsBegin"; } + Log.info("Get drops", drops); + return ProcessTask(*this, { task_name }).set_reusable_image(image).run(); } diff --git a/src/MaaCore/Task/SSS/SSSBattleProcessTask.h b/src/MaaCore/Task/SSS/SSSBattleProcessTask.h index 42b8bf1173..7936e42cba 100644 --- a/src/MaaCore/Task/SSS/SSSBattleProcessTask.h +++ b/src/MaaCore/Task/SSS/SSSBattleProcessTask.h @@ -1,5 +1,5 @@ #pragma once -#include "../Miscellaneous/BattleProcessTask.h" +#include "Task/Miscellaneous/BattleProcessTask.h" namespace asst { @@ -19,9 +19,10 @@ namespace asst virtual bool need_to_wait_until_end() const noexcept override { return true; } virtual bool wait_until_start(bool weak = true) override; + bool check_and_do_strategy(const cv::Mat& reusable = cv::Mat()); bool check_if_start_over(const battle::copilot::Action& action); - bool draw_card(bool with_retry = true); - bool get_drops(); + bool draw_card(bool with_retry = true, const cv::Mat& reusable = cv::Mat()); + bool check_and_get_drops(const cv::Mat& reusable = cv::Mat()); battle::sss::CombatData m_sss_combat_data; std::unordered_set m_all_cores;