From f3714a000fc1c1395e5fa7b929bc2ad53cf550aa Mon Sep 17 00:00:00 2001 From: MistEO Date: Mon, 2 Jan 2023 02:58:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E4=BF=9D=E5=85=A8=E9=83=A8=E7=BD=B2=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/copilot/SSS_Test.json | 12 ---- resource/tasks.json | 9 +++ resource/template/SSSDrawCard.png | Bin 0 -> 3433 bytes src/MaaCore/Common/AsstBattleDef.h | 2 +- .../Config/Miscellaneous/CopilotConfig.cpp | 2 +- src/MaaCore/MaaCore.vcxproj.filters | 6 +- src/MaaCore/Task/BattleHelper.cpp | 18 ++++-- src/MaaCore/Task/BattleHelper.h | 6 +- .../Task/Miscellaneous/BattleProcessTask.cpp | 21 ++++--- .../Task/Miscellaneous/BattleProcessTask.h | 2 +- .../Miscellaneous/SSSBattleProcessTask.cpp | 53 +++++++++++++++++- .../Task/Miscellaneous/SSSBattleProcessTask.h | 4 ++ .../Roguelike/RoguelikeBattleTaskPlugin.cpp | 9 +-- .../Roguelike/RoguelikeBattleTaskPlugin.h | 3 +- 14 files changed, 101 insertions(+), 46 deletions(-) create mode 100644 resource/template/SSSDrawCard.png diff --git a/resource/copilot/SSS_Test.json b/resource/copilot/SSS_Test.json index c17800b757..6c09832f46 100644 --- a/resource/copilot/SSS_Test.json +++ b/resource/copilot/SSS_Test.json @@ -94,18 +94,6 @@ 4 ], "direction": "下" - }, - { - "kills": 1000, - "name": "桃金娘", - "location": [ - 5, - 4 - ], - "direction": "下" - }, - { - "type": "摆完挂机" } ], "retry_times": 3 diff --git a/resource/tasks.json b/resource/tasks.json index 8d1881a6e1..7d021b3146 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -9505,5 +9505,14 @@ 288, 144 ] + }, + "SSSDrawCard": { + "action": "ClickSelf", + "roi": [ + 1151, + 319, + 129, + 157 + ] } } diff --git a/resource/template/SSSDrawCard.png b/resource/template/SSSDrawCard.png new file mode 100644 index 0000000000000000000000000000000000000000..1ecbbe66d231fb0925429e14b7d902e437aa23cf GIT binary patch literal 3433 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 SwitchSpeed, group_name 为空 + std::string name; // 目标名,若 type >= SwitchSpeed, name 为空 Point location; DeployDirection direction = DeployDirection::Right; SkillUsage modify_usage = SkillUsage::NotUse; diff --git a/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp b/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp index 49baaa053f..775708f523 100644 --- a/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp +++ b/src/MaaCore/Config/Miscellaneous/CopilotConfig.cpp @@ -163,7 +163,7 @@ std::vector asst::CopilotConfig::parse_actions(co action.cost_changes = action_info.get("cost_changes", 0); action.costs = action_info.get("costs", 0); action.cooling = action_info.get("cooling", -1); - action.group_name = action_info.get("name", std::string()); + action.name = action_info.get("name", std::string()); action.location.x = action_info.get("location", 0, 0); action.location.y = action_info.get("location", 1, 0); diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters index 3cb10169bf..68adfbfc4d 100644 --- a/src/MaaCore/MaaCore.vcxproj.filters +++ b/src/MaaCore/MaaCore.vcxproj.filters @@ -417,9 +417,6 @@ 源文件\Task\Miscellaneous - - 源文件\Task\Miscellaneous - 源文件\Task\Roguelike @@ -468,6 +465,9 @@ 源文件\Task\Miscellaneous + + 源文件\Task\Roguelike + diff --git a/src/MaaCore/Task/BattleHelper.cpp b/src/MaaCore/Task/BattleHelper.cpp index 089c1adaf2..f4154ee3c0 100644 --- a/src/MaaCore/Task/BattleHelper.cpp +++ b/src/MaaCore/Task/BattleHelper.cpp @@ -121,12 +121,17 @@ bool asst::BattleHelper::speed_up() return ProcessTask(this_task(), { "BattleSpeedUp" }).run(); } +bool asst::BattleHelper::abandon() +{ + return ProcessTask(this_task(), { "RoguelikeBattleExitBegin" }).run(); +} + bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) { LogTraceFunction; if (init) { - wait_for_start(); + wait_until_start(); } cv::Mat image = init || reusable.empty() ? m_inst_helper.ctrler()->get_image() : reusable; @@ -406,7 +411,7 @@ bool asst::BattleHelper::check_pause_button() return battle_flag_analyzer.analyze(); } -bool asst::BattleHelper::wait_for_start() +bool asst::BattleHelper::wait_until_start() { LogTraceFunction; @@ -416,17 +421,22 @@ bool asst::BattleHelper::wait_for_start() return true; } -bool asst::BattleHelper::wait_for_end() +bool asst::BattleHelper::wait_until_end() { LogTraceFunction; while (!m_inst_helper.need_exit() && check_pause_button()) { - use_all_ready_skill(); + do_strategic_action(); std::this_thread::yield(); } return true; } +bool asst::BattleHelper::do_strategic_action(const cv::Mat& reusable) +{ + return use_all_ready_skill(reusable); +} + bool asst::BattleHelper::use_all_ready_skill(const cv::Mat& reusable) { bool used = false; diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index 682f1e195e..9ce41741a5 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -29,6 +29,7 @@ namespace asst virtual bool set_stage_name(const std::string& name); virtual void clear(); virtual const std::string oper_name_ocr_task_name() const noexcept { return "BattleOperName"; } + virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()); bool calc_tiles_info(const std::string& stage_name); bool load_avatar_cache(const std::string& name, bool with_token = false); @@ -36,6 +37,7 @@ namespace asst bool pause(); bool speed_up(); + bool abandon(); bool update_deployment(bool init = false, const cv::Mat& reusable = cv::Mat()); bool update_kills(const cv::Mat& reusable = cv::Mat()); @@ -47,8 +49,8 @@ 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(); - bool wait_for_start(); - bool wait_for_end(); + bool wait_until_start(); + bool wait_until_end(); bool use_all_ready_skill(const cv::Mat& reusable = cv::Mat()); bool check_and_use_skill(const std::string& name, const cv::Mat& reusable = cv::Mat()); bool check_and_use_skill(const Point& loc, const cv::Mat& reusable = cv::Mat()); diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp index bccc50ba0b..2b2a3a1b6d 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp @@ -45,6 +45,10 @@ bool asst::BattleProcessTask::_run() do_action(i); } + if (need_to_wait_until_end()) { + wait_until_end(); + } + return true; } @@ -56,11 +60,6 @@ void asst::BattleProcessTask::clear() m_in_bullet_time = false; } -bool asst::BattleProcessTask::do_strategic_action(const cv::Mat& reusable) -{ - return use_all_ready_skill(reusable); -} - bool asst::BattleProcessTask::set_stage_name(const std::string& stage_name) { LogTraceFunction; @@ -122,7 +121,7 @@ bool asst::BattleProcessTask::to_group() m_oper_in_group.merge(ungrouped); for (const auto& action : m_combat_data.actions) { - const std::string& action_name = action.group_name; + const std::string& action_name = action.name; if (action_name.empty() || m_oper_in_group.contains(action_name)) { continue; } @@ -160,7 +159,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index) } bool ret = false; - const std::string& name = m_oper_in_group[action.group_name]; + const std::string& name = m_oper_in_group[action.name]; const auto& location = action.location; switch (action.type) { @@ -189,7 +188,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index) break; case ActionType::SkillUsage: - m_skill_usage[action.group_name] = action.modify_usage; + m_skill_usage[action.name] = action.modify_usage; ret = true; break; @@ -199,7 +198,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index) break; case ActionType::SkillDaemon: - ret = wait_for_end(); + ret = wait_until_end(); break; default: ret = do_derived_action(action_index); @@ -223,7 +222,7 @@ void asst::BattleProcessTask::notify_action(const battle::copilot::Action& actio json::value info = basic_info_with_what("CopilotAction"); info["details"] |= json::object { { "action", ActionNames.at(action.type) }, - { "target", action.group_name }, + { "target", action.name }, { "doc", action.doc }, { "doc_color", action.doc_color }, }; @@ -296,7 +295,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) // 部署干员还有额外等待费用够或 CD 转好 if (!m_in_bullet_time && action.type == ActionType::Deploy) { - const std::string& name = m_oper_in_group[action.group_name]; + const std::string& name = m_oper_in_group[action.name]; update_image_if_empty(); while (!need_exit()) { update_deployment(false, image); diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h index 2c40f324e7..d79ae23701 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h @@ -23,8 +23,8 @@ namespace asst virtual void clear() override; virtual bool do_derived_action([[maybe_unused]] size_t action_index) { return false; } - virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()); virtual battle::copilot::CombatData& get_combat_data() { return m_combat_data; } + virtual bool need_to_wait_until_end() const { return false; } void load_cache(); bool to_group(); diff --git a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp index 3b9cb0c120..1704cc6cb8 100644 --- a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp @@ -2,6 +2,7 @@ #include "Config/Miscellaneous/SSSCopilotConfig.h" #include "Controller.h" +#include "Task/ProcessTask.h" #include "Utils/Logger.hpp" using namespace asst::battle; @@ -46,9 +47,17 @@ bool asst::SSSBattleProcessTask::do_derived_action(size_t action_index) { LogTraceFunction; - std::ignore = action_index; + const auto& action = get_combat_data().actions.at(action_index); - return false; + switch (action.type) { + case battle::copilot::ActionType::DrawCard: + return draw_card(); + case battle::copilot::ActionType::CheckIfStartOver: + return check_if_start_over(action); + default: + Log.error("unknown action type", static_cast(action.type)); + return false; + } } bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) @@ -100,7 +109,47 @@ bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) } } + if (m_sss_combat_data.draw_as_possible) { + draw_card(); + } + use_all_ready_skill(image); return true; } + +bool asst::SSSBattleProcessTask::check_if_start_over(const battle::copilot::Action& action) +{ + LogTraceFunction; + + update_deployment(); + + bool to_abandon = false; + if (!action.name.empty() && !m_cur_deployment_opers.contains(action.name) && + !m_battlefield_opers.contains(action.name)) { + to_abandon = true; + } + else if (!action.role_counts.empty()) { + std::unordered_map cur_counts; + for (const auto& oper : m_cur_deployment_opers | views::values) { + cur_counts[oper.role] += 1; + } + for (const auto& [role, number] : action.role_counts) { + if (cur_counts[role] < number) { + to_abandon = true; + break; + } + } + } + + if (to_abandon) { + abandon(); + } + + return true; +} + +bool asst::SSSBattleProcessTask::draw_card() +{ + return ProcessTask(*this, { "SSSDrawCard" }).run(); +} diff --git a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h index dd0a325c73..fd928e7fd3 100644 --- a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h +++ b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h @@ -17,6 +17,10 @@ namespace asst virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()) override; virtual battle::copilot::CombatData& get_combat_data() { return m_sss_combat_data; } virtual const std::string oper_name_ocr_task_name() const noexcept { return "SSSBattleOperName"; } + virtual bool need_to_wait_until_end() const { return true; } + + bool check_if_start_over(const battle::copilot::Action& action); + bool draw_card(); battle::sss::CombatData m_sss_combat_data; std::unordered_set m_all_cores; diff --git a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp index 6e3d1cce31..2463fd7f63 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp @@ -91,7 +91,7 @@ bool asst::RoguelikeBattleTaskPlugin::_run() return true; } -void asst::RoguelikeBattleTaskPlugin::wait_for_start_button_clicked() +void asst::RoguelikeBattleTaskPlugin::wait_until_start_button_clicked() { ProcessTask(*this, { "RoguelikeWaitForStartButtonClicked" }).set_task_delay(0).set_retry_times(0).run(); } @@ -110,7 +110,7 @@ bool asst::RoguelikeBattleTaskPlugin::calc_stage_info() { LogTraceFunction; - wait_for_start_button_clicked(); + wait_until_start_button_clicked(); clear(); bool calced = false; @@ -609,11 +609,6 @@ std::optional asst::RoguelikeBattleTaskPlugin::cal return best_oper; } -bool asst::RoguelikeBattleTaskPlugin::abandon() -{ - return ProcessTask(*this, { "RoguelikeBattleExitBegin" }).run(); -} - void asst::RoguelikeBattleTaskPlugin::all_melee_retreat() { for (const auto& loc : m_used_tiles | views::keys) { diff --git a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h index 5a39cd7649..0e8bf112e5 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h @@ -34,7 +34,6 @@ namespace asst void load_cache(); void all_melee_retreat(); - bool abandon(); std::optional check_urgent(const std::unordered_set& pre_cooling, const std::unordered_set& cur_cooling, @@ -63,7 +62,7 @@ namespace asst battle::DeployDirection direction); void check_drone_tiles(); - void wait_for_start_button_clicked(); + void wait_until_start_button_clicked(); std::string oper_name_in_config(const battle::DeploymentOper& oper) const; battle::LocationType get_oper_location_type(const battle::DeploymentOper& oper) const;