void copy_point_list(struct point_list *l, struct point_list *l2) { int i; assert(l != NULL); assert(l2 != NULL); point_list_init(l2, l->name); for (i = 0; i < l->length; i++) { struct point temp; point_init(&temp, l->plist[i].name, l->plist[i].x, l->plist[i].x); point_list_add(l2, &temp); } }
bool AStar::get_path(const int pos_x, const int dst_y, waypoint_list_t& wplst) { /// @author ZF /// @details Fills a waypoint list with sensible waypoints. It will return false if it failed to add at least one waypoint. // The function goes through all the AStar_nodes and finds out which one are critical. A critical node is one that // creates a corner. The function automatically prunes away all non-critical nodes. The final waypoint will always be // the destination coordinates. int i; size_t path_length, waypoint_num; //bool diagonal_movement = false; Node *current_node, *last_waypoint, *safe_waypoint; Node *node_path[MAX_ASTAR_PATH]; //Fill the waypoint list as much as we can, the final waypoint will always be the destination waypoint waypoint_num = 0; current_node = final_node.get(); last_waypoint = start_node.get(); //Build the local node path tree path_length = 0; while (path_length < MAX_ASTAR_PATH && current_node != start_node.get()) { // add the node to the end of the path node_path[path_length++] = current_node; // get next node current_node = current_node->parent.get(); } //Begin at the end of the list, which contains the starting node safe_waypoint = nullptr; for (i = path_length - 1; i >= 0 && waypoint_num < MAXWAY; i--) { bool change_direction; //get current node current_node = node_path[i]; //the first node should be safe if (nullptr == safe_waypoint) safe_waypoint = current_node; //is there a change in direction? change_direction = (last_waypoint->ix != current_node->ix && last_waypoint->iy != current_node->iy); //are we moving diagonally? if so, then don't fill the waypoint list with unessecary waypoints /*if( i != 0 ) { if( diagonal_movement ) diagonal_movement = (ABS(current_node->ix - safe_waypoint->ix) == 1) && (ABS(current_node->iy - safe_waypoint->iy) == 1); else diagonal_movement = (ABS(current_node->ix - last_waypoint->ix) == 1) && (ABS(current_node->iy - last_waypoint->iy) == 1); if( diagonal_movement ) { safe_waypoint = current_node; continue; } }*/ //If we have a change in direction, we need to add it as a waypoint, always add the last waypoint if (i == 0 || change_direction) { int way_x; int way_y; //Special exception for final waypoint, use raw integer if (i == 0) { way_x = pos_x; way_y = dst_y; } else { // translate to raw coordinates way_x = safe_waypoint->ix * Info<int>::Grid::Size() + (Info<int>::Grid::Size() / 2); way_y = safe_waypoint->iy * Info<int>::Grid::Size() + (Info<int>::Grid::Size() / 2); } #ifdef DEBUG_ASTAR // using >> for division only works if you know for certainty that the value // you are shifting is not intended to be neative printf("Waypoint %d: X: %d, Y: %d \n", waypoint_num, static_cast<int>(way_x / GRID_ISIZE), static_cast<int>(way_y / GRID_ISIZE)); point_list_add(way_x, way_y, 200, 800); line_list_add(last_waypoint->ix*GRID_FSIZE + (GRID_ISIZE / 2), last_waypoint->iy*GRID_FSIZE + (GRID_ISIZE / 2), 200, way_x, way_y, 200, 800); #endif // add the node to the waypoint list last_waypoint = safe_waypoint; waypoint_list_t::push(wplst, way_x, way_y); waypoint_num++; //This one is now safe safe_waypoint = current_node; } //keep track of the last safe node from our previous waypoint else { safe_waypoint = current_node; } } #ifdef DEBUG_ASTAR if (waypoint_num > 0) point_list_add(start_node->ix*GRID_FSIZE + (GRID_ISIZE / 2), start_node->iy*GRID_FSIZE + (GRID_ISIZE / 2), 200, 80); #endif return waypoint_num > 0; }