feat: 肉鸽模式支持设置开始次数、投资次数、投满停止

This commit is contained in:
MistEO
2022-07-23 01:05:18 +08:00
parent dedd186a0f
commit 8cbd7f2c79
14 changed files with 215 additions and 55 deletions

View File

@@ -159,10 +159,16 @@ Appends a task.
```jsonc
{
"enable": bool, // Whether to enable this task, optional, by default true
"mode": int // Mode, optional, by default 0
// 0 - Plays as much as you can
// 1 - Exits after first level
// 2 - Plays until trading
"mode": int, // Mode, optional, by default 0
// 0 - For candle, plays as much as you can with stable strategy
// 1 - For Originium Ingots, exits after first level
// 2 - For both, Plays until invests
// 3 - For pass, plays as much as you can with aggressive strategy
"starts_count": int, // Number of starts, optional, by default INT_MAX
"investments_count": int,
// Number of investments, optional, by default INT_MAX
"stop_when_investment_full": bool
// Stop the task when investment is full, optional, by default false
}
```

View File

@@ -159,10 +159,16 @@ TaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const char* p
```jsonc
{
"enable": bool, // 是否启用本任务,可选,默认为 true
"mode": int // 模式,可选项。默认 0
// 0 - 尽可能一直往后打
// 1 - 第一层投资完源石锭就退出
// 2 - 投资过后再退出,没有投资就继续往后打
"mode": int, // 模式,可选项。默认 0
// 0 - 刷蜡烛,尽可能稳定的打更多层数
// 1 - 刷源石锭,第一层投资完就退出
// 2 - 【即将弃用】两者兼顾,投资过后再退出,没有投资就继续往后打
// 3 - 【开发中】尝试通关,尽可能打的远
"starts_count": int, // 开始探索 次数,可选,默认 INT_MAX。达到后自动停止任务
"investments_count": int,
// 投资源石锭 次数,可选,默认 INT_MAX。达到后自动停止任务
"stop_when_investment_full": bool
// 投资满了自动停止任务,可选,默认 false
}
```

View File

@@ -34,6 +34,7 @@
<ClInclude Include="DepotRecognitionTask.h" />
<ClInclude Include="DepotTask.h" />
<ClInclude Include="GameCrashRestartTaskPlugin.h" />
<ClInclude Include="RoguelikeControlTaskPlugin.h" />
<ClInclude Include="RoguelikeRecruitConfiger.h" />
<ClInclude Include="CopilotTask.h" />
<ClInclude Include="DebugTask.h" />
@@ -118,6 +119,7 @@
<ClCompile Include="DepotRecognitionTask.cpp" />
<ClCompile Include="DepotTask.cpp" />
<ClCompile Include="GameCrashRestartTaskPlugin.cpp" />
<ClCompile Include="RoguelikeControlTaskPlugin.cpp" />
<ClCompile Include="RoguelikeRecruitConfiger.cpp" />
<ClCompile Include="CopilotTask.cpp" />
<ClCompile Include="DebugTask.cpp" />

View File

