diff --git a/resource/roguelike_copilot.json b/resource/roguelike_copilot.json index 9ff70b6145..da1397cf3e 100644 --- a/resource/roguelike_copilot.json +++ b/resource/roguelike_copilot.json @@ -1,17 +1,4 @@ [ - { - "stage_name": "驯兽小屋", - "replacement_home": [ - [ - 8, - 3 - ], - [ - 8, - 4 - ] - ] - }, { "stage_name": "巡逻队", "replacement_home": [ diff --git a/src/MeoAssistant/BattleDataConfiger.h b/src/MeoAssistant/BattleDataConfiger.h index bd9e8156cf..73292f3729 100644 --- a/src/MeoAssistant/BattleDataConfiger.h +++ b/src/MeoAssistant/BattleDataConfiger.h @@ -22,22 +22,26 @@ namespace asst return iter->second.role; } + static inline const BattleAttackRange& EmptyRange{ {0, 0} }; + const BattleAttackRange& get_range(const std::string& name, size_t index) const { - static const BattleAttackRange empty = { {0, 0} }; auto char_iter = m_chars.find(name); if (char_iter == m_chars.cend()) { - return empty; + return EmptyRange; } const auto& ranges = char_iter->second.ranges; if (index < 0 || index >= ranges.size()) { - return empty; + if (ranges.empty()) { + return EmptyRange; + } + index = 0; } const std::string& range_name = ranges.at(index); auto range_iter = m_ranges.find(range_name); if (range_iter == m_ranges.cend()) { - return empty; + return EmptyRange; } return range_iter->second; } diff --git a/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp b/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp index dbd1914a93..b9f23a3e91 100644 --- a/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp +++ b/src/MeoAssistant/RoguelikeBattleTaskPlugin.cpp @@ -250,7 +250,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle() wait_melee = true; } } - else if (m_used_tiles.size() == 1) { + else if (m_used_tiles.size() == 1 && m_homes.size() == 1) { if (op.role == BattleRole::Medic) { wait_medic = true; } @@ -301,10 +301,11 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle() if (oper_name_analyzer.analyze()) { oper_name_analyzer.sort_result_by_score(); oper_name = oper_name_analyzer.get_result().front().text; + opt_oper.name = oper_name; } // 计算最优部署位置及方向 - const auto& [placed_loc, direction] = calc_best_plan(opt_oper.role); + const auto& [placed_loc, direction] = calc_best_plan(opt_oper); // 将干员拖动到场上 Point placed_point = m_side_tile_info.at(placed_loc).pos; @@ -526,10 +527,10 @@ bool asst::RoguelikeBattleTaskPlugin::wait_start() // return placed_rect; //} -asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::calc_best_plan(BattleRole role) +asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::calc_best_plan(const BattleRealTimeOper& oper) { auto buildable_type = Loc::All; - switch (role) { + switch (oper.role) { case BattleRole::Medic: case BattleRole::Support: case BattleRole::Sniper: @@ -594,7 +595,7 @@ asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::cal return DeployInfo(); } m_used_tiles.clear(); - return calc_best_plan(role); + return calc_best_plan(oper); } std::sort(available_locations.begin(), available_locations.end(), comp_dist); @@ -613,12 +614,12 @@ asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::cal int min_dist = std::abs(near_loc.x - home.x) + std::abs(near_loc.y - home.y); for (const auto& loc : available_locations) { - auto cur_result = calc_best_direction_and_score(loc, role); + auto cur_result = calc_best_direction_and_score(loc, oper); // 离得远的要扣分 constexpr int DistWeights = -1050; int extra_dist = std::abs(loc.x - home.x) + std::abs(loc.y - home.y) - min_dist; int extra_dist_score = DistWeights * extra_dist; - if (role == BattleRole::Medic) { // 医疗干员离得远无所谓 + if (oper.role == BattleRole::Medic) { // 医疗干员离得远无所谓 extra_dist_score = 0; } @@ -631,7 +632,7 @@ asst::RoguelikeBattleTaskPlugin::DeployInfo asst::RoguelikeBattleTaskPlugin::cal return { best_location, best_direction }; } -std::pair asst::RoguelikeBattleTaskPlugin::calc_best_direction_and_score(Point loc, BattleRole role) +std::pair asst::RoguelikeBattleTaskPlugin::calc_best_direction_and_score(Point loc, const BattleRealTimeOper& oper) { LogTraceFunction; @@ -658,51 +659,54 @@ std::pair asst::RoguelikeBattleTaskPlugin::calc_best_direction base_direction.x = sgn(loc.x - home_loc.x); } // 医疗反着算 - if (role == BattleRole::Medic) { + if (oper.role == BattleRole::Medic) { base_direction = -base_direction; } + int64_t elite = m_status->get_number("Roguelike-" + oper.name).value_or(0); // 按朝右算,后面根据方向做转换 - std::vector right_attack_range = { Point(0, 0) }; + BattleAttackRange right_attack_range = Resrc.battle_data().get_range(oper.name, elite); - switch (role) { - case BattleRole::Support: - right_attack_range = { - Point(-1, -1),Point(0, -1),Point(1, -1),Point(2, -1), - Point(-1, 0), Point(0, 0), Point(1, 0), Point(2, 0), - Point(-1, 1), Point(0, 1), Point(1, 1), Point(2, 1), - }; - break; - case BattleRole::Caster: - right_attack_range = { - Point(0, -1),Point(1, -1),Point(2, -1), - Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 0), - Point(0, 1), Point(1, 1), Point(2, 1), - }; - break; - case BattleRole::Medic: - case BattleRole::Sniper: - right_attack_range = { - Point(0, -1),Point(1, -1),Point(2, -1),Point(3, -1), - Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 0), - Point(0, 1), Point(1, 1), Point(2, 1), Point(3, 1), - }; - break; - case BattleRole::Warrior: - right_attack_range = { - Point(0, 0), Point(1, 0), Point(2, 0) - }; - break; - case BattleRole::Special: - case BattleRole::Tank: - case BattleRole::Pioneer: - case BattleRole::Drone: - right_attack_range = { - Point(0, 0), Point(1, 0) - }; - break; - default: - break; + if (right_attack_range == BattleDataConfiger::EmptyRange) { + switch (oper.role) { + case BattleRole::Support: + right_attack_range = { + Point(-1, -1),Point(0, -1),Point(1, -1),Point(2, -1), + Point(-1, 0), Point(0, 0), Point(1, 0), Point(2, 0), + Point(-1, 1), Point(0, 1), Point(1, 1), Point(2, 1), + }; + break; + case BattleRole::Caster: + right_attack_range = { + Point(0, -1),Point(1, -1),Point(2, -1), + Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 0), + Point(0, 1), Point(1, 1), Point(2, 1), + }; + break; + case BattleRole::Medic: + case BattleRole::Sniper: + right_attack_range = { + Point(0, -1),Point(1, -1),Point(2, -1),Point(3, -1), + Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 0), + Point(0, 1), Point(1, 1), Point(2, 1), Point(3, 1), + }; + break; + case BattleRole::Warrior: + right_attack_range = { + Point(0, 0), Point(1, 0), Point(2, 0) + }; + break; + case BattleRole::Special: + case BattleRole::Tank: + case BattleRole::Pioneer: + case BattleRole::Drone: + right_attack_range = { + Point(0, 0), Point(1, 0) + }; + break; + default: + break; + } } int max_score = 0; @@ -721,7 +725,7 @@ std::pair asst::RoguelikeBattleTaskPlugin::calc_best_direction { TileKey::Wall, 500 }, { TileKey::Road, 1000 }, { TileKey::Home, 500 }, - { TileKey::EnemyHome, 900 }, + { TileKey::EnemyHome, 1200 }, { TileKey::Floor, 1000 }, { TileKey::Hole, 0 }, { TileKey::Telin, 700 }, @@ -745,7 +749,7 @@ std::pair asst::RoguelikeBattleTaskPlugin::calc_best_direction { TileKey::Healing, 1000 }, }; - switch (role) { + switch (oper.role) { case BattleRole::Medic: if (m_used_tiles.find(absolute_pos) != m_used_tiles.end()) // 根据哪个方向上人多决定朝向哪 score += 10000; diff --git a/src/MeoAssistant/RoguelikeBattleTaskPlugin.h b/src/MeoAssistant/RoguelikeBattleTaskPlugin.h index c4598222c3..24f80e6f41 100644 --- a/src/MeoAssistant/RoguelikeBattleTaskPlugin.h +++ b/src/MeoAssistant/RoguelikeBattleTaskPlugin.h @@ -41,11 +41,11 @@ namespace asst Point direction; }; - DeployInfo calc_best_plan(BattleRole role); + DeployInfo calc_best_plan(const BattleRealTimeOper& oper); // 计算摆放干员的朝向 // 返回滑动的方向、得分 - std::pair calc_best_direction_and_score(Point loc, BattleRole role); + std::pair calc_best_direction_and_score(Point loc, const BattleRealTimeOper& oper); bool m_opers_used = false; int m_pre_hp = 0; diff --git a/tools/TestCaller/main.cpp b/tools/TestCaller/main.cpp index 777d176c4c..064b908577 100644 --- a/tools/TestCaller/main.cpp +++ b/tools/TestCaller/main.cpp @@ -81,9 +81,9 @@ int main([[maybe_unused]] int argc, char** argv) AsstAppendTask(ptr, "Roguelike", R"( { - "squad": "", - "roles": "先手必胜", - "core_char": "空弦" + "squad": "突击战术分队", + "roles": "近卫", + "core_char": "棘刺" } )");