Files
MaaAssistantArknights/src/MeoAssistant/RoguelikeRecruitTaskPlugin.cpp

214 lines
6.7 KiB
C++

#include "RoguelikeRecruitTaskPlugin.h"
#include "RoguelikeRecruitImageAnalyzer.h"
#include "Controller.h"
#include "TaskData.h"
#include "Resource.h"
#include "Logger.hpp"
#include "RuntimeStatus.h"
#include "ProcessTask.h"
bool asst::RoguelikeRecruitTaskPlugin::verify(AsstMsg msg, const json::value& details) const
{
if (msg != AsstMsg::SubTaskCompleted
|| details.get("subtask", std::string()) != "ProcessTask") {
return false;
}
if (details.at("details").at("task").as_string() == "Roguelike1ChooseOper") {
return true;
}
else {
return false;
}
}
bool asst::RoguelikeRecruitTaskPlugin::_run()
{
LogTraceFunction;
if (check_core_char()) {
return true;
}
bool recruited = false;
auto recruit_oper = [&](const BattleRecruitOperInfo& info) {
select_oper(info);
recruited = true;
};
constexpr int SwipeTimes = 5;
int i = 0;
for (; i != SwipeTimes; ++i) {
auto image = m_ctrler->get_image();
RoguelikeRecruitImageAnalyzer analyzer(image);
if (!analyzer.analyze()) {
return false;
}
const auto& oper_list = analyzer.get_result();
for (const auto& info : oper_list) {
// 先看看有没有精二的
if (info.elite != 2) {
continue;
}
recruit_oper(info);
break;
}
if (!recruited) {
for (const auto& info : oper_list) {
if (!info.required) {
continue;
}
// 拿个精一 50 以上的
if (info.elite == 0 ||
(info.elite == 1 && info.level < 50)) {
continue;
}
recruit_oper(info);
break;
}
}
if (!recruited) {
Log.info("All are lower");
// 随便招个精一的
for (const auto& info : oper_list) {
if (!info.required) {
continue;
}
if (info.elite == 0) {
continue;
}
recruit_oper(info);
break;
}
}
// 这玩意选了也没啥用,不如省点理智
//if (!recruited) {
// // 随便招个
// Log.info("All are very lower");
// auto info = oper_list.front();
// recruit_oper(info);
//}
// 没有合适的干员,尝试向右翻页
if (!recruited) {
ProcessTask(*this, { "SlowlySwipeToTheRight" }).run();
sleep(Task.get("Roguelike1Custom-HijackSquad")->rear_delay);
continue;
}
// 已经招募到合适的干员
return true;
}
Log.info(__FUNCTION__, "did not choose oper.");
swipe_to_the_left_of_operlist(i / 2 + 1);
return false;
}
bool asst::RoguelikeRecruitTaskPlugin::check_core_char()
{
LogTraceFunction;
auto core_opt = m_status->get_str("RoguelikeCoreChar");
if (!core_opt || core_opt->empty()) {
return false;
}
m_status->set_str("RoguelikeCoreChar", "");
constexpr int SwipeTimes = 10;
int i = 0;
for (; i != SwipeTimes; ++i) {
auto image = m_ctrler->get_image();
RoguelikeRecruitImageAnalyzer analyzer(image);
if (!analyzer.analyze()) {
Log.info(__FUNCTION__, "| Unable to analyze image.");
break;
}
const auto& chars = analyzer.get_result();
auto it = ranges::find_if(chars,
[&](const BattleRecruitOperInfo& oper) -> bool {
return oper.name == core_opt.value();
});
std::string oper_names = "";
for (const auto& oper : chars) {
if (!oper_names.empty()) {
oper_names += ", ";
}
oper_names += oper.name;
}
Log.info(__FUNCTION__, "| Oper list:", oper_names);
if (it == chars.cend()) {
slowly_swipe(ProcessTaskAction::SlowlySwipeToTheRight);
sleep(Task.get("Roguelike1Custom-HijackSquad")->rear_delay);
continue;
}
select_oper(*it);
return true;
}
Log.info(__FUNCTION__, "| Cannot find oper `" + core_opt.value() + "`");
swipe_to_the_left_of_operlist();
return false;
}
void asst::RoguelikeRecruitTaskPlugin::select_oper(const BattleRecruitOperInfo& oper)
{
Log.info(__FUNCTION__, "| Choose oper:", oper.name, "( elite", oper.elite, "level", oper.level, ")");
m_ctrler->click(oper.rect);
m_status->set_number(RuntimeStatus::RoguelikeCharElitePrefix + oper.name, oper.elite);
m_status->set_number(RuntimeStatus::RoguelikeCharLevelPrefix + oper.name, oper.level);
std::string overview_str = m_status->get_str(RuntimeStatus::RoguelikeCharOverview).value_or(json::value().to_string());
json::value overview = json::parse(overview_str).value_or(json::value());
overview[oper.name] = json::object{
{ "elite", oper.elite },
{ "level", oper.level },
};
m_status->set_str(RuntimeStatus::RoguelikeCharOverview, overview.to_string());
}
void asst::RoguelikeRecruitTaskPlugin::swipe_to_the_left_of_operlist(int loop_times)
{
LogTraceFunction;
static Rect begin_rect = Task.get("RoguelikeRecruitSwipeToTheLeftBegin")->specific_rect;
static Rect end_rect = Task.get("RoguelikeRecruitSwipeToTheLeftEnd")->specific_rect;
static int duration = Task.get("RoguelikeRecruitSwipeToTheLeftBegin")->pre_delay;
static int extra_delay = Task.get("RoguelikeRecruitSwipeToTheLeftBegin")->rear_delay;
static int cfg_loop_times = Task.get("RoguelikeRecruitSwipeToTheLeftBegin")->max_times;
for (int i = 0; i != cfg_loop_times * loop_times; ++i) {
if (need_exit()) {
return;
}
m_ctrler->swipe(end_rect, begin_rect, duration, true, 0, false);
}
sleep(extra_delay);
}
void asst::RoguelikeRecruitTaskPlugin::slowly_swipe(ProcessTaskAction action)
{
LogTraceFunction;
static Rect right_rect = Task.get("RoguelikeRecruitSlowlySwipeRightRect")->specific_rect;
static Rect left_rect = Task.get("RoguelikeRecruitSlowlySwipeLeftRect")->specific_rect;
static int duration = Task.get("RoguelikeRecruitSlowlySwipeRightRect")->pre_delay;
static int extra_delay = Task.get("RoguelikeRecruitSlowlySwipeRightRect")->rear_delay;
switch (action) {
case asst::ProcessTaskAction::SlowlySwipeToTheLeft:
m_ctrler->swipe(left_rect, right_rect, duration, true, extra_delay, true);
break;
case asst::ProcessTaskAction::SlowlySwipeToTheRight:
m_ctrler->swipe(right_rect, left_rect, duration, true, extra_delay, true);
break;
default: // 走不到这里
break;
}
}