diff --git a/resource/tasks.json b/resource/tasks.json index 09cd9ff3da..3141e88576 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -9604,6 +9604,11 @@ 39, 250, 203 + ], + "postDelay": 2000, + "next": [ + "SSSStartFighting2", + "SSSDropRecruitmentFlag" ] }, "SSSClickUntilStartScreen": { diff --git a/src/MaaCore/MaaCore.vcxproj b/src/MaaCore/MaaCore.vcxproj index 39614d24a6..2341b7da6e 100644 --- a/src/MaaCore/MaaCore.vcxproj +++ b/src/MaaCore/MaaCore.vcxproj @@ -35,6 +35,7 @@ + @@ -157,6 +158,7 @@ + @@ -404,7 +406,7 @@ - + \ No newline at end of file diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters index 9e7d4094eb..204e7705d4 100644 --- a/src/MaaCore/MaaCore.vcxproj.filters +++ b/src/MaaCore/MaaCore.vcxproj.filters @@ -465,9 +465,6 @@ 源文件\Task\Interface - - 源文件\Task\Roguelike - 源文件\Config\Miscellaneous @@ -477,6 +474,12 @@ 源文件\Task\SSS + + 源文件\Task\SSS + + + 源文件\Task\Miscellaneous + @@ -782,5 +785,8 @@ 源文件\Task\SSS + + 源文件\Task\SSS + \ No newline at end of file diff --git a/src/MaaCore/Task/Interface/SSSCopilotTask.cpp b/src/MaaCore/Task/Interface/SSSCopilotTask.cpp index d39aa34e5a..705f11360b 100644 --- a/src/MaaCore/Task/Interface/SSSCopilotTask.cpp +++ b/src/MaaCore/Task/Interface/SSSCopilotTask.cpp @@ -4,6 +4,7 @@ #include "Config/TaskData.h" #include "Task/Miscellaneous/BattleFormationTask.h" #include "Task/ProcessTask.h" +#include "Task/SSS/SSSDropRewardsTaskPlugin.h" #include "Task/SSS/SSSStageManagerTask.h" #include "Utils/Logger.hpp" #include "Utils/Platform.hpp" @@ -28,6 +29,7 @@ asst::SSSCopilotTask::SSSCopilotTask(const AsstCallback& callback, Assistant* in .set_ignore_error(false); m_subtasks.emplace_back(start_2_tp); + m_stage_task_ptr->register_plugin(); m_subtasks.emplace_back(m_stage_task_ptr); } diff --git a/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp new file mode 100644 index 0000000000..7846cbb54f --- /dev/null +++ b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp @@ -0,0 +1,60 @@ +#include "SSSDropRewardsTaskPlugin.h" + +#include "Config/Miscellaneous/BattleDataConfig.h" +#include "Config/Miscellaneous/SSSCopilotConfig.h" +#include "Controller.h" +#include "Task/ProcessTask.h" +#include "Task/SSS/SSSBattleProcessTask.h" +#include "Utils/Logger.hpp" +#include "Vision/OcrImageAnalyzer.h" +#include "Vision/OcrWithPreprocessImageAnalyzer.h" + +bool asst::SSSDropRewardsTaskPlugin::verify(AsstMsg msg, const json::value& details) const +{ + if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") { + return false; + } + + const std::string& task = details.get("details", "task", ""); + return task == "SSSDropRecruitmentFlag"; +} + +bool asst::SSSDropRewardsTaskPlugin::_run() +{ + using namespace battle; + LogTraceFunction; + + OcrImageAnalyzer analyzer(ctrler()->get_image()); + analyzer.set_task_info("SSSDropRecruitmentOCR"); + if (!analyzer.analyze()) { + Log.error(__FUNCTION__, "OCR failed to analyze"); + return false; + } + + struct DropRecruitment + { + TextRect ocr_res; + std::optional role; + }; + + std::vector opers; + for (const auto& result : analyzer.get_result()) { + auto role = BattleData.get_role(result.text); + opers.emplace_back(DropRecruitment { + .ocr_res = result, .role = role == Role::Unknown ? std::nullopt : std::optional(role) }); + } + + for (const std::string& name : SSSCopilot.get_data().drop_tool_men) { + auto role = get_role_type(name); + bool is_role = role != Role::Unknown; + auto iter = ranges::find_if(opers, [&](const DropRecruitment& props) { + return (is_role && props.role) ? *props.role == role : props.ocr_res.text == name; + }); + if (iter != opers.cend()) { + ctrler()->click(iter->ocr_res.rect); + break; + } + } + + return ProcessTask(*this, { "SSSDropRecruitmentConfrim" }).run(); +} diff --git a/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h new file mode 100644 index 0000000000..1261dc7a8a --- /dev/null +++ b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Task/AbstractTaskPlugin.h" + +namespace asst +{ + class SSSDropRewardsTaskPlugin : public AbstractTaskPlugin + { + public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~SSSDropRewardsTaskPlugin() noexcept override = default; + + virtual bool verify(AsstMsg msg, const json::value& details) const override; + + protected: + bool _run() override; + }; +} diff --git a/src/MaaCore/Task/SSS/SSSStageManagerTask.cpp b/src/MaaCore/Task/SSS/SSSStageManagerTask.cpp index 735142a53e..84ba3123e3 100644 --- a/src/MaaCore/Task/SSS/SSSStageManagerTask.cpp +++ b/src/MaaCore/Task/SSS/SSSStageManagerTask.cpp @@ -73,61 +73,13 @@ std::optional asst::SSSStageManagerTask::analyze_stage() bool asst::SSSStageManagerTask::comfirm_battle_complete() { - ProcessTask task(*this, { "SSSComfirmBattleComplete" }); - task.set_times_limit("SSSStartFighting", 0).set_times_limit("SSSBegin", 0); - if (!task.run()) { - return false; - } - - if (const std::string& last = task.get_last_task_name(); last == "SSSStartFighting") { - return true; - } - else if (last == "SSSDropRecruitmentFlag") { - get_drop_rewards(); - return false; - } - return false; + return ProcessTask(*this, { "SSSComfirmBattleComplete" }) + .set_times_limit("SSSStartFighting", 0) + .set_times_limit("SSSBegin", 0) + .run(); } -bool asst::SSSStageManagerTask::get_drop_rewards() -{ - using namespace battle; - LogTraceFunction; - - OcrImageAnalyzer analyzer(ctrler()->get_image()); - analyzer.set_task_info("SSSDropRecruitmentOCR"); - if (!analyzer.analyze()) { - Log.error(__FUNCTION__, "OCR failed to analyze"); - return false; - } - - struct DropRecruitment - { - TextRect ocr_res; - std::optional role; - }; - - std::vector opers; - for (const auto& result : analyzer.get_result()) { - auto role = BattleData.get_role(result.text); - opers.emplace_back(DropRecruitment { - .ocr_res = result, .role = role == Role::Unknown ? std::nullopt : std::optional(role) }); - } - - for (const std::string& name : SSSCopilot.get_data().drop_tool_men) { - auto role = get_role_type(name); - bool is_role = role != Role::Unknown; - auto iter = ranges::find_if(opers, [&](const DropRecruitment& props) { - return (is_role && props.role) ? *props.role == role : props.ocr_res.text == name; - }); - if (iter != opers.cend()) { - ctrler()->click(iter->ocr_res.rect); - break; - } - } - - return ProcessTask(*this, { "SSSDropRecruitmentConfrim" }).run(); -} +bool asst::SSSStageManagerTask::get_drop_rewards() {} bool asst::SSSStageManagerTask::click_start_button() {