mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-16 01:40:46 +08:00
Reapply "feat:实现自适应调整连战次数 (#12555)"
This reverts commit 7359653317.
移除不相关的文件修改
---------
Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
This commit is contained in:
@@ -1253,6 +1253,11 @@
|
||||
"action": "ClickRect",
|
||||
"specificRect": [965, 200, 70, 50]
|
||||
},
|
||||
"FightSeries-List-Exceeded": {
|
||||
"template": "FightSeries-List-Exceeded.png",
|
||||
"roi": [965, 200, 70, 325],
|
||||
"doc": "找到每一个需要补充理智的连战次数"
|
||||
},
|
||||
"StartButton1": {
|
||||
"doc": "绑定插件调整连战次数",
|
||||
"algorithm": "OcrDetect",
|
||||
@@ -1520,6 +1525,7 @@
|
||||
"next": ["CloseStonePage"]
|
||||
},
|
||||
"CloseStonePage": {
|
||||
"Doc": "2025.5.5:next 在 FightSeriesAdjustPlugin 插件中被动态修改",
|
||||
"algorithm": "JustReturn",
|
||||
"action": "ClickRect",
|
||||
"specificRect": [0, 200, 300, 400],
|
||||
|
||||
BIN
resource/template/FightSeries-List-Exceeded.png
Normal file
BIN
resource/template/FightSeries-List-Exceeded.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 336 B |
@@ -248,6 +248,7 @@
|
||||
<ClInclude Include="LDExtras.h" />
|
||||
<ClInclude Include="Task\Experiment\CombatRecordRecognitionTask.h" />
|
||||
<ClInclude Include="Task\Experiment\SingleStepBattleProcessTask.h" />
|
||||
<ClInclude Include="Task\Fight\FightSeriesAdjustPlugin.h" />
|
||||
<ClInclude Include="Task\Fight\FightTimesTaskPlugin.h" />
|
||||
<ClInclude Include="Task\Fight\MedicineCounterTaskPlugin.h" />
|
||||
<ClInclude Include="Task\Fight\SanityBeforeStageTaskPlugin.h" />
|
||||
@@ -446,6 +447,7 @@
|
||||
<ClCompile Include="LDExtras.cpp" />
|
||||
<ClCompile Include="Task\Experiment\CombatRecordRecognitionTask.cpp" />
|
||||
<ClCompile Include="Task\Experiment\SingleStepBattleProcessTask.cpp" />
|
||||
<ClCompile Include="Task\Fight\FightSeriesAdjustPlugin.cpp" />
|
||||
<ClCompile Include="Task\Fight\FightTimesTaskPlugin.cpp" />
|
||||
<ClCompile Include="Task\Fight\MedicineCounterTaskPlugin.cpp" />
|
||||
<ClCompile Include="Task\Fight\SanityBeforeStageTaskPlugin.cpp" />
|
||||
|
||||
@@ -1328,6 +1328,9 @@
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeInputSeedTaskPlugin.h">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Task\Fight\FightSeriesAdjustPlugin.h">
|
||||
<Filter>Source\Task\Fight</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vision\VisionHelper.cpp">
|
||||
@@ -1842,6 +1845,9 @@
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeInputSeedTaskPlugin.cpp">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Task\Fight\FightSeriesAdjustPlugin.cpp">
|
||||
<Filter>Source\Task\Fight</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="meojson.natvis" />
|
||||
|
||||
103
src/MaaCore/Task/Fight/FightSeriesAdjustPlugin.cpp
Normal file
103
src/MaaCore/Task/Fight/FightSeriesAdjustPlugin.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "FightSeriesAdjustPlugin.h"
|
||||
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/MultiMatcher.h"
|
||||
#include "Vision/RegionOCRer.h"
|
||||
|
||||
bool asst::FightSeriesAdjustPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
if (msg != AsstMsg::SubTaskCompleted || details.get("subtask", std::string()) != "ProcessTask") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return details.get("details", "task", "").ends_with("CloseStonePage");
|
||||
}
|
||||
|
||||
bool asst::FightSeriesAdjustPlugin::_run()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
auto task = ProcessTask(*this, { "FightSeries-Open" });
|
||||
task.run();
|
||||
|
||||
int exceeded_num = get_exceeded_num();
|
||||
if (exceeded_num <= 6 && exceeded_num > 1) {
|
||||
ProcessTask(*this, { "FightSeries-List-" + std::to_string(exceeded_num - 1) }).run();
|
||||
set_close_stone_page_next(true);
|
||||
}
|
||||
else {
|
||||
set_close_stone_page_next(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int asst::FightSeriesAdjustPlugin::get_exceeded_num() const
|
||||
{
|
||||
const std::vector<std::pair<int, int>> list_y_ranges = {
|
||||
{ 505, 505 + 55 }, // List-1: [505, 560)
|
||||
{ 445, 445 + 55 }, // List-2: [445, 500)
|
||||
{ 383, 383 + 55 }, // List-3: [383, 438)
|
||||
{ 320, 320 + 55 }, // List-4: [320, 375)
|
||||
{ 260, 260 + 55 }, // List-5: [260, 315)
|
||||
{ 200, 200 + 50 } // List-6: [200, 250)
|
||||
};
|
||||
|
||||
auto img = ctrler()->get_image();
|
||||
if (img.empty()) {
|
||||
return 0;
|
||||
}
|
||||
MultiMatcher multi_matcher(img);
|
||||
multi_matcher.set_task_info("FightSeries-List-Exceeded");
|
||||
if (!multi_matcher.analyze()) {
|
||||
Log.info(__FUNCTION__, "Fight series exceeded analyze failed");
|
||||
LogInfo << __FUNCTION__ << "Falling back to OCR for exceeded number detection.";
|
||||
|
||||
std::vector<int> detected_numbers;
|
||||
|
||||
for (const auto& range : list_y_ranges) {
|
||||
RegionOCRer analyzer(img);
|
||||
analyzer.set_task_info("NumberOcrReplace");
|
||||
analyzer.set_bin_threshold(150, 255);
|
||||
analyzer.set_roi({ 980, range.first, 40, range.second - range.first });
|
||||
|
||||
auto result_opt = analyzer.analyze();
|
||||
if (result_opt && !result_opt->text.empty()) {
|
||||
try {
|
||||
int number = std::stoi(result_opt->text);
|
||||
detected_numbers.push_back(number);
|
||||
}
|
||||
catch (const std::invalid_argument&) {
|
||||
LogInfo << __FUNCTION__ << "OCR failed to parse number: " << result_opt->text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!detected_numbers.empty()) {
|
||||
int max_number = *std::max_element(detected_numbers.begin(), detected_numbers.end());
|
||||
LogInfo << __FUNCTION__ << "Detected max number via OCR: " << max_number;
|
||||
return max_number + 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
auto match_result = multi_matcher.get_result();
|
||||
if (match_result.empty()) {
|
||||
LogInfo << __FUNCTION__ << "No matches found for FightSeries-List-Exceeded.";
|
||||
return -1;
|
||||
}
|
||||
sort_by_vertical_(match_result);
|
||||
int exceeded_y_pos = match_result.back().rect.y;
|
||||
for (size_t i = 0; i < list_y_ranges.size(); ++i) {
|
||||
const auto& range = list_y_ranges[i];
|
||||
if (exceeded_y_pos >= range.first && exceeded_y_pos < range.second) {
|
||||
int list_index = static_cast<int>(i + 1); // 列表序号从 1 开始
|
||||
LogInfo << __FUNCTION__ << "Exceeded icon y=" << exceeded_y_pos << " is within List-" << list_index
|
||||
<< " range [" << range.first << ", " << range.second << ").";
|
||||
return list_index;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
32
src/MaaCore/Task/Fight/FightSeriesAdjustPlugin.h
Normal file
32
src/MaaCore/Task/Fight/FightSeriesAdjustPlugin.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Config/TaskData.h"
|
||||
#include "Task/AbstractTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class FightSeriesAdjustPlugin final : public AbstractTaskPlugin
|
||||
{
|
||||
public:
|
||||
using AbstractTaskPlugin::AbstractTaskPlugin;
|
||||
virtual ~FightSeriesAdjustPlugin() override = default;
|
||||
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
void set_close_stone_page_next(bool enable) const
|
||||
{
|
||||
Task.get("Fight@CloseStonePage")->next =
|
||||
enable ? modified_close_stone_page_next : original_close_stone_page_next;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
private:
|
||||
// 临时处理
|
||||
std::vector<std::string> original_close_stone_page_next = { "Fight@StageSNReturnFlag", "Fight@Stop" };
|
||||
std::vector<std::string> modified_close_stone_page_next = { "Fight@StartButton1",
|
||||
"Fight@StageSNReturnFlag",
|
||||
"Fight@Stop" };
|
||||
int get_exceeded_num() const;
|
||||
};
|
||||
}
|
||||
@@ -38,3 +38,4 @@ bool asst::FightTimesTaskPlugin::_run()
|
||||
inited = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "Config/TaskData.h"
|
||||
#include "Task/Fight/DrGrandetTaskPlugin.h"
|
||||
#include "Task/Fight/FightSeriesAdjustPlugin.h"
|
||||
#include "Task/Fight/FightTimesTaskPlugin.h"
|
||||
#include "Task/Fight/MedicineCounterTaskPlugin.h"
|
||||
#include "Task/Fight/SanityBeforeStageTaskPlugin.h"
|
||||
@@ -54,6 +55,8 @@ asst::FightTask::FightTask(const AsstCallback& callback, Assistant* inst) :
|
||||
m_fight_times_task_plugin_prt = m_fight_task_ptr->register_plugin<FightTimesTaskPlugin>();
|
||||
m_fight_times_task_plugin_prt->set_retry_times(3);
|
||||
m_medicine_plugin = m_fight_task_ptr->register_plugin<MedicineCounterTaskPlugin>();
|
||||
m_fight_series_adjust_plugin_ptr = m_fight_task_ptr->register_plugin<FightSeriesAdjustPlugin>();
|
||||
m_fight_series_adjust_plugin_ptr->set_retry_times(3);
|
||||
|
||||
m_subtasks.emplace_back(m_start_up_task_ptr);
|
||||
m_subtasks.emplace_back(m_stage_navigation_task_ptr);
|
||||
@@ -70,11 +73,23 @@ bool asst::FightTask::set_params(const json::value& params)
|
||||
const int expiring_medicine = params.get("expiring_medicine", 0);
|
||||
const int stone = params.get("stone", 0);
|
||||
const int times = params.get("times", INT_MAX);
|
||||
const int series = params.get("series", 1);
|
||||
if (series < 1 || series > 6) {
|
||||
int series = params.get("series", 1);
|
||||
|
||||
// 重置插件状态 1000 表示自动连战,-1 表示禁用连战切换
|
||||
m_fight_times_task_plugin_prt->set_enable(series != -1);
|
||||
m_fight_series_adjust_plugin_ptr->set_close_stone_page_next(false);
|
||||
m_fight_series_adjust_plugin_ptr->set_enable(series == 1000);
|
||||
if (series == 1000) {
|
||||
series = 6;
|
||||
}
|
||||
else if (series == -1) {
|
||||
series = 1;
|
||||
}
|
||||
else if (series < 1 || series > 6) {
|
||||
Log.error("Invalid series");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool enable_penguin = params.get("report_to_penguin", false);
|
||||
bool enable_yituliu = params.get("report_to_yituliu", false);
|
||||
std::string penguin_id = params.get("penguin_id", "");
|
||||
|
||||
@@ -12,6 +12,7 @@ class StageNavigationTask;
|
||||
class DrGrandetTaskPlugin;
|
||||
class SideStoryReopenTask;
|
||||
class MedicineCounterTaskPlugin;
|
||||
class FightSeriesAdjustPlugin;
|
||||
|
||||
class FightTask final : public InterfaceTask
|
||||
{
|
||||
@@ -28,6 +29,7 @@ protected:
|
||||
std::shared_ptr<StageNavigationTask> m_stage_navigation_task_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_fight_task_ptr = nullptr;
|
||||
std::shared_ptr<FightTimesTaskPlugin> m_fight_times_task_plugin_prt = nullptr;
|
||||
std::shared_ptr<FightSeriesAdjustPlugin> m_fight_series_adjust_plugin_ptr = nullptr;
|
||||
std::shared_ptr<MedicineCounterTaskPlugin> m_medicine_plugin = nullptr;
|
||||
std::shared_ptr<StageDropsTaskPlugin> m_stage_drops_plugin_ptr = nullptr;
|
||||
std::shared_ptr<DrGrandetTaskPlugin> m_dr_grandet_task_plugin_ptr = nullptr;
|
||||
|
||||
@@ -103,10 +103,17 @@ public class FightSettingsUserControlModel : TaskViewModel
|
||||
{ "炭", "SK-5" },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or private sets the list of series.
|
||||
/// </summary>
|
||||
public List<int> SeriesList { get; private set; } = Enumerable.Range(1, 6).ToList();
|
||||
public Dictionary<string, int> SeriesList { get; } = new()
|
||||
{
|
||||
{ "AUTO", 1000 },
|
||||
{ "6", 6 },
|
||||
{ "5", 5 },
|
||||
{ "4", 4 },
|
||||
{ "3", 6 },
|
||||
{ "2", 2 },
|
||||
{ "1", 1 },
|
||||
{ LocalizationHelper.GetString("NotSelected"), -1 },
|
||||
};
|
||||
|
||||
public string?[] Stages => [Stage1, Stage2, Stage3];
|
||||
|
||||
@@ -465,7 +472,7 @@ public class FightSettingsUserControlModel : TaskViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private int _series = ConfigurationHelper.GetValue(ConfigurationKeys.SeriesQuantity, 1);
|
||||
private int _series = ConfigurationHelper.GetValue(ConfigurationKeys.SeriesQuantity, 1000);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the max number of times.
|
||||
|
||||
@@ -170,7 +170,9 @@
|
||||
IsHitTestVisible="{c:Binding !FightTaskRunning,
|
||||
Source={x:Static helper:Instances.TaskQueueViewModel}}"
|
||||
ItemsSource="{Binding SeriesList}"
|
||||
SelectedValue="{Binding Series}" />
|
||||
SelectedValue="{Binding Series}"
|
||||
DisplayMemberPath="Key"
|
||||
SelectedValuePath="Value" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid Grid.Row="3">
|
||||
|
||||
Reference in New Issue
Block a user