@@ -76,6 +76,12 @@
<Filter Include="源文件\ImageAnalyzer\Final\Infrast">
<UniqueIdentifier>{a37e0b23-e8f8-499c-adf5-9990277e9ffe}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Task\Plugin\Roguelike">
<UniqueIdentifier>{82f533ab-3647-46ea-b9e1-0af634b3545c}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\Task\Plugin\Roguelike">
<UniqueIdentifier>{67b117db-cce6-459f-bd26-bf897c02fbd7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Controller.h">
@@ -207,12 +213,6 @@
<ClInclude Include="HashImageAnalyzer.h">
<Filter>头文件\ImageAnalyzer\General</Filter>
</ClInclude>
<ClInclude Include="RoguelikeBattleTaskPlugin.h">
<Filter>头文件\Task\Plugin</Filter>
</ClInclude>
<ClInclude Include="RoguelikeFormationTaskPlugin.h">
<Filter>头文件\Task\Plugin</Filter>
</ClInclude>
<ClInclude Include="TilePack.h">
<Filter>头文件\Resource</Filter>
</ClInclude>
@@ -276,12 +276,6 @@
<ClInclude Include="RoguelikeTask.h">
<Filter>头文件\Task</Filter>
</ClInclude>
<ClInclude Include="RoguelikeRecruitTaskPlugin.h">
<Filter>头文件\Task\Plugin</Filter>
</ClInclude>
<ClInclude Include="RoguelikeSkillSelectionTaskPlugin.h">
<Filter>头文件\Task\Plugin</Filter>
</ClInclude>
<ClInclude Include="DebugTask.h">
<Filter>头文件\Task\Plugin</Filter>
</ClInclude>
@@ -345,6 +339,21 @@
<ClInclude Include="StopGameTaskPlugin.h">
<Filter>头文件\Task\Plugin</Filter>
</ClInclude>
<ClInclude Include="RoguelikeBattleTaskPlugin.h">
<Filter>头文件\Task\Plugin\Roguelike</Filter>
</ClInclude>
<ClInclude Include="RoguelikeFormationTaskPlugin.h">
<Filter>头文件\Task\Plugin\Roguelike</Filter>
</ClInclude>
<ClInclude Include="RoguelikeRecruitTaskPlugin.h">
<Filter>头文件\Task\Plugin\Roguelike</Filter>
</ClInclude>
<ClInclude Include="RoguelikeSkillSelectionTaskPlugin.h">
<Filter>头文件\Task\Plugin\Roguelike</Filter>
</ClInclude>
<ClInclude Include="RoguelikeControlTaskPlugin.h">
<Filter>头文件\Task\Plugin\Roguelike</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Controller.cpp">
@@ -458,12 +467,6 @@
<ClCompile Include="HashImageAnalyzer.cpp">
<Filter>源文件\ImageAnalyzer\General</Filter>
</ClCompile>
<ClCompile Include="RoguelikeBattleTaskPlugin.cpp">
<Filter>源文件\Task\Plugin</Filter>
</ClCompile>
<ClCompile Include="RoguelikeFormationTaskPlugin.cpp">
<Filter>源文件\Task\Plugin</Filter>
</ClCompile>
<ClCompile Include="TilePack.cpp">
<Filter>源文件\Resource</Filter>
</ClCompile>
@@ -524,12 +527,6 @@
<ClCompile Include="RoguelikeTask.cpp">
<Filter>源文件\Task</Filter>
</ClCompile>
<ClCompile Include="RoguelikeRecruitTaskPlugin.cpp">
<Filter>源文件\Task\Plugin</Filter>
</ClCompile>
<ClCompile Include="RoguelikeSkillSelectionTaskPlugin.cpp">
<Filter>源文件\Task\Plugin</Filter>
</ClCompile>
<ClCompile Include="DebugTask.cpp">
<Filter>源文件\Task</Filter>
</ClCompile>
@@ -596,6 +593,21 @@
<ClCompile Include="StopGameTaskPlugin.cpp">
<Filter>源文件\Task\Plugin</Filter>
</ClCompile>
<ClCompile Include="RoguelikeBattleTaskPlugin.cpp">
<Filter>源文件\Task\Plugin\Roguelike</Filter>
</ClCompile>
<ClCompile Include="RoguelikeFormationTaskPlugin.cpp">
<Filter>源文件\Task\Plugin\Roguelike</Filter>
</ClCompile>
<ClCompile Include="RoguelikeRecruitTaskPlugin.cpp">
<Filter>源文件\Task\Plugin\Roguelike</Filter>
</ClCompile>
<ClCompile Include="RoguelikeSkillSelectionTaskPlugin.cpp">
<Filter>源文件\Task\Plugin\Roguelike</Filter>
</ClCompile>
<ClCompile Include="RoguelikeControlTaskPlugin.cpp">
<Filter>源文件\Task\Plugin\Roguelike</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\resource\config.json">

View File

@@ -141,12 +141,14 @@ bool ProcessTask::_run()
}
if (exec_times >= max_times) {
info["what"] = "ExceededLimit";
info["details"] = json::object{
{ "task", cur_name },
{ "exec_times", exec_times },
{ "max_times", max_times }
};
Log.info("exec times exceeded the limit", info.to_string());
callback(AsstMsg::SubTaskExtraInfo, info);
m_cur_tasks_name = m_cur_task_ptr->exceeded_next;
sleep(m_task_delay);
continue;
@@ -260,6 +262,13 @@ bool asst::ProcessTask::on_run_fails()
return run();
}
json::value asst::ProcessTask::basic_info() const
{
return AbstractTask::basic_info() | json::object{
{ "first", json::array(m_raw_tasks_name) }
};
}
void ProcessTask::exec_click_task(const Rect& matched_rect)
{
m_ctrler->click(matched_rect);

View File

@@ -25,6 +25,7 @@ namespace asst
protected:
virtual bool _run() override;
virtual bool on_run_fails() override;
virtual json::value basic_info() const override;
void exec_click_task(const Rect& matched_rect);
void exec_swipe_task(ProcessTaskAction action);

View File

@@ -310,7 +310,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle()
Point placed_point = m_side_tile_info.at(placed_loc).pos;
Rect placed_rect(placed_point.x, placed_point.y, 1, 1);
int dist = static_cast<int>(Point::distance(
placed_point, {opt_oper.rect.x + opt_oper.rect.width / 2, opt_oper.rect.y + opt_oper.rect.height / 2}));
placed_point, { opt_oper.rect.x + opt_oper.rect.width / 2, opt_oper.rect.y + opt_oper.rect.height / 2 }));
// 1000 是随便取的一个系数,把整数的 pre_delay 转成小数用的
int duration = static_cast<int>(swipe_oper_task_ptr->pre_delay / 800.0 * dist * log10(dist));
m_ctrler->swipe(opt_oper.rect, placed_rect, duration, true, 0);
@@ -708,7 +708,7 @@ std::pair<asst::Point, int> asst::RoguelikeBattleTaskPlugin::calc_best_direction
int max_score = 0;
Point opt_direction;
for (const Point& direction : {Point::right(), Point::up(), Point::left(), Point::down()}) {
for (const Point& direction : { Point::right(), Point::up(), Point::left(), Point::down() }) {
int score = 0;
for (const Point& relative_pos : right_attack_range) {
Point absolute_pos = loc + relative_pos;
@@ -746,16 +746,16 @@ std::pair<asst::Point, int> asst::RoguelikeBattleTaskPlugin::calc_best_direction
};
switch (role) {
case BattleRole::Medic:
if (m_used_tiles.find(absolute_pos) != m_used_tiles.end()) // 根据哪个方向上人多决定朝向哪
score += 10000;
if (auto iter = m_side_tile_info.find(absolute_pos); iter != m_side_tile_info.end())
score += TileKeyMedicWeights.at(iter->second.key);
break;
default:
if (auto iter = m_side_tile_info.find(absolute_pos); iter != m_side_tile_info.end())
score += TileKeyFightWeights.at(iter->second.key);
break;
case BattleRole::Medic:
if (m_used_tiles.find(absolute_pos) != m_used_tiles.end()) // 根据哪个方向上人多决定朝向哪
score += 10000;
if (auto iter = m_side_tile_info.find(absolute_pos); iter != m_side_tile_info.end())
score += TileKeyMedicWeights.at(iter->second.key);
break;
default:
if (auto iter = m_side_tile_info.find(absolute_pos); iter != m_side_tile_info.end())
score += TileKeyFightWeights.at(iter->second.key);
break;
}
}
@@ -769,7 +769,7 @@ std::pair<asst::Point, int> asst::RoguelikeBattleTaskPlugin::calc_best_direction
// rotate relative attack range counterclockwise
for (Point& point : right_attack_range)
point = {point.y, -point.x};
point = { point.y, -point.x };
}
return std::make_pair(opt_direction, max_score);

