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);
	}
}
Example #2
0
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;
}