From 018a3cdf4a52aab08fde33da8bb4f2af25afb14f Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Thu, 4 Jan 2024 17:54:28 +0800 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=82=89?= =?UTF-8?q?=E9=B8=BD=E4=BA=8B=E4=BB=B6choice=5Frequire=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 11 +++++++++ .../RoguelikeStageEncounterConfig.cpp | 9 +++++++ .../Roguelike/RoguelikeStageEncounterConfig.h | 11 +++++++++ .../RoguelikeStageEncounterTaskPlugin.cpp | 24 ++++++++++++++++--- .../RoguelikeStageEncounterTaskPlugin.h | 21 ++++++++++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/resource/tasks.json b/resource/tasks.json index d2a7b04a4c..528007e7d6 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -12513,6 +12513,17 @@ "Roguelike@StageEncounterJudgeOption" ] }, + "Roguelike@SpecialValRecognition": { + "algorithm": "OcrDetect", + "action": "DoNothing", + "text": [], + "roi": [ + 615, + 0, + 80, + 45 + ] + }, "Roguelike@StageEncounterJudgeOption": { "algorithm": "JustReturn", "action": "DoNothing", diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index f4eeac4c6f..833e7b1b80 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -16,6 +16,15 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) event.name = event_json.at("name").as_string(); event.option_num = event_json.get("option_num", 0); event.default_choose = event_json.get("choose", 0); + if (event_json.contains("choice_require")) { + for (const auto& requirement_json : event_json.at("choice_require").as_array()) { + ChoiceRequire requirement; + requirement.name = requirement_json.at("name").as_string(); + requirement.chaos_level.value = requirement_json.at("ChaosLevel").get("value", 0); + requirement.chaos_level.type = requirement_json.at("ChaosLevel").at("type").as_string(); + event.choice_require.emplace_back(std::move(requirement)); + } + } m_events[theme].emplace_back(std::move(event)); } return true; diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index 71c1a5dc5c..c88e7df34d 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -8,11 +8,22 @@ namespace asst { + struct ChaosLevel + { + int value = 0; + std::string type; // '>' or '<' + }; + struct ChoiceRequire + { + std::string name; + ChaosLevel chaos_level; + }; struct RoguelikeEvent { std::string name; int option_num = 0; int default_choose = 0; + std::vector choice_require; }; class RoguelikeStageEncounterConfig final : public SingletonHolder, diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 86f5722b40..27cc732d0f 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -73,14 +73,32 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() RoguelikeEvent event = event_map.at(text); - Log.info("Event:", event.name, "choose option", event.default_choose); + int special_val = 0; + // 水月的不好识别,先试试萨米能不能用 + if (m_config->get_theme() == "Sami") { + OCRer analyzer(image); + analyzer.set_task_info(m_config->get_theme() + "Roguelike@SpecialValRecognition"); + analyzer.set_replace(Task.get("NumberOcrReplace")->replace_map); + analyzer.set_use_char_model(true); + + if (!analyzer.analyze()) { + return false; + } + special_val = std::stoi(analyzer.get_result().front().text); + } + + int choose_option = process_task(event, special_val); + Log.info("Event:", event.name, "special_val", special_val, "choose option", choose_option); + auto info = basic_info_with_what("RoguelikeEvent"); info["details"]["name"] = event.name; info["details"]["default_choose"] = event.default_choose; + info["details"]["special_val"] = special_val; + info["details"]["choose"] = choose_option; callback(AsstMsg::SubTaskExtraInfo, info); for (int j = 0; j < 2; ++j) { - ProcessTask(*this, { m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(event.option_num) + "-" + - std::to_string(event.default_choose) }) + ProcessTask(*this, { m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(event.option_num) + + "-" + std::to_string(choose_option) }) .run(); sleep(300); } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 7793e51bf3..ceeaab8e1c 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -1,5 +1,6 @@ #pragma once #include "AbstractRoguelikeTaskPlugin.h" +#include "Config/Roguelike/RoguelikeStageEncounterConfig.h" namespace asst { @@ -14,5 +15,25 @@ namespace asst protected: virtual bool _run() override; + static bool satisfies_condition(const asst::ChoiceRequire& requirement, const int special_val) + { + if (requirement.chaos_level.type == ">") { + return special_val > requirement.chaos_level.value; + } + if (requirement.chaos_level.type == "<") { + return special_val < requirement.chaos_level.value; + } + return false; + } + + static int process_task(const asst::RoguelikeEvent& event, const int special_val) + { + for (const auto& requirement : event.choice_require) { + if (satisfies_condition(requirement, special_val)) { + return requirement.chaos_level.value; + } + } + return event.default_choose; + } }; } From 58920396020243277a4006e97c83b423830095c2 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:27:10 +0800 Subject: [PATCH 02/17] =?UTF-8?q?chore:=20choice=5Frequire=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0choose=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/roguelike/Sami/encounter.json | 3 ++- src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp | 1 + src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h | 1 + src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/resource/roguelike/Sami/encounter.json b/resource/roguelike/Sami/encounter.json index d4f9edddce..9251c99c82 100644 --- a/resource/roguelike/Sami/encounter.json +++ b/resource/roguelike/Sami/encounter.json @@ -539,7 +539,8 @@ "Vision": { "value": "1", "type": ">" - } + }, + "choose": 1 } ] } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index 833e7b1b80..d2af7fe1df 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -20,6 +20,7 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) for (const auto& requirement_json : event_json.at("choice_require").as_array()) { ChoiceRequire requirement; requirement.name = requirement_json.at("name").as_string(); + requirement.choose = requirement_json.get("choose", -1); requirement.chaos_level.value = requirement_json.at("ChaosLevel").get("value", 0); requirement.chaos_level.type = requirement_json.at("ChaosLevel").at("type").as_string(); event.choice_require.emplace_back(std::move(requirement)); diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index c88e7df34d..6a4ae2820e 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -17,6 +17,7 @@ namespace asst { std::string name; ChaosLevel chaos_level; + int choose = -1; }; struct RoguelikeEvent { diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index ceeaab8e1c..57f2266da6 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -30,7 +30,7 @@ namespace asst { for (const auto& requirement : event.choice_require) { if (satisfies_condition(requirement, special_val)) { - return requirement.chaos_level.value; + return requirement.choose == -1 ? event.default_choose : requirement.choose; } } return event.default_choose; From caa4ecb51bd400988a9ff70ee31b84cc045c0a18 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Thu, 4 Jan 2024 20:12:58 +0800 Subject: [PATCH 03/17] =?UTF-8?q?chore:=20ChaosLevel=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=B1=BB=E5=9E=8B=E7=9A=84value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Config/Roguelike/RoguelikeStageEncounterConfig.cpp | 2 +- .../Config/Roguelike/RoguelikeStageEncounterConfig.h | 4 ++-- .../Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h | 7 +++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index d2af7fe1df..8bc9504aeb 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -21,7 +21,7 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) ChoiceRequire requirement; requirement.name = requirement_json.at("name").as_string(); requirement.choose = requirement_json.get("choose", -1); - requirement.chaos_level.value = requirement_json.at("ChaosLevel").get("value", 0); + requirement.chaos_level.value = requirement_json.at("ChaosLevel").at("value").as_string(); requirement.chaos_level.type = requirement_json.at("ChaosLevel").at("type").as_string(); event.choice_require.emplace_back(std::move(requirement)); } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index 6a4ae2820e..30349711d1 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -10,8 +10,8 @@ namespace asst { struct ChaosLevel { - int value = 0; - std::string type; // '>' or '<' + std::string value; + std::string type; // '>' or '<' or '=' 其他的还不支持 }; struct ChoiceRequire { diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 57f2266da6..618b21a10d 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -18,10 +18,13 @@ namespace asst static bool satisfies_condition(const asst::ChoiceRequire& requirement, const int special_val) { if (requirement.chaos_level.type == ">") { - return special_val > requirement.chaos_level.value; + return special_val > std::stoi(requirement.chaos_level.value); } if (requirement.chaos_level.type == "<") { - return special_val < requirement.chaos_level.value; + return special_val < std::stoi(requirement.chaos_level.value); + } + if (requirement.chaos_level.type == "=") { + return special_val == std::stoi(requirement.chaos_level.value); } return false; } From e1f9536b3e9ce1c5dc0a34be446da213b9eb3325 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:44:40 +0800 Subject: [PATCH 04/17] chore: "Sami" -> RoguelikeTheme::Sami Co-authored-by: status102 <102887808+status102@users.noreply.github.com> --- .../Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 27cc732d0f..f881653d39 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -75,7 +75,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() int special_val = 0; // 水月的不好识别,先试试萨米能不能用 - if (m_config->get_theme() == "Sami") { + if (m_config->get_theme() == RoguelikeTheme::Sami) { OCRer analyzer(image); analyzer.set_task_info(m_config->get_theme() + "Roguelike@SpecialValRecognition"); analyzer.set_replace(Task.get("NumberOcrReplace")->replace_map); From c280aa877bfe9138a352ab70a1cc549d3a101d40 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:04:17 +0800 Subject: [PATCH 05/17] chore: use utils::chars_to_number --- .../RoguelikeStageEncounterTaskPlugin.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 618b21a10d..86816d108f 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -17,16 +17,17 @@ namespace asst virtual bool _run() override; static bool satisfies_condition(const asst::ChoiceRequire& requirement, const int special_val) { - if (requirement.chaos_level.type == ">") { - return special_val > std::stoi(requirement.chaos_level.value); + int num = 0; + switch (requirement.chaos_level.type) { + case ">": + return utils::chars_to_number(requirement.chaos_level.value, num) && special_val > num; + case "<": + return utils::chars_to_number(requirement.chaos_level.value, num) && special_val < num; + case "=": + return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; + default: + return false; } - if (requirement.chaos_level.type == "<") { - return special_val < std::stoi(requirement.chaos_level.value); - } - if (requirement.chaos_level.type == "=") { - return special_val == std::stoi(requirement.chaos_level.value); - } - return false; } static int process_task(const asst::RoguelikeEvent& event, const int special_val) From f75b42da632f54a91dd661aefd1989b528cb7417 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Fri, 5 Jan 2024 17:07:10 +0800 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0hp=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E5=88=A4=E6=96=AD=E6=98=AF=E5=90=A6=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E7=82=B9=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 14 +++++++++ .../RoguelikeStageEncounterTaskPlugin.cpp | 31 ++++++++++++++++--- .../RoguelikeStageEncounterTaskPlugin.h | 22 +++++++++++-- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/resource/tasks.json b/resource/tasks.json index 528007e7d6..756ac40e4f 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -12516,6 +12516,8 @@ "Roguelike@SpecialValRecognition": { "algorithm": "OcrDetect", "action": "DoNothing", + "Doc": "特殊值识别,如抗干扰值,需修改对应主题的roi", + ";": null, "text": [], "roi": [ 615, @@ -12524,6 +12526,18 @@ 45 ] }, + "Roguelike@HpRecognition": { + "algorithm": "OcrDetect", + "action": "DoNothing", + "Doc": "生命值识别,暂时是把整个框进去,估计会把后面的生命值也识别到,后面得改改", + "text": [], + "roi": [ + 190, + 30, + 60, + 30 + ] + }, "Roguelike@StageEncounterJudgeOption": { "algorithm": "JustReturn", "action": "DoNothing", diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index f881653d39..22273f9170 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -1,13 +1,11 @@ #include "RoguelikeStageEncounterTaskPlugin.h" #include "Config/Roguelike/RoguelikeStageEncounterConfig.h" -#include "Config/TaskData.h" #include "Controller/Controller.h" #include "Status.h" #include "Task/ProcessTask.h" #include "Utils/ImageIo.hpp" #include "Utils/Logger.hpp" -#include "Vision/OCRer.h" bool asst::RoguelikeStageEncounterTaskPlugin::verify(AsstMsg msg, const json::value& details) const { @@ -84,7 +82,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() if (!analyzer.analyze()) { return false; } - special_val = std::stoi(analyzer.get_result().front().text); + utils::chars_to_number(analyzer.get_result().front().text, special_val); } int choose_option = process_task(event, special_val); @@ -103,5 +101,30 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() sleep(300); } - return true; + // 判断是否点击成功,成功进入对话后左上角的生命值会消失 + image = ctrler()->get_image(); + if (hp(image) == -1) { + return true; + } + + int max_time = event.option_num; + while (max_time > 0) { + for (int i = 0; i < max_time; ++i) { + for (int j = 0; j < 2; ++j) { + ProcessTask(*this, { m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(max_time) + + "-" + std::to_string(i) }) + .run(); + sleep(300); + } + + image = ctrler()->get_image(); + if (hp(image) == -1) { + return true; + } + } + // 没通关结局有些事件会少选项 + --max_time; + } + + return false; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 86816d108f..dd4e074afc 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -1,6 +1,8 @@ #pragma once #include "AbstractRoguelikeTaskPlugin.h" #include "Config/Roguelike/RoguelikeStageEncounterConfig.h" +#include "Config/TaskData.h" +#include "Vision/OCRer.h" namespace asst { @@ -20,11 +22,11 @@ namespace asst int num = 0; switch (requirement.chaos_level.type) { case ">": - return utils::chars_to_number(requirement.chaos_level.value, num) && special_val > num; + return utils::chars_to_number(requirement.chaos_level.value, num) && special_val > num; case "<": - return utils::chars_to_number(requirement.chaos_level.value, num) && special_val < num; + return utils::chars_to_number(requirement.chaos_level.value, num) && special_val < num; case "=": - return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; + return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; default: return false; } @@ -39,5 +41,19 @@ namespace asst } return event.default_choose; } + + static int hp(const cv::Mat& image) + { + int hp_val = -1; + asst::OCRer analyzer(image); + analyzer.set_task_info("Roguelike@HpRecognition"); + analyzer.set_replace(Task.get("NumberOcrReplace")->replace_map); + analyzer.set_use_char_model(true); + + if (!analyzer.analyze()) { + return 0; + } + return utils::chars_to_number(analyzer.get_result().front().text, hp_val) ? hp_val : -1; + } }; } From 70c32571a97d5634256cad2b938adae64b4d68ff Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Fri, 5 Jan 2024 17:08:23 +0800 Subject: [PATCH 07/17] fix: typo --- resource/tasks.json | 1 - 1 file changed, 1 deletion(-) diff --git a/resource/tasks.json b/resource/tasks.json index 756ac40e4f..ff6af19baa 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -12517,7 +12517,6 @@ "algorithm": "OcrDetect", "action": "DoNothing", "Doc": "特殊值识别,如抗干扰值,需修改对应主题的roi", - ";": null, "text": [], "roi": [ 615, From fea5641ce94a261de4488adaeb84d071b93e453a Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:05:58 +0800 Subject: [PATCH 08/17] =?UTF-8?q?chore:=20=E8=AF=86=E5=88=AB=E5=88=B0hp?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E4=BB=8E=E4=B8=8B=E5=BE=80=E4=B8=8A?= =?UTF-8?q?=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp | 7 ++++--- .../Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 22273f9170..97e5241b5d 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -103,13 +103,14 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() // 判断是否点击成功,成功进入对话后左上角的生命值会消失 image = ctrler()->get_image(); - if (hp(image) == -1) { + if (hp(image) <= 0) { return true; } int max_time = event.option_num; while (max_time > 0) { - for (int i = 0; i < max_time; ++i) { + // 从下往上点 + for (int i = max_time; i > 0; --i) { for (int j = 0; j < 2; ++j) { ProcessTask(*this, { m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(max_time) + "-" + std::to_string(i) }) @@ -118,7 +119,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() } image = ctrler()->get_image(); - if (hp(image) == -1) { + if (hp(image) <= 0) { return true; } } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index dd4e074afc..f7c11ff8c9 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -51,9 +51,9 @@ namespace asst analyzer.set_use_char_model(true); if (!analyzer.analyze()) { - return 0; + return -1; } - return utils::chars_to_number(analyzer.get_result().front().text, hp_val) ? hp_val : -1; + return utils::chars_to_number(analyzer.get_result().front().text, hp_val) ? hp_val : 0; } }; } From 3f1e9a2c62db58e18f58a71e6bfad8f1de34f963 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:06:28 +0800 Subject: [PATCH 09/17] =?UTF-8?q?chore:=20=E5=BE=AA=E7=8E=AF=E4=B8=AD?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E6=98=AF=E5=90=A6=E7=82=B9=E5=87=BB=E4=BA=86?= =?UTF-8?q?=E5=81=9C=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 97e5241b5d..331ffccf26 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -118,6 +118,10 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() sleep(300); } + if (need_exit()) { + return false; + } + image = ctrler()->get_image(); if (hp(image) <= 0) { return true; From b95ec6694b4b2a7fab9f7bb303c987b651a1a9b1 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:23:57 +0800 Subject: [PATCH 10/17] =?UTF-8?q?fix:=20requirement.chaos=5Flevel.type?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoguelikeStageEncounterConfig.cpp | 2 +- .../Roguelike/RoguelikeStageEncounterConfig.h | 22 ++++++++++++++++++- .../RoguelikeStageEncounterTaskPlugin.h | 9 ++++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index 8bc9504aeb..94b31666ec 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -22,7 +22,7 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) requirement.name = requirement_json.at("name").as_string(); requirement.choose = requirement_json.get("choose", -1); requirement.chaos_level.value = requirement_json.at("ChaosLevel").at("value").as_string(); - requirement.chaos_level.type = requirement_json.at("ChaosLevel").at("type").as_string(); + requirement.chaos_level.type = parse_comparison_type(requirement_json.at("ChaosLevel").at("type").as_string()); event.choice_require.emplace_back(std::move(requirement)); } } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index 30349711d1..2e89fb1358 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -8,10 +8,18 @@ namespace asst { + enum class ComparisonType + { + GreaterThan, + LessThan, + Equal, + Unsupported + }; + struct ChaosLevel { std::string value; - std::string type; // '>' or '<' or '=' 其他的还不支持 + ComparisonType type = ComparisonType::Unsupported; }; struct ChoiceRequire { @@ -38,6 +46,18 @@ namespace asst private: virtual bool parse(const json::value& json) override; + static ComparisonType parse_comparison_type(const std::string& type_str) + { + if (type_str == ">") + return ComparisonType::GreaterThan; + if (type_str == "<") + return ComparisonType::LessThan; + if (type_str == "=") + return ComparisonType::Equal; + + return ComparisonType::Unsupported; + } + std::unordered_map> m_events; }; diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index f7c11ff8c9..3ed7ca68ef 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -21,13 +21,14 @@ namespace asst { int num = 0; switch (requirement.chaos_level.type) { - case ">": + case ComparisonType::GreaterThan: return utils::chars_to_number(requirement.chaos_level.value, num) && special_val > num; - case "<": + case ComparisonType::LessThan: return utils::chars_to_number(requirement.chaos_level.value, num) && special_val < num; - case "=": + case ComparisonType::Equal: return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; - default: + case ComparisonType::Unsupported: + case default: return false; } } From 09a8508741065625dcd65c79255f200119b5ea8b Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:50:50 +0800 Subject: [PATCH 11/17] fix: typo --- src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 3ed7ca68ef..f76805b5ca 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -28,7 +28,7 @@ namespace asst case ComparisonType::Equal: return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; case ComparisonType::Unsupported: - case default: + default: return false; } } From fca163496e92f181aa3784ea4786d21971039cff Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:51:52 +0800 Subject: [PATCH 12/17] =?UTF-8?q?style:=20=E8=B0=83=E6=95=B4=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index f76805b5ca..f29735b4ca 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -28,9 +28,9 @@ namespace asst case ComparisonType::Equal: return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; case ComparisonType::Unsupported: - default: return false; } + return false; } static int process_task(const asst::RoguelikeEvent& event, const int special_val) From f1fcaf8720c47e6e0e9baf1e07a9dc176123d798 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:00:01 +0800 Subject: [PATCH 13/17] =?UTF-8?q?fix:=20=E6=8A=97=E5=B9=B2=E6=89=B0?= =?UTF-8?q?=E5=80=BC=E5=AD=97=E6=AE=B5=E5=90=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoguelikeStageEncounterConfig.cpp | 7 ++++-- .../Roguelike/RoguelikeStageEncounterConfig.h | 4 ++-- .../RoguelikeStageEncounterTaskPlugin.cpp | 1 + .../RoguelikeStageEncounterTaskPlugin.h | 22 ++++++++++--------- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index 94b31666ec..03e7824730 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -21,8 +21,11 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) ChoiceRequire requirement; requirement.name = requirement_json.at("name").as_string(); requirement.choose = requirement_json.get("choose", -1); - requirement.chaos_level.value = requirement_json.at("ChaosLevel").at("value").as_string(); - requirement.chaos_level.type = parse_comparison_type(requirement_json.at("ChaosLevel").at("type").as_string()); + if (requirement_json.contains("Vision")) { + auto& chaos_level_json = requirement_json.at("Vision"); + requirement.vision.value = chaos_level_json.at("value").as_string(); + requirement.vision.type = parse_comparison_type(chaos_level_json.at("type").as_string()); + } event.choice_require.emplace_back(std::move(requirement)); } } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index 2e89fb1358..a1eee02920 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -16,7 +16,7 @@ namespace asst Unsupported }; - struct ChaosLevel + struct Vision { std::string value; ComparisonType type = ComparisonType::Unsupported; @@ -24,7 +24,7 @@ namespace asst struct ChoiceRequire { std::string name; - ChaosLevel chaos_level; + Vision vision; int choose = -1; }; struct RoguelikeEvent diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 331ffccf26..2a9c5579a9 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -85,6 +85,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() utils::chars_to_number(analyzer.get_result().front().text, special_val); } + // 现在只有抗干扰值判断 int choose_option = process_task(event, special_val); Log.info("Event:", event.name, "special_val", special_val, "choose option", choose_option); diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index f29735b4ca..ee9e224cd5 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -19,16 +19,18 @@ namespace asst virtual bool _run() override; static bool satisfies_condition(const asst::ChoiceRequire& requirement, const int special_val) { - int num = 0; - switch (requirement.chaos_level.type) { - case ComparisonType::GreaterThan: - return utils::chars_to_number(requirement.chaos_level.value, num) && special_val > num; - case ComparisonType::LessThan: - return utils::chars_to_number(requirement.chaos_level.value, num) && special_val < num; - case ComparisonType::Equal: - return utils::chars_to_number(requirement.chaos_level.value, num) && special_val == num; - case ComparisonType::Unsupported: - return false; + if (requirement.vision.type != ComparisonType::Unsupported) { + int num = 0; + switch (requirement.vision.type) { + case ComparisonType::GreaterThan: + return utils::chars_to_number(requirement.vision.value, num) && special_val > num; + case ComparisonType::LessThan: + return utils::chars_to_number(requirement.vision.value, num) && special_val < num; + case ComparisonType::Equal: + return utils::chars_to_number(requirement.vision.value, num) && special_val == num; + case ComparisonType::Unsupported: + return false; + } } return false; } From 1629630060b61731e915af5694d645cad758e3f0 Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Sat, 6 Jan 2024 20:41:48 +0800 Subject: [PATCH 14/17] fix: fix task name of SpecialValRecognition, etc --- .../Roguelike/RoguelikeStageEncounterConfig.cpp | 10 ++++++---- .../RoguelikeStageEncounterTaskPlugin.cpp | 17 ++++++++--------- .../RoguelikeStageEncounterTaskPlugin.h | 5 +++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index 03e7824730..58119e3009 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -21,11 +21,13 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) ChoiceRequire requirement; requirement.name = requirement_json.at("name").as_string(); requirement.choose = requirement_json.get("choose", -1); - if (requirement_json.contains("Vision")) { - auto& chaos_level_json = requirement_json.at("Vision"); - requirement.vision.value = chaos_level_json.at("value").as_string(); - requirement.vision.type = parse_comparison_type(chaos_level_json.at("type").as_string()); + if (auto vision_opt = requirement_json.find("Vision")) { + const auto& vision_json = vision_opt.value(); + requirement.vision.value = vision_json.at("value").as_string(); + requirement.vision.type = parse_comparison_type(vision_json.at("type").as_string()); } + else + continue; event.choice_require.emplace_back(std::move(requirement)); } } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 2a9c5579a9..a98f3b4d12 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -75,7 +75,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() // 水月的不好识别,先试试萨米能不能用 if (m_config->get_theme() == RoguelikeTheme::Sami) { OCRer analyzer(image); - analyzer.set_task_info(m_config->get_theme() + "Roguelike@SpecialValRecognition"); + analyzer.set_task_info(m_config->get_theme() + "@Roguelike@SpecialValRecognition"); analyzer.set_replace(Task.get("NumberOcrReplace")->replace_map); analyzer.set_use_char_model(true); @@ -92,13 +92,14 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() auto info = basic_info_with_what("RoguelikeEvent"); info["details"]["name"] = event.name; info["details"]["default_choose"] = event.default_choose; - info["details"]["special_val"] = special_val; - info["details"]["choose"] = choose_option; callback(AsstMsg::SubTaskExtraInfo, info); + + const auto click_option_task_name = [&](int item, int total) { + return m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(total) + "-" + std::to_string(item); + }; + for (int j = 0; j < 2; ++j) { - ProcessTask(*this, { m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(event.option_num) + - "-" + std::to_string(choose_option) }) - .run(); + ProcessTask(*this, { click_option_task_name(choose_option, event.option_num) }).run(); sleep(300); } @@ -113,9 +114,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() // 从下往上点 for (int i = max_time; i > 0; --i) { for (int j = 0; j < 2; ++j) { - ProcessTask(*this, { m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(max_time) + - "-" + std::to_string(i) }) - .run(); + ProcessTask(*this, { click_option_task_name(i, max_time) }).run(); sleep(300); } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index ee9e224cd5..2c20e4fda5 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -17,7 +17,7 @@ namespace asst protected: virtual bool _run() override; - static bool satisfies_condition(const asst::ChoiceRequire& requirement, const int special_val) + static bool satisfies_condition(const asst::ChoiceRequire& requirement, int special_val) { if (requirement.vision.type != ComparisonType::Unsupported) { int num = 0; @@ -38,8 +38,9 @@ namespace asst static int process_task(const asst::RoguelikeEvent& event, const int special_val) { for (const auto& requirement : event.choice_require) { + if (requirement.choose == -1) continue; if (satisfies_condition(requirement, special_val)) { - return requirement.choose == -1 ? event.default_choose : requirement.choose; + return requirement.choose; } } return event.default_choose; From 988e4c97a16d1b33d1bc0fd5483d870154db9795 Mon Sep 17 00:00:00 2001 From: zzyyyl Date: Sun, 7 Jan 2024 13:50:40 +0800 Subject: [PATCH 15/17] =?UTF-8?q?perf:=20=E5=B0=86=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=A7=BB=E5=85=A5=20.cpp=20=E5=B9=B6=E7=A8=8D=E4=BD=9C?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 3 +- .../RoguelikeStageEncounterTaskPlugin.cpp | 40 +++++++++++++++++ .../RoguelikeStageEncounterTaskPlugin.h | 45 ++----------------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/resource/tasks.json b/resource/tasks.json index ff6af19baa..eb0274b3dd 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -12526,8 +12526,7 @@ ] }, "Roguelike@HpRecognition": { - "algorithm": "OcrDetect", - "action": "DoNothing", + "baseTask": "NumberOcrReplace", "Doc": "生命值识别,暂时是把整个框进去,估计会把后面的生命值也识别到,后面得改改", "text": [], "roi": [ diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index a98f3b4d12..698aa7f454 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -133,3 +133,43 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() return false; } + +bool asst::RoguelikeStageEncounterTaskPlugin::satisfies_condition(const asst::ChoiceRequire& requirement, + int special_val) +{ + int num = 0; + switch (requirement.vision.type) { + case ComparisonType::GreaterThan: + return utils::chars_to_number(requirement.vision.value, num) && special_val > num; + case ComparisonType::LessThan: + return utils::chars_to_number(requirement.vision.value, num) && special_val < num; + case ComparisonType::Equal: + return utils::chars_to_number(requirement.vision.value, num) && special_val == num; + default: + return false; + } +} + +int asst::RoguelikeStageEncounterTaskPlugin::process_task(const asst::RoguelikeEvent& event, const int special_val) +{ + for (const auto& requirement : event.choice_require) { + if (requirement.choose == -1) continue; + if (satisfies_condition(requirement, special_val)) { + return requirement.choose; + } + } + return event.default_choose; +} + +int asst::RoguelikeStageEncounterTaskPlugin::hp(const cv::Mat& image) +{ + int hp_val; + asst::OCRer analyzer(image); + analyzer.set_task_info("Roguelike@HpRecognition"); + + auto res_vec_opt = analyzer.analyze(); + if (!res_vec_opt) { + return -1; + } + return utils::chars_to_number(res_vec_opt->front().text, hp_val) ? hp_val : 0; +} diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 2c20e4fda5..9ca9e35fcd 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -17,47 +17,8 @@ namespace asst protected: virtual bool _run() override; - static bool satisfies_condition(const asst::ChoiceRequire& requirement, int special_val) - { - if (requirement.vision.type != ComparisonType::Unsupported) { - int num = 0; - switch (requirement.vision.type) { - case ComparisonType::GreaterThan: - return utils::chars_to_number(requirement.vision.value, num) && special_val > num; - case ComparisonType::LessThan: - return utils::chars_to_number(requirement.vision.value, num) && special_val < num; - case ComparisonType::Equal: - return utils::chars_to_number(requirement.vision.value, num) && special_val == num; - case ComparisonType::Unsupported: - return false; - } - } - return false; - } - - static int process_task(const asst::RoguelikeEvent& event, const int special_val) - { - for (const auto& requirement : event.choice_require) { - if (requirement.choose == -1) continue; - if (satisfies_condition(requirement, special_val)) { - return requirement.choose; - } - } - return event.default_choose; - } - - static int hp(const cv::Mat& image) - { - int hp_val = -1; - asst::OCRer analyzer(image); - analyzer.set_task_info("Roguelike@HpRecognition"); - analyzer.set_replace(Task.get("NumberOcrReplace")->replace_map); - analyzer.set_use_char_model(true); - - if (!analyzer.analyze()) { - return -1; - } - return utils::chars_to_number(analyzer.get_result().front().text, hp_val) ? hp_val : 0; - } + static bool satisfies_condition(const asst::ChoiceRequire& requirement, int special_val); + static int process_task(const asst::RoguelikeEvent& event, const int special_val); + static int hp(const cv::Mat& image); }; } From ea91bb1b962e31f5ed2fd2a7864939c33b55b01b Mon Sep 17 00:00:00 2001 From: zzyyyl Date: Mon, 8 Jan 2024 13:54:51 +0800 Subject: [PATCH 16/17] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoguelikeStageEncounterConfig.cpp | 37 ++++++---- .../Roguelike/RoguelikeStageEncounterConfig.h | 67 ++++++++----------- .../RoguelikeStageEncounterTaskPlugin.cpp | 38 ++++++++--- .../RoguelikeStageEncounterTaskPlugin.h | 5 +- 4 files changed, 83 insertions(+), 64 deletions(-) diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index 58119e3009..6e38bd6174 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -16,22 +16,33 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) event.name = event_json.at("name").as_string(); event.option_num = event_json.get("option_num", 0); event.default_choose = event_json.get("choose", 0); - if (event_json.contains("choice_require")) { - for (const auto& requirement_json : event_json.at("choice_require").as_array()) { - ChoiceRequire requirement; - requirement.name = requirement_json.at("name").as_string(); - requirement.choose = requirement_json.get("choose", -1); - if (auto vision_opt = requirement_json.find("Vision")) { - const auto& vision_json = vision_opt.value(); - requirement.vision.value = vision_json.at("value").as_string(); - requirement.vision.type = parse_comparison_type(vision_json.at("type").as_string()); - } - else - continue; - event.choice_require.emplace_back(std::move(requirement)); + auto choice_require_opt = event_json.find("choice_require"); + if (!choice_require_opt || !choice_require_opt->is_array()) { + continue; + } + for (const auto& requirement_json : choice_require_opt->as_array()) { + ChoiceRequire requirement; + requirement.name = requirement_json.at("name").as_string(); + requirement.choose = requirement_json.get("choose", -1); + if (auto vision_opt = requirement_json.find("Vision")) { + requirement.vision.value = vision_opt->get("value", ""); + requirement.vision.type = parse_comparison_type(vision_opt->get("type", "")); } + else { + continue; + } + event.choice_require.emplace_back(std::move(requirement)); } m_events[theme].emplace_back(std::move(event)); } return true; } + +asst::RoguelikeStageEncounterConfig::ComparisonType asst::RoguelikeStageEncounterConfig::parse_comparison_type( + const std::string& type_str) +{ + if (type_str == ">") return ComparisonType::GreaterThan; + if (type_str == "<") return ComparisonType::LessThan; + if (type_str == "=") return ComparisonType::Equal; + return ComparisonType::Unsupported; +} diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index a1eee02920..b01ae8b8a7 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -8,33 +8,6 @@ namespace asst { - enum class ComparisonType - { - GreaterThan, - LessThan, - Equal, - Unsupported - }; - - struct Vision - { - std::string value; - ComparisonType type = ComparisonType::Unsupported; - }; - struct ChoiceRequire - { - std::string name; - Vision vision; - int choose = -1; - }; - struct RoguelikeEvent - { - std::string name; - int option_num = 0; - int default_choose = 0; - std::vector choice_require; - }; - class RoguelikeStageEncounterConfig final : public SingletonHolder, public AbstractConfig { @@ -43,20 +16,38 @@ namespace asst const auto& get_events(const std::string& theme) const noexcept { return m_events.at(theme); } + enum class ComparisonType + { + GreaterThan, + LessThan, + Equal, + None, // 没有配置 + Unsupported, // 配置错误或其他 + }; + + struct Vision + { + std::string value; + ComparisonType type = ComparisonType::None; + }; + struct ChoiceRequire + { + std::string name; + Vision vision; + int choose = -1; + }; + struct RoguelikeEvent + { + std::string name; + int option_num = 0; + int default_choose = 0; + std::vector choice_require; + }; + private: virtual bool parse(const json::value& json) override; - static ComparisonType parse_comparison_type(const std::string& type_str) - { - if (type_str == ">") - return ComparisonType::GreaterThan; - if (type_str == "<") - return ComparisonType::LessThan; - if (type_str == "=") - return ComparisonType::Equal; - - return ComparisonType::Unsupported; - } + static ComparisonType parse_comparison_type(const std::string& type_str); std::unordered_map> m_events; }; diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index 698aa7f454..1504702179 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -37,13 +37,13 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() LogTraceFunction; auto mode = m_config->get_mode(); - std::vector events = RoguelikeStageEncounter.get_events(m_config->get_theme()); + std::vector events = RoguelikeStageEncounter.get_events(m_config->get_theme()); // 刷源石锭模式和烧水模式 if (mode == RoguelikeMode::Investment || mode == RoguelikeMode::Collectible) { events = RoguelikeStageEncounter.get_events(m_config->get_theme() + "_deposit"); } std::vector event_names; - std::unordered_map event_map; + std::unordered_map event_map; for (const auto& event : events) { event_names.emplace_back(event.name); event_map.emplace(event.name, event); @@ -69,7 +69,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() } std::string text = resultVec.front().text; - RoguelikeEvent event = event_map.at(text); + Config::RoguelikeEvent event = event_map.at(text); int special_val = 0; // 水月的不好识别,先试试萨米能不能用 @@ -134,23 +134,39 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() return false; } -bool asst::RoguelikeStageEncounterTaskPlugin::satisfies_condition(const asst::ChoiceRequire& requirement, +bool asst::RoguelikeStageEncounterTaskPlugin::satisfies_condition(const Config::ChoiceRequire& requirement, int special_val) { int num = 0; + bool ret = true; switch (requirement.vision.type) { - case ComparisonType::GreaterThan: - return utils::chars_to_number(requirement.vision.value, num) && special_val > num; - case ComparisonType::LessThan: - return utils::chars_to_number(requirement.vision.value, num) && special_val < num; - case ComparisonType::Equal: - return utils::chars_to_number(requirement.vision.value, num) && special_val == num; + case Config::ComparisonType::GreaterThan: + ret &= utils::chars_to_number(requirement.vision.value, num) && special_val > num; + break; + case Config::ComparisonType::LessThan: + ret &= utils::chars_to_number(requirement.vision.value, num) && special_val < num; + break; + case Config::ComparisonType::Equal: + ret &= utils::chars_to_number(requirement.vision.value, num) && special_val == num; + break; + case Config::ComparisonType::None: + break; default: + Log.warn("unsupported vision type"); return false; } + /* + switch (requirement.hp.type) { + // ... + } + */ + if (!ret) { + return false; + } + return true; } -int asst::RoguelikeStageEncounterTaskPlugin::process_task(const asst::RoguelikeEvent& event, const int special_val) +int asst::RoguelikeStageEncounterTaskPlugin::process_task(const Config::RoguelikeEvent& event, const int special_val) { for (const auto& requirement : event.choice_require) { if (requirement.choose == -1) continue; diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index 9ca9e35fcd..89f9bbb982 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -10,6 +10,7 @@ namespace asst { public: using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + using Config = RoguelikeStageEncounterConfig; virtual ~RoguelikeStageEncounterTaskPlugin() override = default; public: @@ -17,8 +18,8 @@ namespace asst protected: virtual bool _run() override; - static bool satisfies_condition(const asst::ChoiceRequire& requirement, int special_val); - static int process_task(const asst::RoguelikeEvent& event, const int special_val); + static bool satisfies_condition(const Config::ChoiceRequire& requirement, int special_val); + static int process_task(const Config::RoguelikeEvent& event, const int special_val); static int hp(const cv::Mat& image); }; } From a4e779c2ac8f79842b16405c7692086c52412b11 Mon Sep 17 00:00:00 2001 From: SherkeyXD <253294679@qq.com> Date: Mon, 8 Jan 2024 16:33:05 +0800 Subject: [PATCH 17/17] =?UTF-8?q?refactor:=20=E5=88=9D=E6=AD=A5=E9=87=8D?= =?UTF-8?q?=E6=9E=84=20choice=5Frequire=20=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/roguelike/Sami/encounter.json | 852 ++++++++++++++++++------- 1 file changed, 638 insertions(+), 214 deletions(-) diff --git a/resource/roguelike/Sami/encounter.json b/resource/roguelike/Sami/encounter.json index 9251c99c82..1106b58aba 100644 --- a/resource/roguelike/Sami/encounter.json +++ b/resource/roguelike/Sami/encounter.json @@ -15,63 +15,86 @@ "name": "随到随取", "option_num": 2, "choose": 2, - "choice_require": [ + "choices": [ { "name": "使用热像仪", - "Vision": { - "value": "3", - "type": ">" - } + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] } ] }, { "name": "定期维护", - "option_num": 3, - "choose": 3, + "option_num": 2, + "choose": 1, "note": "拥有【安玛的爱】时出现第三选项", - "choice_require": [ + "choices": [ { "name": "检查多色测光望远镜的目镜", - "Vision": { - "value": "4", - "type": ">" - } + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "4" + } + ] }, { "name": "不紧不慢地打开一听罐头汤", - "Relic": { - "value": "安玛的爱", - "type": "have" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Relic", + "type": "have", + "value": "安玛的爱" + } + ] } ] }, { "name": "昏黑之室", "option_num": 3, - "choose": 3, - "choice_require": [ - { - "name": "用仪器探测", - "Vision": { - "value": "5", - "type": ">" - } - } - ] + "choose": 3 }, { "name": "疗愈仪式", - "option_num": 3, - "choose": 1, - "choice_require": [ + "option_num": 2, + "choose": 2, + "choices": [ + { + "name": "谨慎尝试", + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "0" + } + ] + }, { "name": "欣然加入", - "Vision": { - "value": "0", - "type": "=" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": "=", + "value": "0" + } + ] } ] }, @@ -79,47 +102,93 @@ "name": "黑色足迹", "option_num": 2, "choose": 2, - "choice_require": [ + "note": "抗干扰指数为0时出现第三选项,遭遇过【负伤的主树】事件时出现第四选项", + "choices": [ { "name": "逃离", - "LivePoint": { - "value": "3", - "type": ">" - } + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "LivePoint", + "type": ">", + "value": "3" + } + ] + }, + { + "name": "解释情况", + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": "=", + "value": "0" + } + ] + }, + { + "name": "解释情况", + "option_num": 4, + "choose": 4, + "requirements": [] } - ], - "note": "抗干扰指数为0或遭遇过【负伤的主树】事件时出现第三选项" + ] }, { "name": "不冻河", "option_num": 2, "choose": 2, "note": "拥有【安玛的爱】时出现第三选项", - "choice_require": [ + "choices": [ { "name": "寻找工具", - "Relic": { - "value": "安玛的爱", - "type": "have" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Relic", + "type": "have", + "value": "安玛的爱" + } + ] } ] }, { "name": "野外生存专家", "option_num": 3, - "choose": 1, - "choice_require": [ + "choose": 3, + "choices": [ + { + "name": "意思意思", + "option_num": 3, + "choose": 1, + "requirements": [ + { + "name": "OriginiumIngot", + "type": ">", + "value": "2" + } + ] + }, { "name": "重金酬谢", - "OriginiumIngot": { - "value": "4", - "type": ">" - }, - "Vision": { - "value": "2", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "OriginiumIngot", + "type": ">", + "value": "4" + }, + { + "name": "Vision", + "type": ">", + "value": "2" + } + ] } ] }, @@ -127,13 +196,18 @@ "name": "在地公共信号放大站756号", "option_num": 3, "choose": 1, - "choice_require": [ + "choices": [ { "name": "提供位置,呼叫增援", - "Vision": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] } ] }, @@ -144,9 +218,29 @@ }, { "name": "在地公共移动站N6号", - "option_num": 2, - "choose": 2, - "note": "也可能只有一个" + "option_num": 1, + "choose": 1, + "note": "拥有【安玛的爱】时出现第二选项,遭遇过【特里蒙旅行社特派团】事件且选择【拿走广告】时出现第三选项", + "choices": [ + { + "name": "“敲一敲”都能解决", + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "Relic", + "type": "have", + "value": "安玛的爱" + } + ] + }, + { + "name": "寻找工具", + "option_num": 3, + "choose": 3, + "requirements": [] + } + ] }, { "name": "度假胜地", @@ -162,13 +256,18 @@ "name": "不见群山", "option_num": 4, "choose": 3, - "choice_require": [ + "choices": [ { "name": "选择她弃在手边的塔罗牌", - "Vision": { - "value": "3", - "type": ">" - } + "option_num": 4, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] } ] }, @@ -176,13 +275,18 @@ "name": "远见所向", "option_num": 4, "choose": 2, - "choice_require": [ + "choices": [ { "name": "我们或许能协作互助", - "Vision": { - "value": "4", - "type": ">" - } + "option_num": 4, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "4" + } + ] } ] }, @@ -210,13 +314,18 @@ "name": "有利可图", "option_num": 3, "choose": 1, - "choice_require": [ + "choices": [ { "name": "分我一点", - "Vision": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] } ] }, @@ -224,17 +333,23 @@ "name": "随行人员", "option_num": 3, "choose": 1, - "choice_require": [ + "choices": [ { "name": "偷听他们聊天", - "LivePoint": { - "value": "3", - "type": ">" - }, - "Vision": { - "value": "1", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "LivePoint", + "type": ">", + "value": "3" + }, + { + "name": "Vision", + "type": ">", + "value": "1" + } + ] } ] }, @@ -242,13 +357,18 @@ "name": "邪恶计划鸭", "option_num": 2, "choose": 2, - "choice_require": [ + "choices": [ { "name": "你在做什么?", - "LivePoint": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "LivePoint", + "type": ">", + "value": "3" + } + ] } ] }, @@ -256,39 +376,68 @@ "name": "百里连营", "option_num": 3, "choose": 2, - "choice_require": [ + "choices": [ { "name": "一边警戒一边前进", - "Vision": { - "value": "1", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "1" + } + ] }, { "name": "走近一些", - "LivePoint": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 1, + "requirements": [ + { + "name": "LivePoint", + "type": ">", + "value": "3" + } + ] } ] }, { "name": "请君入戏", "option_num": 3, - "choose": 1 + "choose": 1, + "choices": [ + { + "name": "钱包掉了", + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "OriginiumIngot", + "type": ">", + "value": "12" + } + ] + } + ] }, { "name": "北风女巫", "option_num": 3, "choose": 2, - "choice_require": [ + "choices": [ { "name": "乖乖照做", - "Vision": { - "value": "5", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "5" + } + ] } ] }, @@ -301,13 +450,18 @@ "name": "猜疑链", "option_num": 3, "choose": 1, - "choice_require": [ + "choices": [ { "name": "勘察情况并维持秩序", - "Vision": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] } ] }, @@ -315,13 +469,18 @@ "name": "走过萨米的臂膀", "option_num": 2, "choose": 1, - "choice_require": [ + "choices": [ { "name": "戴上头盔", - "Relic": { - "value": "树痕之盔", - "type": "have" - } + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "Relic", + "type": "have", + "value": "树痕之盔" + } + ] } ] }, @@ -335,59 +494,118 @@ "option_num": 2, "choose": 1 }, + { + "name": "重构", + "option_num": 2, + "choose": 1, + "choices": [ + { + "name": "过载使用探测仪器", + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] + }, + { + "name": "依靠安玛的遗赠", + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Relic", + "type": "have", + "value": "树痕之盔" + } + ] + } + ] + }, + { + "name": "探索者的一小步", + "option_num": 1, + "choose": 1 + }, { "name": "鲍勃杂货店", "option_num": 3, "choose": 1, - "choice_require": [ + "choices": [ { "name": "选择他脚边的货品", - "Vision": { - "value": "1", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "1" + } + ] }, { "name": "选择仓库深处的货品", - "Vision": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "3" + } + ] + }, + { + "name": "选择仓库深处的货品", + "option_num": 4, + "choose": 4, + "requirements": [ + { + "name": "Relic", + "type": "have", + "value": "四叶草化石" + } + ] } ] }, { "name": "科考站", "option_num": 3, - "choose": 1, - "choice_require": [ - { - "name": "无人机好像有新发现", - "Vision": { - "value": "1", - "type": ">" - } - } - ] + "choose": 1 }, { "name": "北地巫师竞技", "option_num": 2, "choose": 2, - "choice_require": [ + "choices": [ { "name": "接过名册木板,是该选择了!", - "OriginiumIngot": { - "value": "3", - "type": ">" - } + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "OriginiumIngot", + "type": ">", + "value": "3" + } + ] }, { "name": "没来过萨米的人一定没见过!", - "OriginiumIngot": { - "value": "3", - "type": ">" - } + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "OriginiumIngot", + "type": ">", + "value": "3" + } + ] } ] }, @@ -395,41 +613,85 @@ "name": "最好的朋友", "option_num": 2, "choose": 2, - "choice_require": [ + "choices": [ { "name": "仓皇离开", - "Shield": { - "value": "1", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Shield", + "type": ">", + "value": "1" + } + ] }, { "name": "留下", - "LivePointCap": { - "value": "1", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "LivePointCap", + "type": ">", + "value": "1" + } + ] }, { "name": "再喝一口", - "LivePoint": { - "value": "3", - "type": ">" - } + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "LivePoint", + "type": ">", + "value": "3" + } + ] } ] }, { "name": "深渊入口", "option_num": 2, - "choose": 2, - "choice_require": [ + "choose": 1, + "choices": [ + { + "name": "那就试试看", + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "1" + } + ] + }, { "name": "再试试看吧", - "Vision": { - "value": "1", - "type": ">" - } + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "1" + } + ] + }, + { + "name": "设备坏了,就地点样", + "option_num": 2, + "choose": 1, + "requirements": [ + { + "name": "Vision", + "type": "=", + "value": "0" + } + ] } ] }, @@ -437,48 +699,114 @@ "name": "低地市集", "option_num": 3, "choose": 3, - "choice_require": [ + "choices": [ { "name": "选择碎草药", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "选择好看的织物", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "选择湿膏药", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "选择好看的木刻", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "选择纯霜露", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "选择琥珀核", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] + }, + { + "name": "帮助拿着密文版的萨米人", + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Foldartal", + "type": "not have", + "value": "伤痕 && 空无" + } + ] + }, + { + "name": "循着嚎叫声走去", + "option_num": 4, + "choose": 4, + "requirements": [ + { + "name": "Vision", + "type": "=", + "value": "5 || 6" + } + ] + }, + { + "name": "循着号角声走去", + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "6" + } + ] } ] }, @@ -486,20 +814,66 @@ "name": "雪与木的笆篱", "option_num": 3, "choose": 3, - "choice_require": [ + "choices": [ { "name": "“活力”", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "“金钱”", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] + }, + { + "name": "“树痕”", + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Foldartal", + "type": "not have", + "value": "伤痕 && 空无" + } + ] + }, + { + "name": "“战斗”", + "option_num": 4, + "choose": 4, + "requirements": [ + { + "name": "Vision", + "type": "=", + "value": "5 || 6" + } + ] + }, + { + "name": "“护卫”", + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "6" + } + ] } ] }, @@ -507,20 +881,66 @@ "name": "安玛塔卢", "option_num": 3, "choose": 3, - "choice_require": [ + "choices": [ { "name": "寻求希望", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] }, { "name": "寻求护佑", - "ChaosLevel": { - "value": "3", - "type": ">" - } + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "ChaosLevel", + "type": ">", + "value": "3" + } + ] + }, + { + "name": "寻求“树痕”的踪迹", + "option_num": 3, + "choose": 2, + "requirements": [ + { + "name": "Foldartal", + "type": "not have", + "value": "伤痕 && 空无" + } + ] + }, + { + "name": "护卫林地", + "option_num": 4, + "choose": 4, + "requirements": [ + { + "name": "Vision", + "type": "=", + "value": "5 || 6" + } + ] + }, + { + "name": "坚守林地", + "option_num": 3, + "choose": 3, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "6" + } + ] } ] }, @@ -533,16 +953,20 @@ "name": "前行的林地", "option_num": 2, "choose": 2, - "choice_require": [ + "choices": [ { "name": "树上就不能走吗?", - "Vision": { - "value": "1", - "type": ">" - }, - "choose": 1 + "option_num": 2, + "choose": 2, + "requirements": [ + { + "name": "Vision", + "type": ">", + "value": "1" + } + ] } ] } ] -} +} \ No newline at end of file