View File

@@ -0,0 +1,28 @@
#include "RoguelikeControlTaskPlugin.h"
bool asst::RoguelikeControlTaskPlugin::verify(AsstMsg msg, const json::value& details) const
{
if (msg != AsstMsg::SubTaskExtraInfo
|| details.get("subtask", std::string()) != "ProcessTask") {
return false;
}
const std::string what = details.get("what", std::string());
if (what != "ExceededLimit") {
return false;
}
const std::string task = details.at("details").at("task").as_string();
if (task == "Roguelike1Start" ||
task == "Roguelike1StageTraderInvestConfirm" ||
task == "Roguelike1StageTraderInvestSystemFull") {
return true;
}
return false;
}
bool asst::RoguelikeControlTaskPlugin::_run()
{
m_task_ptr->set_enable(false);
return true;
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "AbstractTaskPlugin.h"
namespace asst
{
class RoguelikeControlTaskPlugin : public AbstractTaskPlugin
{
public:
using AbstractTaskPlugin::AbstractTaskPlugin;
virtual ~RoguelikeControlTaskPlugin() = default;
public:
virtual bool verify(AsstMsg msg, const json::value& details) const override;
protected:
virtual bool _run() override;
};
}

View File

@@ -6,6 +6,7 @@
#include "RoguelikeRecruitTaskPlugin.h"
#include "RoguelikeSkillSelectionTaskPlugin.h"
#include "RoguelikeBattleTaskPlugin.h"
#include "RoguelikeControlTaskPlugin.h"
#include "Logger.hpp"
@@ -17,6 +18,7 @@ asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, void* callback_
.set_retry_times(50);
m_roguelike_task_ptr->regiseter_plugin<RoguelikeFormationTaskPlugin>();
m_roguelike_task_ptr->regiseter_plugin<RoguelikeControlTaskPlugin>();
m_battle_task_ptr = m_roguelike_task_ptr->regiseter_plugin<RoguelikeBattleTaskPlugin>();
@@ -27,16 +29,17 @@ asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, void* callback_
m_skill_task_ptr->set_retry_times(3);
// 这个任务如果卡住会放弃当前的肉鸽并重新开始,所以多添加一点。先这样凑合用
for (int i = 0; i != 10000; ++i) {
for (int i = 0; i != 100; ++i) {
m_subtasks.emplace_back(m_roguelike_task_ptr);
}
}
bool asst::RoguelikeTask::set_params(const json::value& params)
{
// 0 - 尽可能一直往后打
// 1 - 第一层投资完源石锭就退出
// 2 - 投资过后再退出,没有投资就继续往后打
// 0 - 刷蜡烛,尽可能稳定的打更多层数
// 1 - 刷源石锭,第一层投资完就退出
// 2 - 【弃用】两者兼顾,投资过后再退出,没有投资就继续往后打
// 3 - 尝试通关,激进策略
int mode = params.get("mode", 0);
switch (mode) {
@@ -53,5 +56,18 @@ bool asst::RoguelikeTask::set_params(const json::value& params)
return false;
}
int number_of_starts = params.get("starts_count", INT_MAX);
m_roguelike_task_ptr->set_times_limit("Roguelike1Start", number_of_starts);
int number_of_investments = params.get("investments_count", INT_MAX);
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestConfirm", 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);
constexpr int InvestLimit = 999;
m_roguelike_task_ptr->set_times_limit("Roguelike1StageTraderInvestConfirm", InvestLimit);
}
return true;
}

