diff --git a/resource/tasks.json b/resource/tasks.json index 187710aedf..a701bb6fa6 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -3479,7 +3479,7 @@ 100 ], "preDelay": 1000, - "rearDelay": 200 + "rearDelay": 0 }, "Roguelike1Begin": { "algorithm": "justReturn", @@ -3521,7 +3521,21 @@ ] }, "Roguelike1LastReward2": { - "Doc": "你的上一次探索突破了至少两层困难,这一次可以获得更多支援——5源石锭", + "Doc": "你的上一次探索突破了至少两层困难,这一次可以获得更多支援—— 5 源石锭", + "action": "clickSelf", + "cache": false, + "roi": [ + 174, + 151, + 935, + 533 + ], + "next": [ + "Roguelike1LastRewardConfirm" + ] + }, + "Roguelike1LastReward3": { + "Doc": "你的上一次探索突破了至少两层困难,这一次可以获得更多支援—— 3 目标生命", "action": "clickSelf", "cache": false, "roi": [ @@ -3537,6 +3551,7 @@ "Roguelike1LastRewardConfirm": { "template": "Roguelike1RecruitConfirm.png", "action": "clickSelf", + "cache": false, "roi": [ 174, 151, @@ -3570,6 +3585,7 @@ "next": [ "Roguelike1LastReward", "Roguelike1LastReward2", + "Roguelike1LastReward3", "Roguelike1Team3" ] }, @@ -3767,6 +3783,7 @@ "rearDelay": 3000, "next": [ "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -3783,9 +3800,11 @@ 1280, 554 ], + "templThreshold": 0.85, "next": [ "Roguelike1StageTraderEnter", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -3805,6 +3824,41 @@ "Roguelike1StageTraderLeave" ] }, + "Roguelike1StageSafeHouse": { + "Doc": "安全的角落", + "action": "clickSelf", + "cache": false, + "roi": [ + 0, + 53, + 1280, + 554 + ], + "next": [ + "Roguelike1StageSafeHouseEnter", + "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", + "Roguelike1StageEncounter", + "Roguelike1StageBoons", + "Roguelike1StageCambatDps", + "Roguelike1StageEmergencyDps" + ] + }, + "Roguelike1StageSafeHouseEnter": { + "action": "clickSelf", + "roi": [ + 1037, + 374, + 221, + 221 + ], + "next": [ + "Roguelike1StageEncounterFree", + "Roguelike1StageEncounterLeave", + "Roguelike1StageEncounterUnknown", + "Roguelike1StageEncounterClickToLeave" + ] + }, "Roguelike1StageTraderInvestSystem": { "action": "clickSelf", "roi": [ @@ -3891,6 +3945,7 @@ ], "next": [ "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -3910,6 +3965,7 @@ "next": [ "Roguelike1StageEncounterEnter", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -3929,6 +3985,7 @@ "next": [ "Roguelike1StageEncounterEnter", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -4067,6 +4124,7 @@ "Roguelike1StageCambatDpsEnter", "Roguelike1StageEmergencyDpsEnter", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -4084,8 +4142,7 @@ ], "next": [ "Roguelike1QuickFormation" - ], - "rearDelay": 2000 + ] }, "Roguelike1StageEmergencyDps": { "Doc": "紧急作战", @@ -4101,6 +4158,7 @@ "Roguelike1StageCambatDpsEnter", "Roguelike1StageEmergencyDpsEnter", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -4130,7 +4188,8 @@ ], "next": [ "Roguelike1FormationConfirm" - ] + ], + "rearDelay": 2000 }, "Roguelike1FormationOper": { "cache": false, @@ -4222,6 +4281,7 @@ "next": [ "Roguelike1DropsFlag", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -4244,6 +4304,7 @@ "Roguelike1GetDropRecruit", "Roguelike1GetDropLeave", "Roguelike1StageTrader", + "Roguelike1StageSafeHouse", "Roguelike1StageEncounter", "Roguelike1StageBoons", "Roguelike1StageCambatDps", @@ -4362,6 +4423,17 @@ "Roguelike1ClickToStartPoint" ] }, + "Roguelike1MissionFailedFlag2": { + "roi": [ + 473, + 0, + 351, + 194 + ], + "next": [ + "Roguelike1ClickToStartPoint" + ] + }, "Roguelike1ClickToStartPoint": { "algorithm": "justReturn", "action": "clickRect", diff --git a/resource/template/Roguelike1LastReward3.png b/resource/template/Roguelike1LastReward3.png new file mode 100644 index 0000000000..522466b886 Binary files /dev/null and b/resource/template/Roguelike1LastReward3.png differ diff --git a/resource/template/Roguelike1MissionFailedFlag2.png b/resource/template/Roguelike1MissionFailedFlag2.png new file mode 100644 index 0000000000..7a3d21106a Binary files /dev/null and b/resource/template/Roguelike1MissionFailedFlag2.png differ diff --git a/resource/template/Roguelike1StageSafeHouse.png b/resource/template/Roguelike1StageSafeHouse.png new file mode 100644 index 0000000000..4c2f29ec86 Binary files /dev/null and b/resource/template/Roguelike1StageSafeHouse.png differ diff --git a/resource/template/Roguelike1StageSafeHouseEnter.png b/resource/template/Roguelike1StageSafeHouseEnter.png new file mode 100644 index 0000000000..7d235f0e77 Binary files /dev/null and b/resource/template/Roguelike1StageSafeHouseEnter.png differ diff --git a/src/MeoAssistant/AsstDef.h b/src/MeoAssistant/AsstDef.h index 777c0f02d0..b5923e5e15 100644 --- a/src/MeoAssistant/AsstDef.h +++ b/src/MeoAssistant/AsstDef.h @@ -31,6 +31,10 @@ namespace asst Point& operator=(const Point&) noexcept = default; Point& operator=(Point&&) noexcept = default; bool operator==(const Point& rhs) const noexcept { return x == rhs.x && y == rhs.y; } + std::string to_string() const + { + return "[ " + std::to_string(x) + ", " + std::to_string(y) + " ]"; + } int x = 0; int y = 0; }; diff --git a/src/MeoAssistant/BattleImageAnalyzer.cpp b/src/MeoAssistant/BattleImageAnalyzer.cpp index 82ce26e0b5..8f244cef4c 100644 --- a/src/MeoAssistant/BattleImageAnalyzer.cpp +++ b/src/MeoAssistant/BattleImageAnalyzer.cpp @@ -10,11 +10,14 @@ bool asst::BattleImageAnalyzer::analyze() { - opers_analyze(); - skill_analyze(); // 生命值和家门,只要识别到了任一个,就可以说明当前是在战斗场景 bool ret = hp_analyze(); ret |= home_analyze(); + + if (ret) { + opers_analyze(); + skill_analyze(); + } return ret; } diff --git a/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp b/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp index b445bfcdee..de6de4d901 100644 --- a/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp +++ b/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp @@ -58,6 +58,7 @@ bool asst::RoguelikeBattleTaskPlugin::get_stage_info() } m_side_tile_info = std::move(side_info); calced = true; + Log.info("stage info getted, tiles_size", m_side_tile_info.size()); break; } if (calced) { @@ -168,7 +169,8 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle() break; } - Point placed_point = get_placed(loc); + Point placed_loc = get_placed(loc); + Point placed_point = m_side_tile_info.at(placed_loc).pos; #ifdef ASST_DEBUG auto image = Ctrler.get_image(); cv::circle(image, cv::Point(placed_point.x, placed_point.y), 10, cv::Scalar(0, 0, 255), -1); @@ -181,26 +183,27 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle() if (m_cur_home_index >= m_homes.size()) { m_cur_home_index = 0; } - Point home_point(WindowWidthDefault / 2, WindowHeightDefault / 2); + Point home_loc(5, 5); if (m_cur_home_index < m_homes.size()) { - home_point = m_homes.at(m_cur_home_index); + home_loc = m_homes.at(m_cur_home_index); } - + Point home_point = m_side_tile_info.at(home_loc).pos; Rect home_rect(home_point.x, home_point.y, 1, 1); - int dx = placed_point.x - home_point.x; - int dy = placed_point.y - home_point.y; - if (std::abs(dx) < std::abs(dy)) { - dx = 0; - } - else { - dy = 0; - } - constexpr int coeff = 100; + int dx = placed_loc.x - home_loc.x; + int dy = placed_loc.y - home_loc.y; + + constexpr int coeff = 500; Point end_point; switch (opt_oper.role) { case Role::Medic: { + if (std::abs(dx) <= std::abs(dy)) { + dx = 0; + } + else { + dy = 0; + } end_point.x = placed_point.x - coeff * dx; end_point.y = placed_point.y - coeff * dy; } @@ -215,6 +218,12 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle() case Role::Drone: default: { + if (std::abs(dx) < std::abs(dy)) { + dx = 0; + } + else { + dy = 0; + } end_point.x = placed_point.x + coeff * dx; end_point.y = placed_point.y + coeff * dy; } @@ -235,7 +244,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle() } Ctrler.swipe(placed_point, end_point, swipe_oper_task_ptr->rear_delay); - m_used_tiles.emplace(placed_point); + m_used_tiles.emplace(placed_loc); m_used_opers = true; ++m_cur_home_index; @@ -281,9 +290,9 @@ void asst::RoguelikeBattleTaskPlugin::clear() asst::Point asst::RoguelikeBattleTaskPlugin::get_placed(Loc buildable_type) { if (m_homes.empty()) { - for (const auto& side : m_side_tile_info) { + for (const auto& [loc, side] : m_side_tile_info) { if (side.key == TilePack::TileKey::Home) { - m_homes.emplace_back(side.pos); + m_homes.emplace_back(loc); } } if (m_homes.empty()) { @@ -297,26 +306,27 @@ asst::Point asst::RoguelikeBattleTaskPlugin::get_placed(Loc buildable_type) Point nearest; int min_dist = INT_MAX; - Point home(WindowWidthDefault / 2, WindowHeightDefault / 2); + Point home(5, 5); // 默认值,一般是地图的中间 if (m_cur_home_index < m_homes.size()) { home = m_homes.at(m_cur_home_index); } - for (const auto& tile : m_side_tile_info) { + for (const auto& [loc, tile] : m_side_tile_info) { if (tile.buildable == buildable_type || tile.buildable == Loc::All) { - if (m_used_tiles.find(tile.pos) != m_used_tiles.cend()) { + if (m_used_tiles.find(loc) != m_used_tiles.cend()) { continue; } - int dx = std::abs(home.x - tile.pos.x); - int dy = std::abs(home.y - tile.pos.y); + int dx = std::abs(home.x - loc.x); + int dy = std::abs(home.y - loc.y); int dist = dx * dx + dy * dy; if (dist < min_dist) { min_dist = dist; - nearest = tile.pos; + nearest = loc; } } } + Log.info(__FUNCTION__, nearest.to_string()); return nearest; } diff --git a/src/MeoAssistant/RoguelikeBattleTaskPlugin.h b/src/MeoAssistant/RoguelikeBattleTaskPlugin.h index 3bc5b4a5de..00fbde743c 100644 --- a/src/MeoAssistant/RoguelikeBattleTaskPlugin.h +++ b/src/MeoAssistant/RoguelikeBattleTaskPlugin.h @@ -25,13 +25,13 @@ namespace asst void clear(); // 通过资源文件离线计算可放置干员的位置,优先使用 - // 返回 可放置干员的坐标 + // 返回 可格子的位置 Point get_placed(Loc buildable_type); bool m_used_opers = false; int m_pre_hp = 0; - std::vector m_side_tile_info; + std::unordered_map m_side_tile_info; std::vector m_homes; size_t m_cur_home_index = 0; std::unordered_set m_used_tiles; diff --git a/src/MeoAssistant/TilePack.cpp b/src/MeoAssistant/TilePack.cpp index de9af12bee..1d39497d55 100644 --- a/src/MeoAssistant/TilePack.cpp +++ b/src/MeoAssistant/TilePack.cpp @@ -23,7 +23,8 @@ bool asst::TilePack::load(const std::string & dir) return m_tile_calculator != nullptr; } -std::vector asst::TilePack::calc(const std::string & stage_code, bool side) const +std::unordered_map asst::TilePack::calc( + const std::string & stage_code, bool side) const { LogTraceFunction; @@ -35,10 +36,10 @@ std::vector asst::TilePack::calc(const std::string & s Log.trace("After tiles cacl run"); if (!ret) { Log.info("Tiles calc error!"); - return std::vector(); + return std::unordered_map(); } - std::vector dst; + std::unordered_map dst; static const std::unordered_map TileKeyMapping = { { "tile_forbidden", TileKey::Forbidden }, @@ -63,14 +64,11 @@ std::vector asst::TilePack::calc(const std::string & s Log.error("Unknown tile type:", tile.tileKey); } - dst.emplace_back( - TileInfo{ + dst.emplace(Point(static_cast(x), static_cast(y)), TileInfo{ static_cast(tile.buildableType), static_cast(tile.heightType), key, - Point(static_cast(cv_p.x), static_cast(cv_p.y)), - Point(static_cast(x), static_cast(y)) - }); + Point(static_cast(cv_p.x), static_cast(cv_p.y)) }); } } return dst; diff --git a/src/MeoAssistant/TilePack.h b/src/MeoAssistant/TilePack.h index 205cde3b76..eb92b04ffd 100644 --- a/src/MeoAssistant/TilePack.h +++ b/src/MeoAssistant/TilePack.h @@ -45,7 +45,7 @@ namespace asst HeightType height = HeightType::Invaild; TileKey key = TileKey::Invaild; Point pos; // 像素坐标 - Point loc; // 格子坐标 + Point loc; // 格子位置 }; public: using AbstractResource::AbstractResource; @@ -53,7 +53,7 @@ namespace asst virtual bool load(const std::string& dir) override; - std::vector calc(const std::string& stage_code, bool side) const; + std::unordered_map calc(const std::string& stage_code, bool side) const; private: std::shared_ptr m_tile_calculator = nullptr;