mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-16 01:40:46 +08:00
feat.支持肉鸽干员技能选择字段
This commit is contained in:
BIN
3rdparty/resource/PaddleOCR/det/inference.pdiparams
vendored
BIN
3rdparty/resource/PaddleOCR/det/inference.pdiparams
vendored
Binary file not shown.
BIN
3rdparty/resource/PaddleOCR/det/inference.pdmodel
vendored
BIN
3rdparty/resource/PaddleOCR/det/inference.pdmodel
vendored
Binary file not shown.
2
3rdparty/resource/PaddleOCR/det/version.txt
vendored
2
3rdparty/resource/PaddleOCR/det/version.txt
vendored
@@ -1 +1 @@
|
||||
ch_PP-OCRv2_det_slim_quant_infer
|
||||
ch_PP-OCRv2_det_infer
|
||||
@@ -127,8 +127,9 @@ TaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const char* p
|
||||
"opers": [ // 会去选择的干员,必选项。数组有序
|
||||
{
|
||||
"name": string, // 干员名,必选项
|
||||
"fullMatch": bool, // 干员名是否需要全字匹配,可选项。默认 false
|
||||
"skill": int, // 使用哪个技能,取值范围 [1, 3],可选项,默认 1
|
||||
// 若设置为 3, 当 3 技能不可用时,会选择 2 技能
|
||||
// 同理若设置为 2, 当 2 技能不可用时,会选择 1 技能(好像没有这种 case?)
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
@@ -3933,6 +3933,10 @@
|
||||
[
|
||||
"蛇居箱",
|
||||
"蛇屠箱"
|
||||
],
|
||||
[
|
||||
".+刺",
|
||||
"棘刺"
|
||||
]
|
||||
],
|
||||
"roi": [
|
||||
@@ -4604,8 +4608,57 @@
|
||||
"Roguelike1StartAction"
|
||||
]
|
||||
},
|
||||
"Roguelike1SkillSelectionFlag": {
|
||||
"templThreshold": 0.9,
|
||||
"maskRange": [
|
||||
1,
|
||||
255
|
||||
]
|
||||
},
|
||||
"Roguelike1SkillSelectionName": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [],
|
||||
"action": "DoNothing",
|
||||
"ocrReplace": [
|
||||
[
|
||||
"白面.+",
|
||||
"白面鸮"
|
||||
],
|
||||
[
|
||||
"蛇居箱",
|
||||
"蛇屠箱"
|
||||
],
|
||||
[
|
||||
".+刺",
|
||||
"棘刺"
|
||||
]
|
||||
],
|
||||
"rectMove": [
|
||||
150,
|
||||
-30,
|
||||
180,
|
||||
65
|
||||
]
|
||||
},
|
||||
"Roguelike1SkillSelectionRect": {
|
||||
"template": "empty.png",
|
||||
"roi": [
|
||||
171,
|
||||
2,
|
||||
170,
|
||||
3
|
||||
],
|
||||
"rectMove": [
|
||||
5,
|
||||
-45,
|
||||
45,
|
||||
45
|
||||
],
|
||||
"templThreshold": 60,
|
||||
"Doc": "这里的阈值作为平均灰度值(亮度)阈值使用"
|
||||
},
|
||||
"Roguelike1StartAction": {
|
||||
"Doc": "本任务注册了插件 RoguelikeBattleTaskPlugin",
|
||||
"Doc": "本任务注册了插件 RoguelikeSkillSelectionTaskPlugin、RoguelikeBattleTaskPlugin",
|
||||
"action": "ClickSelf",
|
||||
"roi": [
|
||||
905,
|
||||
|
||||
BIN
resource/template/Roguelike1SkillSelectionFlag.png
Normal file
BIN
resource/template/Roguelike1SkillSelectionFlag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -19,6 +19,9 @@
|
||||
#include "InfrastTask.h"
|
||||
#include "RecruitTask.h"
|
||||
#include "RoguelikeTask.h"
|
||||
#ifdef ASST_DEBUG
|
||||
#include "DebugTask.h"
|
||||
#endif
|
||||
|
||||
using namespace asst;
|
||||
|
||||
@@ -104,6 +107,11 @@ asst::Assistant::TaskId asst::Assistant::append_task(const std::string& type, co
|
||||
else if (type == RoguelikeTask::TaskType) {
|
||||
ptr = std::make_shared<RoguelikeTask>(task_callback, (void*)this);
|
||||
}
|
||||
#ifdef ASST_DEBUG
|
||||
else if (type == DebugTask::TaskType) {
|
||||
ptr = std::make_shared<DebugTask>(task_callback, (void*)this);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
Log.error(__FUNCTION__, "| invalid type:", type);
|
||||
return 0;
|
||||
|
||||
10
src/MeoAssistant/DebugTask.cpp
Normal file
10
src/MeoAssistant/DebugTask.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "DebugTask.h"
|
||||
|
||||
#include "RoguelikeSkillSelectionTaskPlugin.h"
|
||||
|
||||
asst::DebugTask::DebugTask(AsstCallback callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType)
|
||||
{
|
||||
auto task_ptr = std::make_shared<RoguelikeSkillSelectionTaskPlugin>(callback, callback_arg, TaskType);
|
||||
m_subtasks.emplace_back(task_ptr);
|
||||
}
|
||||
14
src/MeoAssistant/DebugTask.h
Normal file
14
src/MeoAssistant/DebugTask.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "PackageTask.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class DebugTask : public PackageTask
|
||||
{
|
||||
public:
|
||||
DebugTask(AsstCallback callback, void* callback_arg);
|
||||
virtual ~DebugTask() = default;
|
||||
|
||||
static constexpr const char* TaskType = "Debug";
|
||||
};
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
<ClInclude Include="AwardTask.h" />
|
||||
<ClInclude Include="BattleImageAnalyzer.h" />
|
||||
<ClInclude Include="BattlePerspectiveImageAnalyzer.h" />
|
||||
<ClInclude Include="DebugTask.h" />
|
||||
<ClInclude Include="FightTask.h" />
|
||||
<ClInclude Include="InfrastTask.h" />
|
||||
<ClInclude Include="MallTask.h" />
|
||||
@@ -70,6 +71,8 @@
|
||||
<ClInclude Include="RoguelikeFormationTaskPlugin.h" />
|
||||
<ClInclude Include="RoguelikeFormationImageAnalyzer.h" />
|
||||
<ClInclude Include="RoguelikeRecruitTaskPlugin.h" />
|
||||
<ClInclude Include="RoguelikeSkillSelectionImageAnalyzer.h" />
|
||||
<ClInclude Include="RoguelikeSkillSelectionTaskPlugin.h" />
|
||||
<ClInclude Include="RoguelikeTask.h" />
|
||||
<ClInclude Include="RuntimeStatus.h" />
|
||||
<ClInclude Include="StageDropsTaskPlugin.h" />
|
||||
@@ -92,6 +95,7 @@
|
||||
<ClCompile Include="AwardTask.cpp" />
|
||||
<ClCompile Include="BattleImageAnalyzer.cpp" />
|
||||
<ClCompile Include="BattlePerspectiveImageAnalyzer.cpp" />
|
||||
<ClCompile Include="DebugTask.cpp" />
|
||||
<ClCompile Include="FightTask.cpp" />
|
||||
<ClCompile Include="InfrastTask.cpp" />
|
||||
<ClCompile Include="MallTask.cpp" />
|
||||
@@ -136,6 +140,8 @@
|
||||
<ClCompile Include="RoguelikeFormationTaskPlugin.cpp" />
|
||||
<ClCompile Include="RoguelikeFormationImageAnalyzer.cpp" />
|
||||
<ClCompile Include="RoguelikeRecruitTaskPlugin.cpp" />
|
||||
<ClCompile Include="RoguelikeSkillSelectionImageAnalyzer.cpp" />
|
||||
<ClCompile Include="RoguelikeSkillSelectionTaskPlugin.cpp" />
|
||||
<ClCompile Include="RoguelikeTask.cpp" />
|
||||
<ClCompile Include="RuntimeStatus.cpp" />
|
||||
<ClCompile Include="StageDropsTaskPlugin.cpp" />
|
||||
|
||||
@@ -294,6 +294,15 @@
|
||||
<ClInclude Include="RoguelikeRecruitTaskPlugin.h">
|
||||
<Filter>头文件\Task\Plugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RoguelikeSkillSelectionTaskPlugin.h">
|
||||
<Filter>头文件\Task\Plugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DebugTask.h">
|
||||
<Filter>头文件\Task\Plugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RoguelikeSkillSelectionImageAnalyzer.h">
|
||||
<Filter>头文件\ImageAnalyzer\Final</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Controller.cpp">
|
||||
@@ -485,6 +494,15 @@
|
||||
<ClCompile Include="RoguelikeRecruitTaskPlugin.cpp">
|
||||
<Filter>源文件\Task\Plugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RoguelikeSkillSelectionTaskPlugin.cpp">
|
||||
<Filter>源文件\Task\Plugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DebugTask.cpp">
|
||||
<Filter>源文件\Task</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RoguelikeSkillSelectionImageAnalyzer.cpp">
|
||||
<Filter>源文件\ImageAnalyzer\Final</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\resource\config.json">
|
||||
|
||||
@@ -126,6 +126,14 @@ bool asst::MultiMatchImageAnalyzer::multi_match_templ(const cv::Mat templ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASST_DEBUG
|
||||
for (const auto& rect : m_result) {
|
||||
cv::rectangle(m_image_draw, utils::make_rect<cv::Rect>(rect.rect), cv::Scalar(0, 0, 255), 2);
|
||||
cv::putText(m_image_draw, std::to_string(rect.score), cv::Point(rect.rect.x, rect.rect.y), 1, 1, cv::Scalar(0, 0, 255));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string log_str = "[ ";
|
||||
for (const auto& res : m_result) {
|
||||
log_str += res.rect.to_string() + " : " + std::to_string(res.score) + "; ";
|
||||
|
||||
@@ -145,6 +145,15 @@ void asst::OcrImageAnalyzer::sort_result()
|
||||
);
|
||||
}
|
||||
|
||||
void asst::OcrImageAnalyzer::sort_result_by_score()
|
||||
{
|
||||
std::sort(m_ocr_result.begin(), m_ocr_result.end(),
|
||||
[](const TextRect& lhs, const TextRect& rhs) -> bool {
|
||||
return lhs.score < rhs.score;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void asst::OcrImageAnalyzer::sort_result_by_required()
|
||||
{
|
||||
if (m_required.empty()) {
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace asst
|
||||
virtual bool analyze() override;
|
||||
|
||||
void sort_result(); // 按位置排序,左上角的排在前面
|
||||
void sort_result_by_score(); // 按分数排序,得分最高的在前面
|
||||
void sort_result_by_required(); // 按传入的需求数组排序,传入的在前面结果接在前面
|
||||
|
||||
void set_use_cache(bool is_use) noexcept;
|
||||
|
||||
@@ -20,12 +20,6 @@ bool asst::RoguelikeFormationTaskPlugin::verify(AsstMsg msg, const json::value&
|
||||
}
|
||||
}
|
||||
|
||||
bool asst::RoguelikeFormationTaskPlugin::set_operators(std::vector<BattleOper> opers)
|
||||
{
|
||||
m_opers = std::move(opers);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeFormationTaskPlugin::_run()
|
||||
{
|
||||
RoguelikeFormationImageAnalyzer formation_analyzer(m_ctrler->get_image());
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
struct BattleOper
|
||||
{
|
||||
std::string name;
|
||||
bool full_match = false;
|
||||
int skill = 1;
|
||||
};
|
||||
// 集成战略模式快捷编队任务
|
||||
class RoguelikeFormationTaskPlugin : public AbstractTaskPlugin
|
||||
{
|
||||
@@ -18,11 +12,7 @@ namespace asst
|
||||
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
bool set_operators(std::vector<BattleOper> opers);
|
||||
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
std::vector<BattleOper> m_opers;
|
||||
};
|
||||
}
|
||||
|
||||
77
src/MeoAssistant/RoguelikeSkillSelectionImageAnalyzer.cpp
Normal file
77
src/MeoAssistant/RoguelikeSkillSelectionImageAnalyzer.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "RoguelikeSkillSelectionImageAnalyzer.h"
|
||||
|
||||
#include "AsstUtils.hpp"
|
||||
#include "OcrImageAnalyzer.h"
|
||||
#include "MultiMatchImageAnalyzer.h"
|
||||
#include "TaskData.h"
|
||||
#include "Logger.hpp"
|
||||
|
||||
bool asst::RoguelikeSkillSelectionImageAnalyzer::analyze()
|
||||
{
|
||||
MultiMatchImageAnalyzer flag_analyzer(m_image);
|
||||
flag_analyzer.set_task_info(Task.get("Roguelike1SkillSelectionFlag"));
|
||||
|
||||
if (!flag_analyzer.analyze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& flags = flag_analyzer.get_result();
|
||||
|
||||
int unknow_index = 0;
|
||||
for (const auto& flag : flags) {
|
||||
std::string name = name_analyze(flag.rect);
|
||||
auto skills = skill_analyze(flag.rect);
|
||||
if (skills.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (name.empty()) {
|
||||
name = "Unknown" + std::to_string(unknow_index++);
|
||||
}
|
||||
m_result.emplace(std::move(name), std::move(skills));
|
||||
}
|
||||
|
||||
return !m_result.empty();
|
||||
}
|
||||
|
||||
std::string asst::RoguelikeSkillSelectionImageAnalyzer::name_analyze(const Rect& roi)
|
||||
{
|
||||
OcrImageAnalyzer analyzer;
|
||||
auto name_task_ptr = Task.get("Roguelike1SkillSelectionName");
|
||||
analyzer.set_task_info(name_task_ptr);
|
||||
analyzer.set_image(m_image, roi.move(name_task_ptr->rect_move));
|
||||
|
||||
if (!analyzer.analyze()) {
|
||||
return std::string();
|
||||
}
|
||||
analyzer.sort_result_by_score();
|
||||
return analyzer.get_result().front().text;
|
||||
}
|
||||
|
||||
std::vector<asst::Rect> asst::RoguelikeSkillSelectionImageAnalyzer::skill_analyze(const Rect& roi)
|
||||
{
|
||||
const auto task_ptr = std::dynamic_pointer_cast<MatchTaskInfo>(Task.get("Roguelike1SkillSelectionRect"));
|
||||
Rect cor_roi = roi.move(task_ptr->roi);
|
||||
cv::Mat image_roi = m_image(utils::make_rect<cv::Rect>(cor_roi));
|
||||
|
||||
std::vector<Rect> result_vec;
|
||||
|
||||
int skill_width = cor_roi.width / MaxNumOfSkills;
|
||||
for (int x = 0; x + skill_width < cor_roi.width; x += skill_width) {
|
||||
Rect single_skill_rect(x, 0, skill_width, cor_roi.height);
|
||||
cv::Mat skill = image_roi(utils::make_rect<cv::Rect>(single_skill_rect));
|
||||
cv::Mat skill_gray;
|
||||
cv::cvtColor(skill, skill_gray, cv::COLOR_BGR2GRAY);
|
||||
cv::Scalar avg = cv::mean(skill_gray);
|
||||
Log.trace(__FUNCTION__, "gray avg", avg[0]);
|
||||
if (avg[0] < task_ptr->templ_threshold) {
|
||||
break;
|
||||
}
|
||||
Rect result = cor_roi.move(single_skill_rect.move(task_ptr->rect_move));
|
||||
#ifdef ASST_DEBUG
|
||||
cv::rectangle(m_image_draw, utils::make_rect<cv::Rect>(result), cv::Scalar(0, 255, 0), 3);
|
||||
#endif
|
||||
result_vec.emplace_back(result);
|
||||
}
|
||||
|
||||
return result_vec;
|
||||
}
|
||||
37
src/MeoAssistant/RoguelikeSkillSelectionImageAnalyzer.h
Normal file
37
src/MeoAssistant/RoguelikeSkillSelectionImageAnalyzer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include "AbstractImageAnalyzer.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class RoguelikeSkillSelectionImageAnalyzer final : public AbstractImageAnalyzer
|
||||
{
|
||||
public:
|
||||
static constexpr size_t MaxNumOfSkills = 3;
|
||||
public:
|
||||
using AbstractImageAnalyzer::AbstractImageAnalyzer;
|
||||
virtual ~RoguelikeSkillSelectionImageAnalyzer() = default;
|
||||
|
||||
virtual bool analyze() override;
|
||||
|
||||
const auto& get_result() const noexcept
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
private:
|
||||
// 该分析器不支持外部设置ROI
|
||||
virtual void set_roi(const Rect& roi) noexcept override
|
||||
{
|
||||
AbstractImageAnalyzer::set_roi(roi);
|
||||
}
|
||||
virtual void set_image(const cv::Mat image, const Rect& roi)
|
||||
{
|
||||
AbstractImageAnalyzer::set_image(image, roi);
|
||||
}
|
||||
|
||||
std::string name_analyze(const Rect& roi);
|
||||
std::vector<Rect> skill_analyze(const Rect& roi);
|
||||
|
||||
std::unordered_map<std::string, std::vector<Rect>> m_result; // 干员名 : 技能的位置(多个技能)
|
||||
};
|
||||
}
|
||||
67
src/MeoAssistant/RoguelikeSkillSelectionTaskPlugin.cpp
Normal file
67
src/MeoAssistant/RoguelikeSkillSelectionTaskPlugin.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "RoguelikeSkillSelectionTaskPlugin.h"
|
||||
|
||||
#include "RoguelikeSkillSelectionImageAnalyzer.h"
|
||||
#include "Controller.h"
|
||||
#include "TaskData.h"
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
bool asst::RoguelikeSkillSelectionTaskPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
if (msg != AsstMsg::SubTaskStart
|
||||
|| details.get("subtask", std::string()) != "ProcessTask") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (details.at("details").at("task").as_string() == "Roguelike1StartAction") {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void asst::RoguelikeSkillSelectionTaskPlugin::set_skill_map(SkillMap skill_mapping)
|
||||
{
|
||||
m_skill_mapping = std::move(skill_mapping);
|
||||
}
|
||||
|
||||
bool asst::RoguelikeSkillSelectionTaskPlugin::_run()
|
||||
{
|
||||
//#ifdef ASST_DEBUG
|
||||
// m_skill_mapping.clear();
|
||||
// m_skill_mapping.reserve(4);
|
||||
// m_skill_mapping.emplace("棘刺", 3);
|
||||
// m_skill_mapping.emplace("芙蓉", 1);
|
||||
// m_skill_mapping.emplace("梓兰", 1);
|
||||
// m_skill_mapping.emplace("阿米娅", 3);
|
||||
// m_skill_mapping.emplace("Unknown", 3);
|
||||
//#endif
|
||||
auto image = m_ctrler->get_image();
|
||||
RoguelikeSkillSelectionImageAnalyzer analyzer(image);
|
||||
|
||||
if (!analyzer.analyze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& [name, skill_vec] : analyzer.get_result()) {
|
||||
for (const auto& [req_name, req_skill] : m_skill_mapping) {
|
||||
if (name.find(req_name) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
size_t index = 0;
|
||||
if (skill_vec.size() < req_skill) {
|
||||
index = skill_vec.size() - 1;
|
||||
Log.info("skill", req_skill, "not exists, use skill", index);
|
||||
}
|
||||
else {
|
||||
index = req_skill - 1;
|
||||
}
|
||||
Rect target = skill_vec.at(index);
|
||||
m_ctrler->click(target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
25
src/MeoAssistant/RoguelikeSkillSelectionTaskPlugin.h
Normal file
25
src/MeoAssistant/RoguelikeSkillSelectionTaskPlugin.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "AbstractTaskPlugin.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class RoguelikeSkillSelectionTaskPlugin final : public AbstractTaskPlugin
|
||||
{
|
||||
public:
|
||||
using SkillMap = std::unordered_map<std::string, int>;
|
||||
public:
|
||||
using AbstractTaskPlugin::AbstractTaskPlugin;
|
||||
virtual ~RoguelikeSkillSelectionTaskPlugin() = default;
|
||||
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
void set_skill_map(SkillMap skill_mapping);
|
||||
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
SkillMap m_skill_mapping;
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "RoguelikeFormationTaskPlugin.h"
|
||||
#include "RoguelikeBattleTaskPlugin.h"
|
||||
#include "RoguelikeRecruitTaskPlugin.h"
|
||||
#include "RoguelikeSkillSelectionTaskPlugin.h"
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
@@ -19,6 +20,9 @@ asst::RoguelikeTask::RoguelikeTask(AsstCallback callback, void* callback_arg)
|
||||
m_recruit_task_ptr = m_roguelike_task_ptr->regiseter_plugin<RoguelikeRecruitTaskPlugin>();
|
||||
m_recruit_task_ptr->set_retry_times(2);
|
||||
|
||||
m_skill_task_ptr = m_roguelike_task_ptr->regiseter_plugin<RoguelikeSkillSelectionTaskPlugin>();
|
||||
m_skill_task_ptr->set_retry_times(0);
|
||||
|
||||
// 这个任务如果卡住会放弃当前的肉鸽并重新开始,所以多添加一点。先这样凑合用
|
||||
for (int i = 0; i != 10000; ++i) {
|
||||
m_subtasks.emplace_back(m_roguelike_task_ptr);
|
||||
@@ -30,23 +34,29 @@ bool asst::RoguelikeTask::set_params(const json::value& params)
|
||||
// 0 - 尽可能一直往后打
|
||||
// 1 - 第一层投资完源石锭就退出
|
||||
// 2 - 投资过后再退出,没有投资就继续往后打
|
||||
int mode = params.get("mode", 0);
|
||||
|
||||
std::vector<std::string> opers_vec;
|
||||
if (params.contains("opers") && params.at("opers").is_array()) {
|
||||
for (auto& oper : params.at("opers").as_array()) {
|
||||
if (oper.contains("name") && oper.at("name").is_string()) {
|
||||
opers_vec.emplace_back(oper.at("name").as_string());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!params.contains("opers") || !params.at("opers").is_array()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> opers_vec;
|
||||
RoguelikeSkillSelectionTaskPlugin::SkillMap skill_map;
|
||||
|
||||
for (auto& oper : params.at("opers").as_array()) {
|
||||
if (!oper.contains("name") || !oper.at("name").is_string()) {
|
||||
return false;
|
||||
}
|
||||
int skill = oper.get("skill", 1);
|
||||
if (skill < 1 || 3 < skill) {
|
||||
return false;
|
||||
}
|
||||
std::string name = oper.at("name").as_string();
|
||||
opers_vec.emplace_back(name);
|
||||
skill_map.emplace(name, skill);
|
||||
}
|
||||
skill_map.emplace("Unknown", 3);
|
||||
|
||||
int mode = params.get("mode", 0);
|
||||
switch (mode) {
|
||||
case 0:
|
||||
break;
|
||||
@@ -62,6 +72,7 @@ bool asst::RoguelikeTask::set_params(const json::value& params)
|
||||
}
|
||||
|
||||
m_recruit_task_ptr->set_opers(std::move(opers_vec));
|
||||
m_skill_task_ptr->set_skill_map(std::move(skill_map));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace asst
|
||||
{
|
||||
class ProcessTask;
|
||||
class RoguelikeRecruitTaskPlugin;
|
||||
class RoguelikeSkillSelectionTaskPlugin;
|
||||
|
||||
class RoguelikeTask : public PackageTask
|
||||
{
|
||||
@@ -19,5 +20,6 @@ namespace asst
|
||||
private:
|
||||
std::shared_ptr<ProcessTask> m_roguelike_task_ptr = nullptr;
|
||||
std::shared_ptr<RoguelikeRecruitTaskPlugin> m_recruit_task_ptr = nullptr;
|
||||
std::shared_ptr<RoguelikeSkillSelectionTaskPlugin> m_skill_task_ptr = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace asst
|
||||
virtual ~StartUpTask() = default;
|
||||
|
||||
static constexpr const char* TaskType = "StartUp";
|
||||
protected:
|
||||
private:
|
||||
|
||||
std::shared_ptr<ProcessTask> m_start_up_task_ptr = nullptr;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user