View File

@@ -985,10 +985,13 @@ namespace MeoAsstGui
return id != 0;
}
public bool AsstAppendRoguelike(int mode)
public bool AsstAppendRoguelike(int mode, int starts, int invests, bool stop_when_full)
{
var task_params = new JObject();
task_params["mode"] = mode;
task_params["starts_count"] = starts;
task_params["investments_count"] = invests;
task_params["stop_when_investment_full"] = stop_when_full;
TaskId id = AsstAppendTaskWithEncoding("Roguelike", task_params);
_latestTaskId[TaskType.Roguelike] = id;
return id != 0;

View File

@@ -7,14 +7,36 @@
xmlns:dd="urn:gong-wpf-dragdrop"
mc:Ignorable="d"
xmlns:vm="clr-namespace:MeoAsstGui;assembly=MeoAsstGui"
xmlns:hc="https://handyorg.github.io/handycontrol"
d:DataContext="{d:DesignInstance {x:Type vm:SettingsViewModel}}"
d:DesignHeight="300" d:DesignWidth="550">
<Grid>
<ComboBox Width="300" Margin="10"
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Style="{StaticResource TextBlockDefault}" Text="策略" VerticalAlignment="Center" Margin="10" />
<ComboBox Width="300" Margin="10"
IsHitTestVisible ="{Binding Path=Idle}"
ItemsSource="{Binding RoguelikeModeList}"
DisplayMemberPath="Display"
SelectedValuePath="Value"
SelectedValue="{Binding RoguelikeMode}" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Style="{StaticResource TextBlockDefault}" Text="开始次数限制" VerticalAlignment="Center" Margin="10" />
<hc:TextBox Text="{Binding RoguelikeStartsCount}" TextWrapping="Wrap" Margin="10"
Width="80" InputMethod.IsInputMethodEnabled="False" TextType="Int" />
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Style="{StaticResource TextBlockDefault}" Text="投资次数限制" VerticalAlignment="Center" Margin="10" />
<hc:TextBox Text="{Binding RoguelikeInvestsCount}" TextWrapping="Wrap" Margin="10"
Width="80" InputMethod.IsInputMethodEnabled="False" TextType="Int" />
</StackPanel>
<CheckBox Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center"
IsChecked="{Binding RoguelikeStopWhenInvestmentFull}" Content="源石锭达到上限停止任务" Margin="10" />
</Grid>
</UserControl>

View File

@@ -135,9 +135,10 @@ namespace MeoAsstGui
RoguelikeModeList = new List<CombData>
{
new CombData { Display = "尽可能往后打", Value = "0" },
new CombData { Display = "刷源石锭投资,第一层商店后直接退出", Value = "1" },
new CombData { Display = "刷源石锭投资,投资过后退出", Value = "2" }
new CombData { Display = "刷蜡烛,尽可能稳定的打更多层数", Value = "0" },
new CombData { Display = "刷源石锭,第一层商店后直接退出", Value = "1" },
//new CombData { Display = "两者兼顾,投资过后退出", Value = "2" } // 弃用
//new CombData { Display = "尝试通关贪B策略", Value = "3" }, // 开发中
};
ClientTypeList = new List<CombData>
@@ -493,6 +494,42 @@ namespace MeoAsstGui
}
}
private string _roguelikeStartsCount = ViewStatusStorage.Get("Roguelike.StartsCount", "9999999");
public int RoguelikeStartsCount
{
get { return int.Parse(_roguelikeStartsCount); }
set
{
SetAndNotify(ref _roguelikeStartsCount, value.ToString());
ViewStatusStorage.Set("Roguelike.StartsCount", value.ToString());
}
}
private string _roguelikeInvestsCount = ViewStatusStorage.Get("Roguelike.InvestsCount", "9999999");
public int RoguelikeInvestsCount
{
get { return int.Parse(_roguelikeInvestsCount); }
set
{
SetAndNotify(ref _roguelikeInvestsCount, value.ToString());
ViewStatusStorage.Set("Roguelike.InvestsCount", value.ToString());
}
}
private string _roguelikeStopWhenInvestmentFull = ViewStatusStorage.Get("Roguelike.StopWhenInvestmentFull", false.ToString());
public bool RoguelikeStopWhenInvestmentFull
{
get { return bool.Parse(_roguelikeStopWhenInvestmentFull); }
set
{
SetAndNotify(ref _roguelikeStopWhenInvestmentFull, value.ToString());
ViewStatusStorage.Set("Roguelike.StopWhenInvestmentFull", value.ToString());
}
}
/* 信用商店设置 */
private bool _creditShopping = Convert.ToBoolean(ViewStatusStorage.Get("Mall.CreditShopping", bool.TrueString));

View File

@@ -796,7 +796,7 @@ namespace MeoAsstGui
int.TryParse(settings.RoguelikeMode, out mode);
var asstProxy = _container.Get<AsstProxy>();
return asstProxy.AsstAppendRoguelike(mode);
return asstProxy.AsstAppendRoguelike(mode, settings.RoguelikeStartsCount, settings.RoguelikeInvestsCount, settings.RoguelikeStopWhenInvestmentFull);
}
public bool killemulator()