Files
MaaAssistantArknights/src/MaaCore/Task/Interface/RoguelikeTask.cpp
2023-09-30 20:00:22 +08:00

188 lines
9.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "RoguelikeTask.h"
#include "Common/AsstBattleDef.h"
#include "Config/TaskData.h"
#include "Status.h"
#include "Task/ProcessTask.h"
#include "Task/Roguelike/RoguelikeBattleTaskPlugin.h"
#include "Task/Roguelike/RoguelikeControlTaskPlugin.h"
#include "Task/Roguelike/RoguelikeCustomStartTaskPlugin.h"
#include "Task/Roguelike/RoguelikeDebugTaskPlugin.h"
#include "Task/Roguelike/RoguelikeDifficultySelectionTaskPlugin.h"
#include "Task/Roguelike/RoguelikeFormationTaskPlugin.h"
#include "Task/Roguelike/RoguelikeLastRewardTaskPlugin.h"
#include "Task/Roguelike/RoguelikeRecruitTaskPlugin.h"
#include "Task/Roguelike/RoguelikeResetTaskPlugin.h"
#include "Task/Roguelike/RoguelikeShoppingTaskPlugin.h"
#include "Task/Roguelike/RoguelikeSkillSelectionTaskPlugin.h"
#include "Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h"
#include "Utils/Logger.hpp"
asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, Assistant* inst)
: InterfaceTask(callback, inst, TaskType),
m_roguelike_task_ptr(std::make_shared<ProcessTask>(callback, inst, TaskType))
{
LogTraceFunction;
m_roguelike_task_ptr->set_ignore_error(true);
m_roguelike_task_ptr->register_plugin<RoguelikeFormationTaskPlugin>();
m_roguelike_task_ptr->register_plugin<RoguelikeControlTaskPlugin>();
m_roguelike_task_ptr->register_plugin<RoguelikeResetTaskPlugin>();
m_debug_task_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeDebugTaskPlugin>();
m_roguelike_task_ptr->register_plugin<RoguelikeShoppingTaskPlugin>()->set_retry_times(0);
m_custom_start_task_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeCustomStartTaskPlugin>();
m_battle_task_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeBattleTaskPlugin>();
m_battle_task_ptr->set_retry_times(0).set_ignore_error(true);
m_recruit_task_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeRecruitTaskPlugin>();
m_recruit_task_ptr->set_retry_times(2).set_ignore_error(true);
m_skill_task_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeSkillSelectionTaskPlugin>();
m_skill_task_ptr->set_retry_times(2).set_ignore_error(true);
m_roguelike_task_ptr->register_plugin<RoguelikeStageEncounterTaskPlugin>()->set_retry_times(0);
m_roguelike_task_ptr->register_plugin<RoguelikeLastRewardTaskPlugin>();
m_roguelike_task_ptr->register_plugin<RoguelikeDifficultySelectionTaskPlugin>();
// 这个任务如果卡住会放弃当前的肉鸽并重新开始,所以多添加一点。先这样凑合用
for (int i = 0; i != 100; ++i) {
m_subtasks.emplace_back(m_roguelike_task_ptr);
}
}
bool asst::RoguelikeTask::set_params(const json::value& params)
{
LogTraceFunction;
std::string theme = params.get("theme", std::string(RoguelikePhantomThemeName));
if (theme != RoguelikePhantomThemeName && theme != RoguelikeMizukiThemeName && theme != RoguelikeSamiThemeName) {
Log.error("Unknown roguelike theme", theme);
return false;
}
if (status() == nullptr) {
m_roguelike_task_ptr->set_tasks({ "Stop" });
Log.error(__FUNCTION__, "status() is null");
return false;
}
status()->set_properties(Status::RoguelikeTheme, theme);
m_roguelike_task_ptr->set_tasks({ theme + "@Roguelike@Begin" });
// 0 - 刷经验,尽可能稳定地打更多层数,不期而遇采用激进策略
// 1 - 刷源石锭,第一层投资完就退出,不期而遇采用保守策略
// 2 - 【已移除】两者兼顾,投资过后再退出,没有投资就继续往后打
// 3 - 尝试通关激进策略TODO
// 4 - 刷开局藏品,以获得热水壶或者演讲稿开局,不期而遇采用保守策略
int mode = params.get("mode", 0);
if (mode != 0 && mode != 1 && mode != 4) {
m_roguelike_task_ptr->set_tasks({ "Stop" });
Log.error(__FUNCTION__, "| Unknown mode", mode);
return false;
}
m_debug_task_ptr->set_enable(mode != 1);
// 是否凹指定干员开局直升
bool start_with_elite_two = params.get("start_with_elite_two", false);
status()->set_properties(Status::RoguelikeMode, std::to_string(mode));
status()->set_properties(Status::RoguelikeNeedChangeDifficulty, "0");
status()->set_properties(Status::RoguelikeStartWithEliteTwo, std::to_string(start_with_elite_two));
if (mode == 4) {
// 设置ocr第三层层名设置识别到退出重进
Task.get<OcrTaskInfo>(theme + "@Roguelike@LevelName")->text =
Task.get<OcrTaskInfo>(theme + "@Roguelike@LevelName_mode4")->text;
Task.get(theme + "@Roguelike@LevelName")->next = Task.get(theme + "@Roguelike@LevelName_mode4")->next;
if (!start_with_elite_two) {
// 获得热水壶和演讲时长延时
Task.get(theme + "@Roguelike@LastReward")->post_delay =
Task.get(theme + "@Roguelike@LastReward_mode4")->post_delay;
Task.get(theme + "@Roguelike@LastReward4")->post_delay =
Task.get(theme + "@Roguelike@LastReward_mode4")->post_delay;
}
// 获得其他奖励时重开
Task.get(theme + "@Roguelike@LastReward2")->next = Task.get(theme + "@Roguelike@LastReward_mode4")->next;
Task.get(theme + "@Roguelike@LastReward3")->next = Task.get(theme + "@Roguelike@LastReward_mode4")->next;
Task.get(theme + "@Roguelike@LastRewardRand")->next = Task.get(theme + "@Roguelike@LastReward_mode4")->next;
}
else {
// 重置需要ocr的层名和next任务
Task.get<OcrTaskInfo>(theme + "@Roguelike@LevelName")->text =
Task.get<OcrTaskInfo>(theme + "@Roguelike@LevelName_normal_mode")->text;
Task.get(theme + "@Roguelike@LevelName")->next = Task.get(theme + "@Roguelike@LevelName_normal_mode")->next;
// 重置获得热水壶和演讲延时
Task.get(theme + "@Roguelike@LastReward")->post_delay =
Task.get(theme + "@Roguelike@LastReward_normal_mode")->post_delay;
Task.get(theme + "@Roguelike@LastReward4")->post_delay =
Task.get(theme + "@Roguelike@LastReward_normal_mode")->post_delay;
// 重置其他奖励next
Task.get(theme + "@Roguelike@LastReward2")->next = Task.get(theme + "@Roguelike@LastReward_normal_mode")->next;
Task.get(theme + "@Roguelike@LastReward3")->next = Task.get(theme + "@Roguelike@LastReward_normal_mode")->next;
Task.get(theme + "@Roguelike@LastRewardRand")->next =
Task.get(theme + "@Roguelike@LastReward_normal_mode")->next;
}
if (mode == 1) {
// 战斗后奖励只拿钱
Task.get(theme + "@Roguelike@DropsFlag")->next = Task.get(theme + "@Roguelike@DropsFlag_mode1")->next;
// 刷源石锭模式是否进入第二层
bool investment_enter_second_floor = params.get("investment_enter_second_floor", true);
if (investment_enter_second_floor) {
m_roguelike_task_ptr->set_times_limit("StageTraderLeave", INT_MAX);
m_roguelike_task_ptr->set_times_limit("StageTraderLeaveConfirm", 0, ProcessTask::TimesLimitType::Post);
}
else {
m_roguelike_task_ptr->set_times_limit("StageTraderLeave", 0);
m_roguelike_task_ptr->set_times_limit("StageTraderLeaveConfirm", INT_MAX);
}
}
else {
// 重置战斗后奖励next
Task.get(theme + "@Roguelike@DropsFlag")->next = Task.get(theme + "@Roguelike@DropsFlag_normal_mode")->next;
m_roguelike_task_ptr->set_times_limit("StageTraderLeave", INT_MAX);
m_roguelike_task_ptr->set_times_limit("StageTraderLeaveConfirm", INT_MAX);
}
int number_of_starts = params.get("starts_count", INT_MAX);
m_roguelike_task_ptr->set_times_limit(theme + "@Roguelike@StartExplore", number_of_starts);
bool investment_enabled = params.get("investment_enabled", true);
if (!investment_enabled) {
// 禁用投资系统,通过 exceededNext 进入商店购买逻辑
m_roguelike_task_ptr->set_times_limit("StageTraderInvestSystem", 0);
}
bool refresh_trader_with_dice = params.get("refresh_trader_with_dice", false);
if (!refresh_trader_with_dice) {
m_roguelike_task_ptr->set_times_limit("StageTraderRefreshWithDice", 0);
}
int number_of_investments = params.get("investments_count", INT_MAX);
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("StageTraderInvestSystemFull", 0);
constexpr int InvestLimit = 999;
m_roguelike_task_ptr->set_times_limit("StageTraderInvestConfirm", InvestLimit);
}
if (auto squad_opt = params.find<std::string>("squad"); squad_opt && !squad_opt->empty()) {
m_custom_start_task_ptr->set_custom(RoguelikeCustomType::Squad, *squad_opt);
}
if (auto roles_opt = params.find<std::string>("roles"); roles_opt && !roles_opt->empty()) {
m_custom_start_task_ptr->set_custom(RoguelikeCustomType::Roles, *roles_opt);
}
if (auto core_char_opt = params.find<std::string>("core_char"); core_char_opt && !core_char_opt->empty()) {
m_custom_start_task_ptr->set_custom(RoguelikeCustomType::CoreChar, *core_char_opt);
}
if (auto use_support_opt = params.find<bool>("use_support"); use_support_opt) {
m_custom_start_task_ptr->set_custom(RoguelikeCustomType::UseSupport, *use_support_opt ? "1" : "0");
}
if (auto use_nonfriend_opt = params.find<bool>("use_nonfriend_support"); use_nonfriend_opt) {
m_custom_start_task_ptr->set_custom(RoguelikeCustomType::UseNonfriendSupport, *use_nonfriend_opt ? "1" : "0");
}
return true;
}