From fcfe37c9288cfca81bbd2ce1f600547b9679af51 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sat, 31 Dec 2022 01:44:18 +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=E5=B9=B2=E5=91=98=E9=83=A8=E7=BD=B2=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/copilot/SSS_Test.json | 65 +++++------ resource/tasks.json | 13 ++- src/MaaCore/Common/AsstBattleDef.h | 5 +- .../Config/Miscellaneous/SSSCopilotConfig.cpp | 3 +- src/MaaCore/MaaCore.vcxproj | 5 +- src/MaaCore/MaaCore.vcxproj.filters | 6 + src/MaaCore/Task/BattleHelper.cpp | 2 +- src/MaaCore/Task/BattleHelper.h | 1 + src/MaaCore/Task/Interface/SSSCopilotTask.cpp | 22 ++-- src/MaaCore/Task/Interface/SSSCopilotTask.h | 4 +- .../Task/Miscellaneous/BattleProcessTask.cpp | 44 +++++--- .../Task/Miscellaneous/BattleProcessTask.h | 9 +- .../Miscellaneous/SSSBattleProcessTask.cpp | 106 ++++++++++++++++++ .../Task/Miscellaneous/SSSBattleProcessTask.h | 25 +++++ 14 files changed, 236 insertions(+), 74 deletions(-) create mode 100644 src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp create mode 100644 src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h diff --git a/resource/copilot/SSS_Test.json b/resource/copilot/SSS_Test.json index 32a450ea3d..c17800b757 100644 --- a/resource/copilot/SSS_Test.json +++ b/resource/copilot/SSS_Test.json @@ -3,7 +3,7 @@ "stage_name": "多索雷斯在建地块", "minimum_required": "v4.9.0", "doc": { - "title": "保全测试作业", + "title": "保全测试作业" }, "buff": "镀膜装置导能阀", "equipment": [ @@ -26,6 +26,11 @@ "name": "水月", "skill": 2, "skill_usage": 1 + }, + { + "name": "桃金娘", + "skill": 2, + "skill_usage": 1 } ], "tool_men": { @@ -48,28 +53,24 @@ "stage_name": "蜂拥而上", "strategies": [ { - "core": "棘刺", + "core": "泥岩", "tool_men": { - "Pioneer": 1, - "Warrior": 1, - "Medic": 1 + "Pioneer": 2 }, "location": [ - 10, - 1 + 6, + 2 ], "direction": "Left" }, { - "core": "泥岩", + "core": "水月", "tool_men": { - "Pioneer": 1, - "Warrior": 1, - "Medic": 1 + "Warrior": 2 }, "location": [ - 2, - 8 + 5, + 2 ], "direction": "Left" }, @@ -78,42 +79,36 @@ "Support": 100 }, "location": [ - 2, - 8 + 5, + 3 ], "direction": "Left" } ], "draw_as_possible": true, "actions": [ - { - "type": "调配干员" - }, - { - "type": "CheckIfStartOver", - "name": "棘刺" - }, - { - "type": "CheckIfStartOver", - "tool_men": { - "Pioneer": 2 - } - }, { "name": "桃金娘", "location": [ - 4, - 5 + 5, + 4 ], - "direction": "左" + "direction": "下" }, { - "kills": 10, - "type": "撤退", - "name": "桃金娘" + "kills": 1000, + "name": "桃金娘", + "location": [ + 5, + 4 + ], + "direction": "下" + }, + { + "type": "摆完挂机" } ], "retry_times": 3 } ] -} \ No newline at end of file +} diff --git a/resource/tasks.json b/resource/tasks.json index f2597ebc12..8d1881a6e1 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -5968,10 +5968,21 @@ "roi": [ 0, 182, - 160, + 200, 30 ] }, + "SSSBattleOperName": { + "algorithm": "OcrDetect", + "text": [], + "fullMatch": true, + "roi": [ + 0, + 102, + 190, + 37 + ] + }, "BattleOfficiallyBegin": { "action": "DoNothing", "roi": [ diff --git a/src/MaaCore/Common/AsstBattleDef.h b/src/MaaCore/Common/AsstBattleDef.h index 2cf989c31a..d7c4d81a20 100644 --- a/src/MaaCore/Common/AsstBattleDef.h +++ b/src/MaaCore/Common/AsstBattleDef.h @@ -196,11 +196,9 @@ namespace asst::battle DeployDirection direction = DeployDirection::None; }; - struct CombatData + struct CombatData : public copilot::CombatData { - std::string stage_name; std::vector strategies; - std::vector actions; bool draw_as_possible = false; }; @@ -222,7 +220,6 @@ namespace asst::battle copilot::OperUsageGroups groups; RoleCounts tool_men; std::vector drop_buffs; - std::vector drop_tool_men; std::vector stages_data; diff --git a/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.cpp b/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.cpp index 8e169b9317..0d9cbc9847 100644 --- a/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.cpp +++ b/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.cpp @@ -68,7 +68,7 @@ bool asst::SSSCopilotConfig::parse(const json::value& json) } for (const auto& stage : json.at("stages").as_array()) { CombatData stage_data; - stage_data.stage_name = stage.at("stage_name").as_string(); + stage_data.info = CopilotConfig::parse_basic_info(stage); stage_data.draw_as_possible = stage.at("draw_as_possible").as_boolean(); stage_data.actions = CopilotConfig::parse_actions(stage); @@ -76,6 +76,7 @@ bool asst::SSSCopilotConfig::parse(const json::value& json) for (const auto& strategy_info : stage.at("strategies").as_array()) { Strategy strategy; strategy.core = strategy_info.get("core", std::string()); + strategy.tool_men = CopilotConfig::parse_role_counts(strategy_info.at("tool_men")); strategy.location.x = strategy_info.at("location").at(0).as_integer(); strategy.location.y = strategy_info.at("location").at(1).as_integer(); strategy.direction = CopilotConfig::string_to_direction(strategy_info.get("direction", "Right")); diff --git a/src/MaaCore/MaaCore.vcxproj b/src/MaaCore/MaaCore.vcxproj index 53ea06b7f1..3c457db70e 100644 --- a/src/MaaCore/MaaCore.vcxproj +++ b/src/MaaCore/MaaCore.vcxproj @@ -33,6 +33,7 @@ + @@ -152,6 +153,7 @@ + @@ -251,6 +253,7 @@ MaaCore 10.0 MaaCore + x64 @@ -400,4 +403,4 @@ - \ No newline at end of file + diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters index 36d98add0c..3cb10169bf 100644 --- a/src/MaaCore/MaaCore.vcxproj.filters +++ b/src/MaaCore/MaaCore.vcxproj.filters @@ -465,6 +465,9 @@ 源文件\Task\Interface + + 源文件\Task\Miscellaneous + @@ -761,5 +764,8 @@ 源文件\Task\Interface + + 源文件\Task\Miscellaneous + \ No newline at end of file diff --git a/src/MaaCore/Task/BattleHelper.cpp b/src/MaaCore/Task/BattleHelper.cpp index baab5e710d..089c1adaf2 100644 --- a/src/MaaCore/Task/BattleHelper.cpp +++ b/src/MaaCore/Task/BattleHelper.cpp @@ -219,7 +219,7 @@ bool asst::BattleHelper::update_deployment(bool init, const cv::Mat& reusable) click_oper_on_deployment(oper.rect); OcrWithPreprocessImageAnalyzer name_analyzer(m_inst_helper.ctrler()->get_image()); - name_analyzer.set_task_info("BattleOperName"); + name_analyzer.set_task_info(oper_name_ocr_task_name()); name_analyzer.set_replace(Task.get("CharsNameOcrReplace")->replace_map); if (!name_analyzer.analyze()) { Log.error("ocr failed"); diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index 512a4ba093..682f1e195e 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -28,6 +28,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"; } bool calc_tiles_info(const std::string& stage_name); bool load_avatar_cache(const std::string& name, bool with_token = false); diff --git a/src/MaaCore/Task/Interface/SSSCopilotTask.cpp b/src/MaaCore/Task/Interface/SSSCopilotTask.cpp index a6783ed44e..b6cfb7a37a 100644 --- a/src/MaaCore/Task/Interface/SSSCopilotTask.cpp +++ b/src/MaaCore/Task/Interface/SSSCopilotTask.cpp @@ -3,7 +3,7 @@ #include "Config/Miscellaneous/SSSCopilotConfig.h" #include "Config/TaskData.h" #include "Task/Miscellaneous/BattleFormationTask.h" -#include "Task/Miscellaneous/BattleProcessTask.h" +#include "Task/Miscellaneous/SSSBattleProcessTask.h" #include "Task/ProcessTask.h" #include "Utils/Logger.hpp" #include "Utils/Platform.hpp" @@ -12,17 +12,17 @@ asst::SSSCopilotTask::SSSCopilotTask(const AsstCallback& callback, Assistant* in : InterfaceTask(callback, inst, TaskType), m_begin_task_ptr(std::make_shared(callback, inst, TaskType)), m_formation_task_ptr(std::make_shared(callback, inst, TaskType)), - m_battle_task_ptr(std::make_shared(callback, inst, TaskType)) + m_battle_task_ptr(std::make_shared(callback, inst, TaskType)) { - m_begin_task_ptr->set_tasks({ inst_string() + "@SSSBegin" }).set_ignore_error(false); - m_subtasks.emplace_back(m_begin_task_ptr); + // m_begin_task_ptr->set_tasks({ inst_string() + "@SSSBegin" }).set_ignore_error(false); + // m_subtasks.emplace_back(m_begin_task_ptr); - m_formation_task_ptr->set_data_resource(BattleFormationTask::DataResource::SSSCopilot); - m_subtasks.emplace_back(m_formation_task_ptr); + // m_formation_task_ptr->set_data_resource(BattleFormationTask::DataResource::SSSCopilot); + // m_subtasks.emplace_back(m_formation_task_ptr); - auto start_2_tp = std::make_shared(callback, inst, TaskType); - start_2_tp->set_tasks({ inst_string() + "@SSSTeamConfirm" }).set_ignore_error(false); - m_subtasks.emplace_back(start_2_tp); + // auto start_2_tp = std::make_shared(callback, inst, TaskType); + // start_2_tp->set_tasks({ inst_string() + "@SSSTeamConfirm" }).set_ignore_error(false); + // m_subtasks.emplace_back(start_2_tp); m_subtasks.emplace_back(m_battle_task_ptr)->set_retry_times(0); } @@ -62,5 +62,9 @@ bool asst::SSSCopilotTask::set_params(const json::value& params) }; m_formation_task_ptr->append_additional_formation(std::move(additional_formation)); + // for debug + m_battle_task_ptr->set_stage_index(0); + m_battle_task_ptr->set_stage_name("蜂拥而上"); + return true; } diff --git a/src/MaaCore/Task/Interface/SSSCopilotTask.h b/src/MaaCore/Task/Interface/SSSCopilotTask.h index 14e305b1c8..725929838b 100644 --- a/src/MaaCore/Task/Interface/SSSCopilotTask.h +++ b/src/MaaCore/Task/Interface/SSSCopilotTask.h @@ -5,7 +5,7 @@ namespace asst { - class BattleProcessTask; + class SSSBattleProcessTask; class BattleFormationTask; class ProcessTask; @@ -23,6 +23,6 @@ namespace asst private: std::shared_ptr m_begin_task_ptr = nullptr; std::shared_ptr m_formation_task_ptr = nullptr; - std::shared_ptr m_battle_task_ptr = nullptr; + std::shared_ptr m_battle_task_ptr = nullptr; }; } diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp index 70c701e6a5..bccc50ba0b 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp @@ -41,7 +41,7 @@ bool asst::BattleProcessTask::_run() update_deployment(true); to_group(); - for (size_t i = 0; i < m_combat_data.actions.size() && !need_exit(); ++i) { + for (size_t i = 0; i < get_combat_data().actions.size() && !need_exit(); ++i) { do_action(i); } @@ -56,6 +56,11 @@ 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; @@ -78,7 +83,7 @@ void asst::BattleProcessTask::load_cache() { LogTraceFunction; - for (const auto& oper_list : m_combat_data.groups | views::values) { + for (const auto& oper_list : get_combat_data().groups | views::values) { for (const auto& oper : oper_list) { load_avatar_cache(oper.name, true); } @@ -89,7 +94,7 @@ void asst::BattleProcessTask::load_cache() bool asst::BattleProcessTask::to_group() { std::unordered_map> groups; - for (const auto& [group_name, oper_list] : m_combat_data.groups) { + for (const auto& [group_name, oper_list] : get_combat_data().groups) { std::vector oper_name_list; ranges::transform(oper_list, std::back_inserter(oper_name_list), [](const auto& oper) { return oper.name; }); groups.emplace(group_name, std::move(oper_name_list)); @@ -125,7 +130,7 @@ bool asst::BattleProcessTask::to_group() } for (const auto& [group_name, oper_name] : m_oper_in_group) { - auto& this_group = m_combat_data.groups[group_name]; + auto& this_group = get_combat_data().groups[group_name]; // there is a build error on macOS // https://github.com/MaaAssistantArknights/MaaAssistantArknights/actions/runs/3779762713/jobs/6425284487 const std::string& oper_name_for_lambda = oper_name; @@ -141,7 +146,7 @@ bool asst::BattleProcessTask::to_group() bool asst::BattleProcessTask::do_action(size_t action_index) { - const auto& action = m_combat_data.actions.at(action_index); + const auto& action = get_combat_data().actions.at(action_index); notify_action(action); @@ -149,7 +154,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index) return false; } if (action.pre_delay > 0) { - sleep_with_use_ready_skill(action.pre_delay); + sleep_and_do_not_urgent(action.pre_delay); // 等待之后画面可能会变化,更新下干员信息 update_deployment(); } @@ -196,9 +201,12 @@ bool asst::BattleProcessTask::do_action(size_t action_index) case ActionType::SkillDaemon: ret = wait_for_end(); break; + default: + ret = do_derived_action(action_index); + break; } - sleep_with_use_ready_skill(action.post_delay); + sleep_and_do_not_urgent(action.post_delay); return ret; } @@ -228,8 +236,8 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) auto update_image_if_empty = [&]() { if (image.empty()) image = ctrler()->get_image(); }; - auto use_all_ready_skill_then_update_image = [&]() { - use_all_ready_skill(image); + auto do_strategy_and_update_image = [&]() { + do_strategic_action(image); image = ctrler()->get_image(); }; @@ -246,7 +254,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) break; } } - use_all_ready_skill_then_update_image(); + do_strategy_and_update_image(); } while (!need_exit()); } @@ -257,7 +265,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) if (m_kills >= action.kills) { break; } - use_all_ready_skill_then_update_image(); + do_strategy_and_update_image(); } } @@ -268,7 +276,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) if (m_cost >= action.costs) { break; } - use_all_ready_skill_then_update_image(); + do_strategy_and_update_image(); } } @@ -282,7 +290,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) if (cooling_count == action.cooling) { break; } - use_all_ready_skill_then_update_image(); + do_strategy_and_update_image(); } } @@ -296,7 +304,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action) iter != m_cur_deployment_opers.cend() && iter->second.available) { break; } - use_all_ready_skill_then_update_image(); + do_strategy_and_update_image(); } } @@ -308,11 +316,11 @@ bool asst::BattleProcessTask::enter_bullet_time_for_next_action(size_t next_inde { LogTraceFunction; - if (next_index > m_combat_data.actions.size()) { + if (next_index > get_combat_data().actions.size()) { Log.error("Bullet time does not have the next step!"); return false; } - const auto& next_action = m_combat_data.actions.at(next_index); + const auto& next_action = get_combat_data().actions.at(next_index); bool ret = false; switch (next_action.type) { @@ -333,7 +341,7 @@ bool asst::BattleProcessTask::enter_bullet_time_for_next_action(size_t next_inde return ret; } -void asst::BattleProcessTask::sleep_with_use_ready_skill(unsigned millisecond) +void asst::BattleProcessTask::sleep_and_do_not_urgent(unsigned millisecond) { LogTraceScope(__FUNCTION__ + std::to_string(millisecond)); @@ -342,7 +350,7 @@ void asst::BattleProcessTask::sleep_with_use_ready_skill(unsigned millisecond) const auto delay = millisecond * 1ms; while (!need_exit() && std::chrono::steady_clock::now() - start < delay) { - use_all_ready_skill(); + do_strategic_action(); std::this_thread::yield(); } } diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h index ccdef0eadd..2c40f324e7 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h @@ -9,7 +9,7 @@ namespace asst { - class BattleProcessTask : public AbstractTask, private BattleHelper + class BattleProcessTask : public AbstractTask, public BattleHelper { public: BattleProcessTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); @@ -22,13 +22,18 @@ namespace asst virtual AbstractTask& this_task() override { return *this; } 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; } + void load_cache(); bool to_group(); bool do_action(size_t action_index); + 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_with_use_ready_skill(unsigned millisecond); + void sleep_and_do_not_urgent(unsigned millisecond); battle::copilot::CombatData m_combat_data; std::unordered_map m_oper_in_group; diff --git a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp new file mode 100644 index 0000000000..3b9cb0c120 --- /dev/null +++ b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp @@ -0,0 +1,106 @@ +#include "SSSBattleProcessTask.h" + +#include "Config/Miscellaneous/SSSCopilotConfig.h" +#include "Controller.h" +#include "Utils/Logger.hpp" + +using namespace asst::battle; +using namespace asst::battle::sss; + +bool asst::SSSBattleProcessTask::set_stage_name(const std::string& stage_name) +{ + LogTraceFunction; + + if (!BattleHelper::set_stage_name(stage_name)) { + json::value info = basic_info_with_what("UnsupportedLevel"); + auto& details = info["details"]; + details["level"] = m_stage_name; + callback(AsstMsg::SubTaskExtraInfo, info); + + return false; + } + if (m_stage_index >= SSSCopilot.stages_size()) { + Log.error("SSS CopilotConfig: stage index out of range", m_stage_index); + return false; + } + + m_sss_combat_data = SSSCopilot.get_data(m_stage_index); + ranges::transform(m_sss_combat_data.strategies, std::inserter(m_all_cores, m_all_cores.begin()), + [](const auto& strategy) { return strategy.core; }); + + return true; +} + +bool asst::SSSBattleProcessTask::set_stage_index(size_t index) +{ + Log.info(__FUNCTION__, index); + + if (index >= SSSCopilot.stages_size()) { + return false; + } + m_stage_index = index; + return true; +} + +bool asst::SSSBattleProcessTask::do_derived_action(size_t action_index) +{ + LogTraceFunction; + + std::ignore = action_index; + + return false; +} + +bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) +{ + LogTraceFunction; + + cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable; + update_deployment(false, image); + + std::unordered_map exist_core; + std::unordered_map available_tool_men; + for (const auto& [name, oper] : m_cur_deployment_opers) { + if (m_all_cores.contains(name)) { + exist_core.emplace(name, oper); + } + else if (oper.available) { + available_tool_men.emplace(oper.role, oper); + } + } + + for (auto& strategy : m_sss_combat_data.strategies) { + bool use_the_core = ranges::all_of(strategy.tool_men, [](const auto& pair) { return pair.second <= 0; }) && + !strategy.core.empty() && exist_core.contains(strategy.core); + if (use_the_core) { + const auto& core = exist_core.at(strategy.core); + if (!core.available) { + // 直接返回,等费用,等下次循环处理部署逻辑 + return true; + } + // 部署完,画面会发生变化,所以直接返回,后续逻辑交给下次循环处理 + return deploy_oper(strategy.core, strategy.location, strategy.direction); + } + + for (auto& [role, quantity] : strategy.tool_men) { + if (quantity <= 0) { + continue; + } + // for apple-clang build error + Role role_for_lambda = role; + auto iter = ranges::find_if(available_tool_men, + [role_for_lambda](const auto& pair) { return pair.first == role_for_lambda; }); + if (iter == available_tool_men.end()) { + continue; + } + + --quantity; + // 部署完,画面会发生变化,所以直接返回,后续逻辑交给下次循环处理 + return deploy_oper(iter->second.name, strategy.location, strategy.direction); + } + } + + use_all_ready_skill(image); + + return true; +} diff --git a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h new file mode 100644 index 0000000000..dd0a325c73 --- /dev/null +++ b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h @@ -0,0 +1,25 @@ +#pragma once +#include "BattleProcessTask.h" + +namespace asst +{ + class SSSBattleProcessTask : public BattleProcessTask + { + public: + using BattleProcessTask::BattleProcessTask; + virtual ~SSSBattleProcessTask() override = default; + + bool set_stage_index(size_t index); + virtual bool set_stage_name(const std::string& stage_name) override; + + protected: + virtual bool do_derived_action(size_t action_index) override; + 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"; } + + battle::sss::CombatData m_sss_combat_data; + std::unordered_set m_all_cores; + size_t m_stage_index = SIZE_MAX; + }; +}