From 89dbba9a0b861a80a774ead22112db4e7e6b9078 Mon Sep 17 00:00:00 2001 From: Alexander van Gessel Date: Wed, 12 May 2010 01:05:26 +0100 Subject: [PATCH] Refactor [move_unit_fake] --- src/game_events.cpp | 168 +++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 74 deletions(-) diff --git a/src/game_events.cpp b/src/game_events.cpp index 44527b6d7a7..2e489fd157f 100644 --- a/src/game_events.cpp +++ b/src/game_events.cpp @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -1021,89 +1022,108 @@ WML_HANDLER_FUNCTION(store_turns, /*event_info*/, cfg) resources::state_of_game->get_variable(var_name) = lexical_cast_default(turns); } +namespace { + std::auto_ptr create_fake_unit(const vconfig& cfg) + { + std::string type = cfg["type"]; + std::string side = cfg["side"]; + std::string variation = cfg["variation"]; + + size_t side_num = lexical_cast_default(side,1)-1; + if (side_num >= resources::teams->size()) side_num = 0; + + unit_race::GENDER gender = string_gender(cfg["gender"]); + const unit_type *ut = unit_types.find(type); + if (!ut) return std::auto_ptr(); + std::auto_ptr fake_unit(new unit(ut, side_num + 1, false, gender)); + + if(!variation.empty()) { + config mod; + config &effect = mod.add_child("effect"); + effect["apply_to"] = "variation"; + effect["name"] = variation; + fake_unit->add_modification("variation",mod); + } + return fake_unit; + } + std::vector fake_unit_path(const unit& fake_unit, const std::vector& xvals, const std::vector& yvals) + { + gamemap *game_map = resources::game_map; + std::vector path; + map_location src; + map_location dst; + for(size_t i = 0; i != std::min(xvals.size(),yvals.size()); ++i) { + if(i==0){ + src.x = atoi(xvals[i].c_str())-1; + src.y = atoi(yvals[i].c_str())-1; + if (!game_map->on_board(src)) { + ERR_CF << "invalid move_unit_fake source: " << src << '\n'; + break; + } + path.push_back(src); + continue; + } + pathfind::shortest_path_calculator calc(fake_unit, + (*resources::teams)[fake_unit.side()-1], + *resources::units, + *resources::teams, + *game_map); + + dst.x = atoi(xvals[i].c_str())-1; + dst.y = atoi(yvals[i].c_str())-1; + if (!game_map->on_board(dst)) { + ERR_CF << "invalid move_unit_fake destination: " << dst << '\n'; + break; + } + + pathfind::plain_route route = pathfind::a_star_search(src, dst, 10000, &calc, + game_map->w(), game_map->h()); + + if (route.steps.size() == 0) { + WRN_NG << "Could not find move_unit_fake route from " << src << " to " << dst << ": ignoring complexities\n"; + pathfind::emergency_path_calculator calc(fake_unit, *game_map); + + route = pathfind::a_star_search(src, dst, 10000, &calc, + game_map->w(), game_map->h()); + if(route.steps.size() == 0) { + // This would occur when trying to do a MUF of a unit + // over locations which are unreachable to it (infinite movement + // costs). This really cannot fail. + WRN_NG << "Could not find move_unit_fake route from " << src << " to " << dst << ": ignoring terrain\n"; + pathfind::dummy_path_calculator calc(fake_unit, *game_map); + route = a_star_search(src, dst, 10000, &calc, game_map->w(), game_map->h()); + assert(route.steps.size() > 0); + } + } + // we add this section to the end of the complete path + // skipping section's head because already included + // by the previous iteration + path.insert(path.end(), + route.steps.begin()+1, route.steps.end()); + + src = dst; + } + return path; + } +} + // Moving a 'unit' - i.e. a dummy unit // that is just moving for the visual effect WML_HANDLER_FUNCTION(move_unit_fake, /*event_info*/, cfg) { - gamemap *game_map = resources::game_map; + std::auto_ptr dummy_unit = create_fake_unit(cfg); + if(!dummy_unit.get()) + return; - std::string type = cfg["type"]; - std::string side = cfg["side"]; - std::string x = cfg["x"]; - std::string y = cfg["y"]; - std::string variation = cfg["variation"]; - - size_t side_num = lexical_cast_default(side,1)-1; - if (side_num >= resources::teams->size()) side_num = 0; - - unit_race::GENDER gender = string_gender(cfg["gender"]); - const unit_type *ut = unit_types.find(type); - if (!ut) return; - unit dummy_unit(ut, side_num + 1, false, gender); - - config mod; - config &effect = mod.add_child("effect"); - effect["apply_to"] = "variation"; - effect["name"] = variation; - dummy_unit.add_modification("variation",mod); + const std::string x = cfg["x"]; + const std::string y = cfg["y"]; const std::vector xvals = utils::split(x); const std::vector yvals = utils::split(y); - std::vector path; - map_location src; - map_location dst; - for(size_t i = 0; i != std::min(xvals.size(),yvals.size()); ++i) { - if(i==0){ - src.x = atoi(xvals[i].c_str())-1; - src.y = atoi(yvals[i].c_str())-1; - if (!game_map->on_board(src)) { - ERR_CF << "invalid move_unit_fake source: " << src << '\n'; - break; - } - path.push_back(src); - continue; - } - pathfind::shortest_path_calculator calc(dummy_unit, - (*resources::teams)[side_num], - *resources::units, - *resources::teams, - *game_map); - dst.x = atoi(xvals[i].c_str())-1; - dst.y = atoi(yvals[i].c_str())-1; - if (!game_map->on_board(dst)) { - ERR_CF << "invalid move_unit_fake destination: " << dst << '\n'; - break; - } - - pathfind::plain_route route = pathfind::a_star_search(src, dst, 10000, &calc, - game_map->w(), game_map->h()); - - if (route.steps.size() == 0) { - WRN_NG << "Could not find move_unit_fake route from " << src << " to " << dst << ": ignoring complexities\n"; - pathfind::emergency_path_calculator calc(dummy_unit, *game_map); - - route = pathfind::a_star_search(src, dst, 10000, &calc, - game_map->w(), game_map->h()); - if(route.steps.size() == 0) { - // This would occur when trying to do a MUF of a unit - // over locations which are unreachable to it (infinite movement - // costs). This really cannot fail. - WRN_NG << "Could not find move_unit_fake route from " << src << " to " << dst << ": ignoring terrain\n"; - pathfind::dummy_path_calculator calc(dummy_unit, *game_map); - route = a_star_search(src, dst, 10000, &calc, game_map->w(), game_map->h()); - assert(route.steps.size() > 0); - } - } - // we add this section to the end of the complete path - // skipping section's head because already included - // by the previous iteration - path.insert(path.end(), - route.steps.begin()+1, route.steps.end()); - - src = dst; - } - if (!path.empty()) unit_display::move_unit(path, dummy_unit, *resources::teams); + const std::vector& path = fake_unit_path(*dummy_unit, xvals, yvals); + if (!path.empty()) + unit_display::move_unit(path, *dummy_unit, *resources::teams); } // Helper function(s) for [set_variable]