refactor: 重构肉鸽资源加载逻辑和任务流程

This commit is contained in:
zzyyyl
2022-10-13 14:10:15 +08:00
parent b2cf7163fb
commit 0a8db14315
20 changed files with 248 additions and 106 deletions

View File

@@ -12,7 +12,7 @@ bool asst::RoguelikeFormationImageAnalyzer::analyze()
m_result.clear();
MultiMatchImageAnalyzer opers_analyzer(m_image);
opers_analyzer.set_task_info("Roguelike1FormationOper");
opers_analyzer.set_task_info("RoguelikeFormationOper");
if (!opers_analyzer.analyze()) {
return false;
@@ -51,7 +51,7 @@ bool asst::RoguelikeFormationImageAnalyzer::selected_analyze(const Rect& roi)
cv::Mat hsv;
cv::cvtColor(img_roi, hsv, cv::COLOR_BGR2HSV);
const auto selected_task_ptr = Task.get<MatchTaskInfo>("Roguelike1FormationOperSelected");
const auto selected_task_ptr = Task.get<MatchTaskInfo>("RoguelikeFormationOperSelected");
int h_low = selected_task_ptr->mask_range.first;
int h_up = selected_task_ptr->mask_range.second;
int s_low = selected_task_ptr->specific_rect.x;

View File

@@ -10,9 +10,9 @@ bool asst::RoguelikeRecruitImageAnalyzer::analyze()
LogTraceFunction;
OcrWithFlagTemplImageAnalyzer analyzer(m_image);
analyzer.set_task_info("Roguelike1RecruitOcrFlag", "Roguelike1RecruitOcr");
analyzer.set_task_info("RoguelikeRecruitOcrFlag", "RoguelikeRecruitOcr");
analyzer.set_replace(Task.get<OcrTaskInfo>("CharsNameOcrReplace")->replace_map);
analyzer.set_threshold(Task.get("Roguelike1RecruitOcr")->specific_rect.x);
analyzer.set_threshold(Task.get("RoguelikeRecruitOcr")->specific_rect.x);
if (!analyzer.analyze()) {
return false;
@@ -46,9 +46,9 @@ int asst::RoguelikeRecruitImageAnalyzer::match_elite(const Rect& raw_roi)
LogTraceFunction;
static const std::unordered_map<std::string, int> EliteTaskName = {
{ "Roguelike1RecruitElite0", 0 },
{ "Roguelike1RecruitElite1", 1 },
{ "Roguelike1RecruitElite2", 2 },
{ "RoguelikeRecruitElite0", 0 },
{ "RoguelikeRecruitElite1", 1 },
{ "RoguelikeRecruitElite2", 2 },
};
int elite_result = 0;
@@ -76,7 +76,7 @@ int asst::RoguelikeRecruitImageAnalyzer::match_level(const Rect& raw_roi)
{
LogTraceFunction;
auto task_ptr = Task.get("Roguelike1RecruitLevel");
auto task_ptr = Task.get("RoguelikeRecruitLevel");
OcrWithPreprocessImageAnalyzer analyzer(m_image, raw_roi.move(task_ptr->roi));
auto& replace = Task.get<OcrTaskInfo>("NumberOcrReplace")->replace_map;
analyzer.set_replace(replace);

View File

@@ -13,7 +13,7 @@
bool asst::RoguelikeSkillSelectionImageAnalyzer::analyze()
{
MultiMatchImageAnalyzer flag_analyzer(m_image);
flag_analyzer.set_task_info("Roguelike1SkillSelectionFlag");
flag_analyzer.set_task_info("RoguelikeSkillSelectionFlag");
if (!flag_analyzer.analyze()) {
return false;
@@ -49,7 +49,7 @@ bool asst::RoguelikeSkillSelectionImageAnalyzer::analyze()
std::string asst::RoguelikeSkillSelectionImageAnalyzer::name_analyze(const Rect& roi)
{
OcrWithPreprocessImageAnalyzer analyzer;
auto name_task_ptr = Task.get<OcrTaskInfo>("Roguelike1SkillSelectionName");
auto name_task_ptr = Task.get<OcrTaskInfo>("RoguelikeSkillSelectionName");
analyzer.set_threshold(name_task_ptr->specific_rect.x);
analyzer.set_task_info(name_task_ptr);
analyzer.set_image(m_image);
@@ -66,9 +66,9 @@ std::string asst::RoguelikeSkillSelectionImageAnalyzer::name_analyze(const Rect&
std::vector<asst::Rect> asst::RoguelikeSkillSelectionImageAnalyzer::skill_analyze(const Rect& roi)
{
static const std::array<std::string, 3> TasksName = {
"Roguelike1SkillSelectionMove1",
"Roguelike1SkillSelectionMove2",
"Roguelike1SkillSelectionMove3",
"RoguelikeSkillSelectionMove1",
"RoguelikeSkillSelectionMove2",
"RoguelikeSkillSelectionMove3",
};
std::vector<Rect> result;
result.reserve(TasksName.size());
@@ -82,6 +82,6 @@ std::vector<asst::Rect> asst::RoguelikeSkillSelectionImageAnalyzer::skill_analyz
void asst::RoguelikeSkillSelectionImageAnalyzer::team_full_analyze()
{
MatchImageAnalyzer analyzer(m_image);
analyzer.set_task_info("Roguelike1SkillSelectionTeamFull");
analyzer.set_task_info("RoguelikeSkillSelectionTeamFull");
m_team_full = !analyzer.analyze();
}

View File

@@ -19,6 +19,9 @@ bool asst::TemplResource::load(const std::filesystem::path& path)
LogTraceFunction;
Log.info("load", path);
#ifdef ASST_DEBUG
bool some_file_not_exists = false;
#endif
for (const std::string& filename : m_templs_filename) {
std::filesystem::path filepath(path / asst::utils::path(filename));
if (!filepath.has_extension()) {
@@ -33,9 +36,18 @@ bool asst::TemplResource::load(const std::filesystem::path& path)
}
else {
Log.error("Templ load failed, file not exists", filepath);
#ifdef ASST_DEBUG
some_file_not_exists = true;
#else
return false;
#endif
}
}
#ifdef ASST_DEBUG
if (some_file_not_exists) {
return false;
}
#endif
m_loaded = true;
return true;
}

View File

@@ -59,3 +59,23 @@ void asst::RuntimeStatus::clear_str() noexcept
{
m_string.clear();
}
std::optional<std::string> asst::RuntimeStatus::get_properties(const std::string& key) const noexcept
{
if (auto iter = m_properties.find(key); iter != m_properties.cend()) {
return iter->second;
}
else {
return std::nullopt;
}
}
void asst::RuntimeStatus::set_properties(std::string key, std::string value)
{
m_properties.insert_or_assign(std::move(key), std::move(value));
}
void asst::RuntimeStatus::clear_properties() noexcept
{
m_properties.clear();
}

View File

@@ -29,6 +29,10 @@ namespace asst
void set_str(std::string key, std::string value);
void clear_str() noexcept;
std::optional<std::string> get_properties(const std::string& key) const noexcept;
void set_properties(std::string key, std::string value);
void clear_properties() noexcept;
RuntimeStatus& operator=(const RuntimeStatus& rhs) = delete;
RuntimeStatus& operator=(RuntimeStatus&& rhs) noexcept = delete;
@@ -45,6 +49,7 @@ namespace asst
private:
std::unordered_map<std::string, int64_t> m_number;
std::unordered_map<std::string, Rect> m_rect;
std::unordered_map<std::string, std::string> m_string;
std::unordered_map<std::string, std::string> m_string; // 跨任务时会被清理的量
std::unordered_map<std::string, std::string> m_properties; // 跨任务时不会清理的量
};
}

View File

@@ -25,7 +25,17 @@ bool asst::RoguelikeBattleTaskPlugin::verify(AsstMsg msg, const json::value& det
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1StartAction") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@StartAction") {
return true;
}
else {
@@ -89,7 +99,7 @@ bool asst::RoguelikeBattleTaskPlugin::_run()
void asst::RoguelikeBattleTaskPlugin::wait_for_start()
{
ProcessTask(*this, { "Roguelike1WaitBattleStart" }).set_task_delay(0).set_retry_times(0).run();
ProcessTask(*this, { "RoguelikeWaitBattleStart" }).set_task_delay(0).set_retry_times(0).run();
}
bool asst::RoguelikeBattleTaskPlugin::get_stage_info()
@@ -786,7 +796,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle()
bool asst::RoguelikeBattleTaskPlugin::speed_up()
{
return ProcessTask(*this, { "Roguelike1BattleSpeedUp" }).run();
return ProcessTask(*this, { "RoguelikeBattleSpeedUp" }).run();
}
bool asst::RoguelikeBattleTaskPlugin::use_skill(const Rect& rect)
@@ -809,7 +819,7 @@ bool asst::RoguelikeBattleTaskPlugin::retreat(const Point& point)
bool asst::RoguelikeBattleTaskPlugin::abandon()
{
return ProcessTask(*this, { "Roguelike1BattleExitBegin" }).run();
return ProcessTask(*this, { "RoguelikeBattleExitBegin" }).run();
}
void asst::RoguelikeBattleTaskPlugin::all_melee_retreat()

View File

@@ -1,5 +1,7 @@
#include "RoguelikeControlTaskPlugin.h"
#include "RuntimeStatus.h"
bool asst::RoguelikeControlTaskPlugin::verify(AsstMsg msg, const json::value& details) const
{
if (msg != AsstMsg::SubTaskExtraInfo || details.get("subtask", std::string()) != "ProcessTask") {
@@ -10,9 +12,18 @@ bool asst::RoguelikeControlTaskPlugin::verify(AsstMsg msg, const json::value& de
return false;
}
const std::string task = details.at("details").at("task").as_string();
if (task == "Roguelike1Start" || task == "Roguelike1StageTraderInvestConfirm" ||
task == "Roguelike1StageTraderInvestSystemFull") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@Start" || task_view == "Roguelike@StageTraderInvestConfirm" ||
task_view == "Roguelike@StageTraderInvestSystemFull") {
return true;
}

View File

@@ -14,13 +14,22 @@ bool asst::RoguelikeCustomStartTaskPlugin::verify(AsstMsg msg, const json::value
return false;
}
static const std::unordered_map<std::string, std::pair<AsstMsg, RoguelikeCustomType>> TaskMap = {
{ "Roguelike1Recruit1", { AsstMsg::SubTaskCompleted, RoguelikeCustomType::Squad } },
{ "Roguelike1Team3", { AsstMsg::SubTaskCompleted, RoguelikeCustomType::Roles } },
{ "Roguelike1RecruitMain", { AsstMsg::SubTaskStart, RoguelikeCustomType::CoreChar } },
};
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
auto it = TaskMap.find(task);
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
static const std::unordered_map<std::string_view, std::pair<AsstMsg, RoguelikeCustomType>> TaskMap = {
{ "Roguelike@Recruit1", { AsstMsg::SubTaskCompleted, RoguelikeCustomType::Squad } },
{ "Roguelike@Team3", { AsstMsg::SubTaskCompleted, RoguelikeCustomType::Roles } },
{ "Roguelike@RecruitMain", { AsstMsg::SubTaskStart, RoguelikeCustomType::CoreChar } },
};
auto it = TaskMap.find(task_view);
if (it == TaskMap.cend()) {
return false;
}
@@ -70,12 +79,12 @@ bool asst::RoguelikeCustomStartTaskPlugin::hijack_squad()
for (size_t i = 0; i != SwipeTimes; ++i) {
auto image = m_ctrler->get_image();
OcrImageAnalyzer analyzer(image);
analyzer.set_task_info("Roguelike1Custom-HijackSquad");
analyzer.set_task_info("RoguelikeCustom-HijackSquad");
analyzer.set_required({ m_customs[RoguelikeCustomType::Squad] });
if (!analyzer.analyze()) {
ProcessTask(*this, { "SlowlySwipeToTheRight" }).run();
sleep(Task.get("Roguelike1Custom-HijackSquad")->rear_delay);
sleep(Task.get("RoguelikeCustom-HijackSquad")->rear_delay);
continue;
}
const auto& rect = analyzer.get_result().front().rect;
@@ -90,7 +99,7 @@ bool asst::RoguelikeCustomStartTaskPlugin::hijack_roles()
{
auto image = m_ctrler->get_image();
OcrImageAnalyzer analyzer(image);
analyzer.set_task_info("Roguelike1Custom-HijackRoles");
analyzer.set_task_info("RoguelikeCustom-HijackRoles");
analyzer.set_required({ m_customs[RoguelikeCustomType::Roles] });
if (!analyzer.analyze()) {
@@ -121,7 +130,7 @@ bool asst::RoguelikeCustomStartTaskPlugin::hijack_core_char()
Log.info("role", role_ocr_name);
auto image = m_ctrler->get_image();
OcrImageAnalyzer analyzer(image);
analyzer.set_task_info("Roguelike1Custom-HijackCoChar");
analyzer.set_task_info("RoguelikeCustom-HijackCoChar");
analyzer.set_required({ role_ocr_name });
if (!analyzer.analyze()) {
return false;
@@ -129,7 +138,7 @@ bool asst::RoguelikeCustomStartTaskPlugin::hijack_core_char()
const auto& role_rect = analyzer.get_result().front().rect;
m_ctrler->click(role_rect);
sleep(Task.get("Roguelike1Custom-HijackCoChar")->pre_delay);
sleep(Task.get("RoguelikeCustom-HijackCoChar")->pre_delay);
m_status->set_str(RuntimeStatus::RoguelikeCoreChar, char_name);
return true;

View File

@@ -1,6 +1,7 @@
#include "RoguelikeDebugTaskPlugin.h"
#include "Controller.h"
#include "RuntimeStatus.h"
bool asst::RoguelikeDebugTaskPlugin::verify(AsstMsg msg, const json::value& details) const
{
@@ -12,9 +13,18 @@ bool asst::RoguelikeDebugTaskPlugin::verify(AsstMsg msg, const json::value& deta
return true;
}
std::string task = details.get("details", "task", std::string());
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (msg == AsstMsg::SubTaskStart && details.get("subtask", std::string()) == "ProcessTask") {
if (task == "Roguelike1ExitThenAbandon" || task == "Roguelike1GamePass") {
if (task_view == "Roguelike@ExitThenAbandon" || task_view == "Roguelike@GamePass") {
return true;
}
}

View File

@@ -6,6 +6,7 @@
#include "Controller.h"
#include "ImageAnalyzer/RoguelikeFormationImageAnalyzer.h"
#include "TaskData.h"
#include "RuntimeStatus.h"
#include "Utils/Logger.hpp"
bool asst::RoguelikeFormationTaskPlugin::verify(AsstMsg msg, const json::value& details) const
@@ -14,7 +15,17 @@ bool asst::RoguelikeFormationTaskPlugin::verify(AsstMsg msg, const json::value&
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1QuickFormation") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@QuickFormation") {
return true;
}
else {
@@ -50,7 +61,7 @@ bool asst::RoguelikeFormationTaskPlugin::_run()
reselect = true;
}
if (!reselect && select_count != 0) {
sleep(Task.get("Roguelike1QuickFormationDelay")->rear_delay);
sleep(Task.get("RoguelikeQuickFormationDelay")->rear_delay);
formation_analyzer.set_image(m_ctrler->get_image());
if (!formation_analyzer.analyze()) {
@@ -76,7 +87,7 @@ bool asst::RoguelikeFormationTaskPlugin::_run()
void asst::RoguelikeFormationTaskPlugin::clear_and_reselect()
{
// 清空并退出游戏会自动按等级重新排序
ProcessTask(*this, { "Roguelike1QuickFormationClearAndReselect" }).run();
ProcessTask(*this, { "RoguelikeQuickFormationClearAndReselect" }).run();
size_t select_count = analyze_and_select();
// 说明第二页还有

View File

@@ -14,7 +14,17 @@ bool asst::RoguelikeRecruitTaskPlugin::verify(AsstMsg msg, const json::value& de
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1ChooseOper") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@ChooseOper") {
return true;
}
else {
@@ -52,7 +62,7 @@ bool asst::RoguelikeRecruitTaskPlugin::_run()
// 干员名字的识别位置
std::unordered_map<std::string, Rect> last_oper_rects;
int SwipeTimes = Task.get("Roguelike1RecruitSwipeMaxTime")->max_times;
int SwipeTimes = Task.get("RoguelikeRecruitSwipeMaxTime")->max_times;
int i = 0;
std::unordered_set<std::string> pre_oper_names;
// 翻页找出所有候选干员
@@ -182,7 +192,7 @@ bool asst::RoguelikeRecruitTaskPlugin::_run()
// 向右滑动
Log.trace(__FUNCTION__, "| Page", i, "oper count:", oper_count, "- continue swiping");
slowly_swipe(ProcessTaskAction::SlowlySwipeToTheRight);
sleep(Task.get("Roguelike1Custom-HijackSquad")->rear_delay);
sleep(Task.get("RoguelikeCustom-HijackSquad")->rear_delay);
}
// 没有候选干员,进入后备逻辑
@@ -307,7 +317,7 @@ bool asst::RoguelikeRecruitTaskPlugin::check_char(const std::string& char_name,
else {
slowly_swipe(ProcessTaskAction::SlowlySwipeToTheRight);
}
sleep(Task.get("Roguelike1Custom-HijackSquad")->rear_delay);
sleep(Task.get("RoguelikeCustom-HijackSquad")->rear_delay);
}
Log.info(__FUNCTION__, "| Cannot find oper `" + char_name + "`");
swipe_to_the_left_of_operlist(i / 3 + 1);

View File

@@ -8,7 +8,17 @@ bool asst::RoguelikeResetTaskPlugin::verify(AsstMsg msg, const json::value& deta
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1Start") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@Start") {
return true;
}
else {

View File

@@ -14,7 +14,17 @@ bool asst::RoguelikeShoppingTaskPlugin::verify(AsstMsg msg, const json::value& d
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1TraderRandomShopping") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@TraderRandomShopping") {
return true;
}
else {
@@ -27,7 +37,7 @@ bool asst::RoguelikeShoppingTaskPlugin::_run()
LogTraceFunction;
OcrWithFlagTemplImageAnalyzer analyzer;
analyzer.set_task_info("Roguelike1TraderShopping", "Roguelike1TraderShoppingOcr");
analyzer.set_task_info("RoguelikeTraderShopping", "RoguelikeTraderShoppingOcr");
analyzer.set_image(m_ctrler->get_image());
if (!analyzer.analyze()) {
@@ -151,7 +161,7 @@ bool asst::RoguelikeShoppingTaskPlugin::_run()
if (!bought) {
// 如果什么都没买,即使有商品,说明也是不需要买的,这里强制离开商店,后面让 ProcessTask 继续跑
return ProcessTask(*this, { "Roguelike1TraderShoppingOver" }).run();
return ProcessTask(*this, { "RoguelikeTraderShoppingOver" }).run();
}
return true;

View File

@@ -14,7 +14,17 @@ bool asst::RoguelikeSkillSelectionTaskPlugin::verify(AsstMsg msg, const json::va
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1StartAction") {
auto roguelike_name_opt = m_status->get_properties("roguelike_name");
if (!roguelike_name_opt) {
return false;
}
const auto& roguelike_name = roguelike_name_opt.value() + "@";
const std::string& task = details.get("details", "task", "");
std::string_view task_view = task;
if (task_view.starts_with(roguelike_name)) {
task_view.remove_prefix(roguelike_name.length());
}
if (task_view == "Roguelike@StartAction") {
return true;
}
else {
@@ -33,7 +43,7 @@ bool asst::RoguelikeSkillSelectionTaskPlugin::_run()
return false;
}
int delay = Task.get("Roguelike1SkillSelectionMove1")->rear_delay;
int delay = Task.get("RoguelikeSkillSelectionMove1")->rear_delay;
bool has_rookie = false;
for (const auto& [name, skill_vec] : analyzer.get_result()) {
if (name.empty()) {

View File

@@ -9,15 +9,15 @@
#include "Plugin/RoguelikeResetTaskPlugin.h"
#include "Plugin/RoguelikeShoppingTaskPlugin.h"
#include "Plugin/RoguelikeSkillSelectionTaskPlugin.h"
#include "RuntimeStatus.h"
#include "Sub/ProcessTask.h"
#include "Utils/Logger.hpp"
asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, void* callback_arg)
: PackageTask(callback, callback_arg, TaskType),
m_roguelike_task_ptr(std::make_shared<ProcessTask>(callback, callback_arg, TaskType))
{
m_roguelike_task_ptr->set_tasks({ "Roguelike1Begin" });
m_roguelike_task_ptr->set_tasks({ "Stop" });
m_roguelike_task_ptr->register_plugin<RoguelikeFormationTaskPlugin>();
m_roguelike_task_ptr->register_plugin<RoguelikeControlTaskPlugin>();
@@ -45,16 +45,26 @@ bool asst::RoguelikeTask::set_params(const json::value& params)
// 2 - 【弃用】两者兼顾,投资过后再退出,没有投资就继续往后打
// 3 - 尝试通关,激进策略
std::string roguelike_name = params.get("name", "Phantom");
if (m_status == nullptr) {
m_roguelike_task_ptr->set_tasks({ "Stop" });
Log.error(__FUNCTION__, "| Cannot set roguelike name!");
return false;
}
m_status->set_properties("roguelike_name", roguelike_name);
roguelike_name += "@";
m_roguelike_task_ptr->set_tasks({ roguelike_name + "Roguelike@Begin" });
int mode = params.get("mode", 0);
switch (mode) {
case 0:
break;
case 1:
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderLeaveConfirm", 0,
m_roguelike_task_ptr->set_times_limit("StageTraderLeaveConfirm", 0,
ProcessTask::TimesLimitType::Post);
break;
case 2:
[[unlikely]] m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestCancel", 0);
[[unlikely]] m_roguelike_task_ptr->set_times_limit("StageTraderInvestCancel", 0);
break;
default:
Log.error(__FUNCTION__, "| Unknown mode", mode);
@@ -62,22 +72,22 @@ bool asst::RoguelikeTask::set_params(const json::value& params)
}
int number_of_starts = params.get("starts_count", INT_MAX);
m_roguelike_task_ptr->set_times_limit("Roguelike1Start", number_of_starts);
m_roguelike_task_ptr->set_times_limit(roguelike_name + "Roguelike@Start", number_of_starts);
bool investment_enabled = params.get("investment_enabled", true);
if (!investment_enabled) {
// 禁用投资系统,通过 exceededNext 进入商店购买逻辑
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestSystem", 0);
m_roguelike_task_ptr->set_times_limit("StageTraderInvestSystem", 0);
}
int number_of_investments = params.get("investments_count", INT_MAX);
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestConfirm", number_of_investments);
m_roguelike_task_ptr->set_times_limit("StageTraderInvestConfirm", number_of_investments);
bool stop_when_full = params.get("stop_when_investment_full", false);
if (stop_when_full) {
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestSystemFull", 0);
m_roguelike_task_ptr->set_times_limit("StageTraderInvestSystemFull", 0);
constexpr int InvestLimit = 999;
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestConfirm", InvestLimit);
m_roguelike_task_ptr->set_times_limit("StageTraderInvestConfirm", InvestLimit);
}
if (auto squad_opt = params.find<std::string>("squad")) {

View File

@@ -60,14 +60,18 @@ bool asst::TaskData::parse(const json::value& json)
}
#ifdef ASST_DEBUG
bool some_next_null = false;
for (const auto& [name, task] : m_all_tasks_info) {
for (const auto& next : task->next) {
if (get(next) == nullptr) {
Log.error(name, "'s next", next, "is null");
return false;
some_next_null = true;
}
}
}
if (some_next_null) {
return false;
}
#endif
return true;
}

View File

@@ -163,24 +163,6 @@ namespace MeoAsstGui
}
private string _curResource = "_Unloaded";
private bool _additionalLoaded = false;
public bool LoadAdditionalResource()
{
if (_additionalLoaded)
{
return true;
}
var settingsModel = _container.Get<SettingsViewModel>();
if (settingsModel.RoguelikeTheme != "Roguelike1")
{
_additionalLoaded = AsstLoadResource(Directory.GetCurrentDirectory() + "\\resource\\addition\\" + settingsModel.RoguelikeTheme + "\\");
return _additionalLoaded;
}
return true;
}
/// <summary>
/// 加载全局资源。
@@ -194,8 +176,6 @@ namespace MeoAsstGui
return true;
}
_additionalLoaded = false;
bool loaded = true;
if (settingsModel.ClientType == string.Empty
|| settingsModel.ClientType == "Official" || settingsModel.ClientType == "Bilibili")
@@ -245,11 +225,13 @@ namespace MeoAsstGui
public void Init()
{
// TODO: 屎山.jpg过几个版本再把这两行删了
File.Delete(Directory.GetCurrentDirectory() + "\\resource\\addition\\Roguelike2\\resource\\roguelike_recruit.json");
File.Delete(Directory.GetCurrentDirectory() + "\\resource\\addition\\Roguelike2\\resource\\roguelike_shopping.json");
DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\resource\\addition\\");
if (dir.Exists)
{
dir.Delete(true);
}
bool loaded = LoadResource();
loaded &= LoadAdditionalResource();
_handle = AsstCreateEx(_callback, IntPtr.Zero);
@@ -611,6 +593,23 @@ namespace MeoAsstGui
if (subTask == "ProcessTask")
{
string taskName = details["details"]["task"].ToString();
var replaceNameMap = new Dictionary<string, string>
{
{ "Phantom@Roguelike@", "Roguelike" },
{ "Mizuki@Roguelike@", "Roguelike" },
{ "Roguelike@", "Roguelike" },
{ "Phantom@", "Roguelike" },
{ "Mizuki@", "Roguelike" },
};
foreach (var ignoreName in replaceNameMap)
{
if (taskName.StartsWith(ignoreName.Key))
{
taskName = ignoreName.Value + taskName.Substring(ignoreName.Key.Length);
}
}
int execTimes = (int)details["details"]["exec_times"];
switch (taskName)
@@ -645,62 +644,62 @@ namespace MeoAsstGui
break;
/* 肉鸽相关 */
case "Roguelike1Start":
case "RoguelikeStart":
mainModel.AddLog(Localization.GetString("BegunToExplore") + $" {execTimes} " + Localization.GetString("UnitTime"), LogColor.Info);
break;
case "Roguelike1StageTraderInvestConfirm":
case "RoguelikeStageTraderInvestConfirm":
mainModel.AddLog(Localization.GetString("HasInvested") + $" {execTimes} " + Localization.GetString("UnitTime"), LogColor.Info);
break;
case "Roguelike1ExitThenAbandon":
case "RoguelikeExitThenAbandon":
mainModel.AddLog(Localization.GetString("ExplorationAbandoned"));
break;
// case "Roguelike1StartAction":
// case "RoguelikeStartAction":
// mainModel.AddLog("开始战斗");
// break;
case "Roguelike1MissionCompletedFlag":
case "RoguelikeMissionCompletedFlag":
mainModel.AddLog(Localization.GetString("FightCompleted"));
break;
case "Roguelike1MissionFailedFlag":
case "RoguelikeMissionFailedFlag":
mainModel.AddLog(Localization.GetString("FightFailed"));
break;
case "Roguelike1StageTraderEnter":
case "RoguelikeStageTraderEnter":
mainModel.AddLog(Localization.GetString("Trader"));
break;
case "Roguelike1StageSafeHouseEnter":
case "RoguelikeStageSafeHouseEnter":
mainModel.AddLog(Localization.GetString("SafeHouse"));
break;
case "Roguelike1StageEncounterEnter":
case "RoguelikeStageEncounterEnter":
mainModel.AddLog(Localization.GetString("Encounter"));
break;
// case "Roguelike1StageBoonsEnter":
// case "RoguelikeStageBoonsEnter":
// mainModel.AddLog("古堡馈赠");
// break;
case "Roguelike1StageCambatDpsEnter":
case "RoguelikeStageCambatDpsEnter":
mainModel.AddLog(Localization.GetString("CambatDps"));
break;
case "Roguelike1StageEmergencyDps":
case "RoguelikeStageEmergencyDps":
mainModel.AddLog(Localization.GetString("EmergencyDps"));
break;
case "Roguelike1StageDreadfulFoe":
case "Roguelike2StageDreadfulFoe-5Enter":
case "RoguelikeStageDreadfulFoe":
case "RoguelikeStageDreadfulFoe-5Enter":
mainModel.AddLog(Localization.GetString("DreadfulFoe"));
break;
case "Roguelike1StageTraderInvestSystemFull":
case "RoguelikeStageTraderInvestSystemFull":
mainModel.AddLog(Localization.GetString("UpperLimit"), LogColor.Info);
break;
case "RestartGameAndContinueFighting":
case "RestartGameAndContinue":
mainModel.AddLog(Localization.GetString("GameCrash"), LogColor.Warning);
break;
@@ -708,7 +707,7 @@ namespace MeoAsstGui
mainModel.AddLog(Localization.GetString("GameDrop"), LogColor.Warning);
break;
case "Roguelike1GamePass":
case "RoguelikeGamePass":
mainModel.AddLog(Localization.GetString("RoguelikeGamePass"), LogColor.RareOperator);
break;
}
@@ -1031,7 +1030,7 @@ namespace MeoAsstGui
/// <returns>是否成功。</returns>
public bool AsstConnect(ref string error)
{
if (!LoadResource() || !LoadAdditionalResource())
if (!LoadResource())
{
error = "Load Resource Failed";
return false;
@@ -1421,9 +1420,10 @@ namespace MeoAsstGui
/// <param name="squad"><paramref name="squad"/> TODO.</param>
/// <param name="roles"><paramref name="roles"/> TODO.</param>
/// <param name="core_char"><paramref name="core_char"/> TODO.</param>
/// <param name="roguelike_name">肉鸽名字。["Phantom", "Mizuki"]</param>
/// <returns>是否成功。</returns>
public bool AsstAppendRoguelike(int mode, int starts, bool investment_enabled, int invests, bool stop_when_full,
string squad, string roles, string core_char)
string squad, string roles, string core_char, string roguelike_name)
{
var task_params = new JObject();
task_params["mode"] = mode;
@@ -1431,6 +1431,7 @@ namespace MeoAsstGui
task_params["investment_enabled"] = investment_enabled;
task_params["investments_count"] = invests;
task_params["stop_when_investment_full"] = stop_when_full;
task_params["name"] = roguelike_name;
if (squad.Length > 0)
{
task_params["squad"] = squad;

View File

@@ -176,8 +176,8 @@ namespace MeoAsstGui
RoguelikeThemeList = new List<CombData>
{
new CombData { Display = Localization.GetString("RoguelikeThemePhantom"), Value = "Roguelike1" },
new CombData { Display = Localization.GetString("RoguelikeThemeMizuki"), Value = "Roguelike2" },
new CombData { Display = Localization.GetString("RoguelikeThemePhantom"), Value = "Phantom" },
new CombData { Display = Localization.GetString("RoguelikeThemeMizuki"), Value = "Mizuki" },
};
RoguelikeSquadList = new List<CombData>
@@ -791,7 +791,7 @@ namespace MeoAsstGui
/* 肉鸽设置 */
private string _roguelikeTheme = ViewStatusStorage.Get("Roguelike.RoguelikeTheme", "Roguelike1");
private string _roguelikeTheme = ViewStatusStorage.Get("Roguelike.RoguelikeTheme", "Phantom");
/// <summary>
/// Gets or sets the Roguelike theme.

View File

@@ -949,14 +949,13 @@ namespace MeoAsstGui
private bool appendRoguelike()
{
var settings = _container.Get<SettingsViewModel>();
int mode;
int.TryParse(settings.RoguelikeMode, out mode);
int.TryParse(settings.RoguelikeMode, out var mode);
var asstProxy = _container.Get<AsstProxy>();
return asstProxy.AsstAppendRoguelike(
mode, settings.RoguelikeStartsCount,
settings.RoguelikeInvestmentEnabled, settings.RoguelikeInvestsCount, settings.RoguelikeStopWhenInvestmentFull,
settings.RoguelikeSquad, settings.RoguelikeRoles, settings.RoguelikeCoreChar);
settings.RoguelikeSquad, settings.RoguelikeRoles, settings.RoguelikeCoreChar, settings.RoguelikeTheme);
}
[DllImport("User32.dll", EntryPoint = "FindWindow")]