mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-16 09:50:40 +08:00
refator: 完成肉鸽战斗任务整体重构(还没测)
This commit is contained in:
@@ -9112,7 +9112,7 @@
|
||||
204
|
||||
]
|
||||
},
|
||||
"RoguelikeWaitBattleStart": {
|
||||
"RoguelikeWaitForStartButtonClicked": {
|
||||
"Doc": "点了开始行动之后,可能会网络不好一直loading,用这个任务等一会",
|
||||
"template": "Roguelike@QuickFormation.png",
|
||||
"action": "DoNothing",
|
||||
@@ -9123,7 +9123,7 @@
|
||||
146
|
||||
],
|
||||
"next": [
|
||||
"RoguelikeWaitBattleStart"
|
||||
"RoguelikeWaitForStartButtonClicked"
|
||||
]
|
||||
},
|
||||
"RoguelikeRecruitSupportOcr": {
|
||||
|
||||
@@ -96,14 +96,14 @@ namespace asst::battle
|
||||
|
||||
struct DeploymentOper
|
||||
{
|
||||
int cost = 0;
|
||||
size_t index = 0;
|
||||
Role role = Role::Unknown;
|
||||
int cost = 0;
|
||||
bool available = false;
|
||||
bool cooling = false;
|
||||
Rect rect;
|
||||
cv::Mat avatar;
|
||||
std::string name;
|
||||
size_t index = 0;
|
||||
bool cooling = false;
|
||||
};
|
||||
|
||||
enum class OperPosition
|
||||
@@ -197,7 +197,6 @@ namespace asst::battle
|
||||
std::vector<ReplacementHome> replacement_home;
|
||||
std::unordered_set<Point> blacklist_location;
|
||||
std::unordered_map<Point, ForceDeployDirection> force_deploy_direction;
|
||||
std::vector<int> key_kills;
|
||||
std::array<Role, 9> role_order = {};
|
||||
bool use_dice_stage = true;
|
||||
int stop_deploy_blocking_num = INT_MAX;
|
||||
|
||||
@@ -57,11 +57,6 @@ bool asst::RoguelikeCopilotConfig::parse(const json::value& json)
|
||||
data.blacklist_location.emplace(point[0].as_integer(), point[1].as_integer());
|
||||
}
|
||||
}
|
||||
if (auto opt = stage_info.find<json::array>("key_kills")) {
|
||||
for (const auto& key_kill : opt.value()) {
|
||||
data.key_kills.emplace_back(static_cast<int>(key_kill));
|
||||
}
|
||||
}
|
||||
data.use_dice_stage = !stage_info.get("not_use_dice", false);
|
||||
|
||||
if (auto opt = stage_info.find<json::value>("force_air_defense_when_deploy_blocking_num")) {
|
||||
|
||||
@@ -42,3 +42,8 @@ bool asst::InstHelper::sleep(unsigned millisecond) const
|
||||
|
||||
return !need_exit();
|
||||
}
|
||||
|
||||
asst::Assistant* asst::InstHelper::inst() noexcept
|
||||
{
|
||||
return m_inst;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace asst
|
||||
std::shared_ptr<Status> status() const;
|
||||
bool need_exit() const;
|
||||
bool sleep(unsigned millisecond) const;
|
||||
Assistant* inst() noexcept;
|
||||
|
||||
InstHelper& operator=(const InstHelper&) = default;
|
||||
InstHelper& operator=(InstHelper&&) noexcept = default;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace asst
|
||||
AbstractTask(const AbstractTask&) = default;
|
||||
AbstractTask(AbstractTask&&) noexcept = default;
|
||||
virtual ~AbstractTask() noexcept = default;
|
||||
using InstHelper::inst;
|
||||
|
||||
virtual bool run();
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ namespace asst
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const = 0;
|
||||
|
||||
std::strong_ordering operator<=>(const AbstractTaskPlugin& rhs) const;
|
||||
|
||||
bool operator==(const AbstractTaskPlugin& rhs) const;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -34,18 +34,12 @@ bool asst::BattleHelper::calc_tiles_info(const std::string& stage_name)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
auto normal_temp = Tile.calc(stage_name, false);
|
||||
if (normal_temp.empty()) {
|
||||
if (!Tile.contains(stage_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto side_temp = Tile.calc(stage_name, true);
|
||||
if (side_temp.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_normal_tile_info = std::move(normal_temp);
|
||||
m_side_tile_info = std::move(side_temp);
|
||||
m_normal_tile_info = Tile.calc(stage_name, false);
|
||||
m_side_tile_info = Tile.calc(stage_name, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -54,17 +48,17 @@ bool asst::BattleHelper::pause()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
return ProcessTask(*dynamic_cast<AbstractTask*>(this), { "BattlePause" }).run();
|
||||
return ProcessTask(this_task(), { "BattlePause" }).run();
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::speed_up()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
return ProcessTask(*dynamic_cast<AbstractTask*>(this), { "BattleSpeedUp" }).run();
|
||||
return ProcessTask(this_task(), { "BattleSpeedUp" }).run();
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::analyze_deployment_opers(bool init)
|
||||
bool asst::BattleHelper::update_deployment(bool init)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
@@ -433,19 +427,29 @@ bool asst::BattleHelper::click_retreat()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
return ProcessTask(*dynamic_cast<AbstractTask*>(this), { "BattleOperRetreatJustClick" }).run();
|
||||
return ProcessTask(this_task(), { "BattleOperRetreatJustClick" }).run();
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::click_skill()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
return ProcessTask(*dynamic_cast<AbstractTask*>(this), { "BattleSkillReadyOnClick", "BattleSkillStopOnClick" })
|
||||
return ProcessTask(this_task(), { "BattleSkillReadyOnClick", "BattleSkillStopOnClick" })
|
||||
.set_task_delay(0)
|
||||
.set_retry_times(1000)
|
||||
.run();
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::cancel_oper_selection()
|
||||
{
|
||||
return ProcessTask(this_task(), { "BattleCancelSelection" }).run();
|
||||
}
|
||||
|
||||
bool asst::BattleHelper::is_name_invaild(const std::string& name)
|
||||
{
|
||||
return BattleData.get_location_type(name) == battle::LocationType::Invalid;
|
||||
}
|
||||
|
||||
std::optional<asst::Rect> asst::BattleHelper::get_oper_rect_on_deployment(const std::string& name) const
|
||||
{
|
||||
LogTraceFunction;
|
||||
@@ -458,3 +462,8 @@ std::optional<asst::Rect> asst::BattleHelper::get_oper_rect_on_deployment(const
|
||||
|
||||
return oper_iter->second.rect;
|
||||
}
|
||||
|
||||
asst::AbstractTask& asst::BattleHelper::this_task()
|
||||
{
|
||||
return *dynamic_cast<AbstractTask*>(this);
|
||||
}
|
||||
|
||||
@@ -20,12 +20,13 @@ namespace asst
|
||||
BattleHelper(Assistant* inst);
|
||||
|
||||
virtual bool set_stage_name(const std::string& name);
|
||||
|
||||
bool calc_tiles_info(const std::string& stage_name);
|
||||
|
||||
bool pause();
|
||||
bool speed_up();
|
||||
|
||||
bool analyze_deployment_opers(bool init = false);
|
||||
bool update_deployment(bool init = false);
|
||||
|
||||
bool deploy_oper(const std::string& name, const Point& loc, battle::DeployDirection direction);
|
||||
bool retreat_oper(const std::string& name);
|
||||
@@ -46,10 +47,12 @@ namespace asst
|
||||
bool click_oper_on_battlefiled(const Point& loc);
|
||||
bool click_retreat(); // 这个是不带识别的,直接点
|
||||
bool click_skill(); // 这个是带识别的,转好了才点
|
||||
bool cancel_oper_selection();
|
||||
|
||||
bool is_name_invaild(const std::string& name);
|
||||
|
||||
std::optional<Rect> get_oper_rect_on_deployment(const std::string& name) const;
|
||||
|
||||
InstHelper m_inst_helper;
|
||||
std::string m_stage_name;
|
||||
std::unordered_map<Point, TilePack::TileInfo> m_side_tile_info;
|
||||
std::unordered_map<Point, TilePack::TileInfo> m_normal_tile_info;
|
||||
@@ -64,5 +67,10 @@ namespace asst
|
||||
|
||||
std::map<std::string, battle::BattlefieldOper> m_battlefield_opers;
|
||||
std::map<Point, battle::BattlefieldOper> m_used_tiles;
|
||||
|
||||
private:
|
||||
virtual AbstractTask& this_task();
|
||||
|
||||
InstHelper m_inst_helper;
|
||||
};
|
||||
}
|
||||
} // namespace asst
|
||||
|
||||
@@ -27,6 +27,7 @@ asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, Assistant* inst
|
||||
|
||||
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>();
|
||||
|
||||
@@ -35,7 +35,7 @@ bool asst::BattleProcessTask::_run()
|
||||
return false;
|
||||
}
|
||||
|
||||
analyze_deployment_opers(true);
|
||||
update_deployment(true);
|
||||
|
||||
for (size_t i = 0; i < m_combat_data.actions.size() && !need_exit(); ++i) {
|
||||
do_action(i);
|
||||
@@ -71,7 +71,7 @@ bool asst::BattleProcessTask::do_action(size_t action_index)
|
||||
if (action.pre_delay > 0) {
|
||||
sleep_with_use_ready_skill(action.pre_delay);
|
||||
// 等待之后画面可能会变化,更新下干员信息
|
||||
analyze_deployment_opers();
|
||||
update_deployment();
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
@@ -226,7 +226,7 @@ bool asst::BattleProcessTask::wait_condition(const Action& action)
|
||||
if (!m_in_bullet_time && action.type == ActionType::Deploy) {
|
||||
const std::string& name = m_oper_in_group[action.group_name];
|
||||
while (!need_exit()) {
|
||||
analyze_deployment_opers();
|
||||
update_deployment();
|
||||
if (auto iter = m_cur_deployment_opers.find(name);
|
||||
iter != m_cur_deployment_opers.cend() && iter->second.available) {
|
||||
break;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class BattleProcessTask : public AbstractTask, public BattleHelper
|
||||
class BattleProcessTask : public AbstractTask, private BattleHelper
|
||||
{
|
||||
public:
|
||||
BattleProcessTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class RoguelikeBattleTaskPlugin : public AbstractTaskPlugin, public BattleHelper
|
||||
class RoguelikeBattleTaskPlugin : public AbstractTaskPlugin, private BattleHelper
|
||||
{
|
||||
using Time_Point = std::chrono::time_point<std::chrono::system_clock>;
|
||||
|
||||
@@ -25,57 +25,105 @@ namespace asst
|
||||
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
void set_stage_name(std::string stage);
|
||||
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
// 有些特殊的角色,他的职业并不一定和正常的位置相对应,比如“掠风”是地面辅助
|
||||
// get_role_position 可以仅知道干员职业的情况下,大概猜测一下位置
|
||||
// get_oper_position 可以在已知干员名的时候获得准确的位置
|
||||
battle::LocationType get_role_location_type(const battle::Role& role);
|
||||
battle::LocationType get_oper_location_type(const std::string& name);
|
||||
// get_role_location_type 可以仅知道干员职业的情况下,大概猜测一下位置
|
||||
// get_oper_location_type 可以在已知干员名的时候获得准确的位置
|
||||
battle::LocationType get_role_location_type(const battle::Role& role) const;
|
||||
battle::LocationType get_oper_location_type(const std::string& name) const;
|
||||
|
||||
std::vector<Point> available_locations(battle::Role role);
|
||||
std::vector<Point> available_locations(const std::string& name);
|
||||
std::vector<Point> available_locations(battle::LocationType type);
|
||||
std::vector<Point> available_locations(battle::Role role) const;
|
||||
std::vector<Point> available_locations(const std::string& name) const;
|
||||
std::vector<Point> available_locations(battle::LocationType type) const;
|
||||
|
||||
battle::OperPosition get_role_position(const battle::Role& role);
|
||||
battle::OperPosition get_role_position(const battle::Role& role) const;
|
||||
|
||||
void wait_for_start();
|
||||
bool get_stage_info();
|
||||
bool battle_pause();
|
||||
bool auto_battle();
|
||||
void all_melee_retreat();
|
||||
bool speed_up();
|
||||
bool use_skill(const Rect& rect);
|
||||
bool retreat(const Point& point);
|
||||
bool abandon();
|
||||
bool calc_stage_info();
|
||||
|
||||
void clear();
|
||||
bool try_possible_skill(const cv::Mat& image);
|
||||
bool check_key_kills(const cv::Mat& image);
|
||||
bool wait_start();
|
||||
bool cancel_oper_selection();
|
||||
bool is_oper_name_error(const std::string& name);
|
||||
void all_melee_retreat();
|
||||
bool abandon();
|
||||
|
||||
void set_position_full(const battle::LocationType& loc_type, bool full);
|
||||
void set_position_full(const Point& point, bool full);
|
||||
void set_position_full(const battle::Role& role, bool full);
|
||||
void set_position_full(const std::string& name, bool full);
|
||||
bool get_position_full(const battle::Role& role);
|
||||
|
||||
bool get_position_full(const battle::LocationType& loc_type) const;
|
||||
bool get_position_full(const battle::Role& role) const;
|
||||
bool get_position_full(const std::string& name) const;
|
||||
|
||||
std::optional<size_t> check_urgent(const std::unordered_set<std::string>& pre_cooling,
|
||||
const std::unordered_set<std::string>& cur_cooling,
|
||||
const std::map<std::string, battle::BattlefieldOper>& pre_bf_opers,
|
||||
bool& deploy_dice_now);
|
||||
std::optional<battle::DeploymentOper> calc_best_oper(std::vector<std::string>& cur_available);
|
||||
|
||||
struct DeployInfo
|
||||
{
|
||||
Point placed;
|
||||
Point direction;
|
||||
battle::DeployDirection direction;
|
||||
};
|
||||
battle::AttackRange get_attack_range(const battle::DeploymentOper& oper);
|
||||
DeployInfo calc_best_plan(const battle::DeploymentOper& oper);
|
||||
std::optional<DeployInfo> calc_best_loc(const battle::DeploymentOper& oper) const;
|
||||
battle::AttackRange get_attack_range(const battle::DeploymentOper& oper,
|
||||
battle::DeployDirection direction = battle::DeployDirection::Right) const;
|
||||
|
||||
// 计算摆放干员的朝向
|
||||
// 返回滑动的方向、得分
|
||||
std::pair<Point, int> calc_best_direction_and_score(Point loc, const battle::DeploymentOper& oper,
|
||||
Point recommended_direction);
|
||||
struct DirectionAndScore
|
||||
{
|
||||
battle::DeployDirection direction;
|
||||
int score = 0;
|
||||
};
|
||||
DirectionAndScore calc_best_direction_and_score(Point loc, const battle::DeploymentOper& oper,
|
||||
battle::DeployDirection recommended_direction) const;
|
||||
|
||||
void postproc_of_deployments(const battle::DeploymentOper& oper, const Point& placed_loc,
|
||||
battle::DeployDirection direction);
|
||||
|
||||
void check_drone_tiles();
|
||||
void wait_for_start_button_clicked();
|
||||
|
||||
/* from config */
|
||||
|
||||
std::vector<battle::roguelike::ReplacementHome> m_homes;
|
||||
bool m_allow_to_use_dice = true;
|
||||
std::unordered_set<Point> m_blacklist_location;
|
||||
std::array<battle::Role, 9> m_role_order {};
|
||||
std::unordered_map<Point, battle::roguelike::ForceDeployDirection> m_force_deploy_direction;
|
||||
|
||||
struct AirDefenseData
|
||||
{
|
||||
/* from config */
|
||||
int stop_blocking_deploy_num = INT_MAX;
|
||||
int deploy_air_defense_num = 0;
|
||||
bool ban_medic = false;
|
||||
/* real time */
|
||||
int has_deployed_blocking_num = 0;
|
||||
int has_deployed_air_defense_num = 0;
|
||||
bool has_finished_deploy_air_defense = false;
|
||||
};
|
||||
AirDefenseData m_force_air_defense;
|
||||
|
||||
/* real time */
|
||||
|
||||
size_t m_cur_home_index = 0;
|
||||
bool m_first_deploy = true;
|
||||
bool m_melee_full = false;
|
||||
bool m_ranged_full = false;
|
||||
|
||||
struct HomeInfo
|
||||
{
|
||||
bool wait_blocking = true;
|
||||
bool wait_medic = true;
|
||||
bool indeed_no_medic = false;
|
||||
Point blocking_pos;
|
||||
};
|
||||
std::vector<HomeInfo> m_homes_status;
|
||||
std::unordered_map<Point, size_t> m_blocking_for_home_index;
|
||||
std::unordered_map<Point, std::vector<size_t>> m_medic_for_home_index;
|
||||
std::deque<size_t> m_urgent_home_index;
|
||||
|
||||
struct DroneTile
|
||||
{
|
||||
@@ -88,61 +136,6 @@ namespace asst
|
||||
}
|
||||
bool operator<(const DroneTile& x) const { return x.placed_time < placed_time; }
|
||||
};
|
||||
|
||||
bool m_opers_used = false;
|
||||
bool m_is_cur_urgent = false;
|
||||
bool m_stage_use_dice = true;
|
||||
bool m_use_dice = false;
|
||||
bool m_first_deploy = true;
|
||||
bool m_melee_full = false;
|
||||
bool m_ranged_full = false;
|
||||
int m_last_not_urgent = -1;
|
||||
int m_pre_hp = 0;
|
||||
int m_kills = 0;
|
||||
int m_total_kills = 0;
|
||||
struct
|
||||
{
|
||||
int stop_blocking_deploy_num = INT_MAX;
|
||||
int has_deployed_blocking_num = 0;
|
||||
int deploy_air_defense_num = 0;
|
||||
int has_deployed_air_defense_num = 0;
|
||||
bool has_finished_deploy_air_defense = false;
|
||||
bool ban_medic = false;
|
||||
|
||||
void clear() noexcept
|
||||
{
|
||||
stop_blocking_deploy_num = INT_MAX;
|
||||
deploy_air_defense_num = 0;
|
||||
has_deployed_blocking_num = 0;
|
||||
has_deployed_air_defense_num = 0;
|
||||
has_finished_deploy_air_defense = false;
|
||||
ban_medic = false;
|
||||
}
|
||||
} m_force_air_defense;
|
||||
|
||||
int m_last_cooling_count = 0;
|
||||
size_t m_cur_home_index = 0;
|
||||
cv::Mat m_dice_image;
|
||||
|
||||
std::array<battle::Role, 9> m_role_order;
|
||||
std::unordered_map<Point, TilePack::TileInfo> m_side_tile_info;
|
||||
std::unordered_map<Point, TilePack::TileInfo> m_normal_tile_info;
|
||||
std::vector<battle::roguelike::ReplacementHome> m_homes;
|
||||
std::vector<bool> m_wait_blocking;
|
||||
std::vector<bool> m_wait_medic;
|
||||
std::vector<bool> m_indeed_no_medic;
|
||||
std::unordered_map<Point, size_t> m_blocking_for_home_index;
|
||||
std::unordered_map<Point, std::vector<size_t>> m_medic_for_home_index;
|
||||
std::stack<size_t> m_next_urgent_index;
|
||||
std::unordered_set<Point> m_blacklist_location;
|
||||
std::set<std::string> m_retreated_opers;
|
||||
std::queue<int> m_key_kills;
|
||||
std::unordered_map<Point, std::string> m_used_tiles;
|
||||
std::unordered_map<std::string, Point> m_opers_in_field;
|
||||
std::unordered_map<std::string, int64_t> m_restore_status;
|
||||
std::priority_queue<DroneTile> m_need_clear_tiles;
|
||||
std::unordered_map<Point, battle::roguelike::ForceDeployDirection> m_force_deploy_direction;
|
||||
|
||||
std::string m_stage_name;
|
||||
};
|
||||
} // namespace asst
|
||||
|
||||
@@ -18,8 +18,6 @@ namespace asst
|
||||
Kills = 16, // 击杀数
|
||||
Cost = 32, // 费用
|
||||
Vacancies = 64, // 剩余可部署干员数
|
||||
// 肉鸽模式需要用到的识别
|
||||
Roguelike = Oper
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user