public static Vector2 find_open_tile(Vector2 target_loc, int id, Vector2 loc)
        {
            reset_move_costs();
            // Prepare outside variables for pathfinding
            Game_Unit unit = Global.game_map.units[id];

            if (map_data_needs_updated(unit))
            {
                update_map_data(unit);
                last_id = id;
            }
            if (Global.game_map.width == 0)
            {
                return(Config.OFF_MAP);
            }
            //Prepare pathfinding variables
            OpenList <Vector2>        open_list   = new OpenList <Vector2>();
            ClosedListRoute <Vector2> closed_list = new ClosedListRoute <Vector2>();

            int temp_parent = -1;

            Vector2 temp_loc        = Vector2.Zero;
            int     temp_f          = 0;
            int     temp_g          = 0;
            int     temp_h          = 0;
            bool    temp_accessible = true;

            Vector2[] check_loc = new Vector2[] {
                new Vector2(0, -1), new Vector2(0, 1), new Vector2(-1, 0), new Vector2(1, 0)
            };
            Vector2 test_loc;
            bool    route_found = false;

            // Start pathfinding
            temp_g = 0;
            temp_h = manhatten_dist(loc, target_loc);
            temp_f = temp_g + temp_h;
            open_list.add_item(loc, temp_parent, temp_f, temp_g, temp_accessible);
            for (; ;)
            {
                if (open_list.size <= 0)
                {
                    break;
                }
                OpenItem <Vector2> lowest_f_item = open_list.get_lowest_f_item();
                temp_loc        = lowest_f_item.Loc;
                temp_parent     = lowest_f_item.Parent;
                temp_f          = lowest_f_item.Fcost;
                temp_g          = lowest_f_item.Gcost;
                temp_accessible = lowest_f_item.Accessible;

                temp_parent = closed_list.add_item(temp_loc, temp_parent, temp_f, temp_g, temp_accessible);
                open_list.remove_open_item();
                if (Global.game_map.get_unit(temp_loc) == null)
                {
                    route_found = true;
                    break;
                }
                else
                {
                    bool reverse = (rand.Next(2) == 0);
                    reverse = false;
                    for (int i = 0; i < check_loc.Length; i++)
                    {
                        test_loc = temp_loc + check_loc[reverse ? 3 - i : i];
                        if (Global.game_map.is_off_map(test_loc))
                        {
                            continue;
                        }
                        if (closed_list.already_added(test_loc))
                        {
                            continue;
                        }
                        check_tile(unit, test_loc, temp_parent, -1, target_loc, open_list, closed_list, true);
                    }
                }
            }
            unit_distance = 0;
            if (route_found)
            {
                return(temp_loc);
            }
            return(Config.OFF_MAP);
        }
        public static List <Vector2> get_route(Vector2 target_loc, int mov, int id, Vector2 loc, bool through_doors = false, bool ignore_doors = false)
        {
            reset_move_costs();
            // Prepare outside variables for pathfinding
            Game_Unit unit = Global.game_map.units[id];

            if (map_data_needs_updated(unit))
            {
                update_map_data(unit, through_doors, ignore_doors);
                last_id = id;
            }
            //Restrict_To_Map = !Global.game_map.is_off_map(loc, false) && !Global.game_map.is_off_map(target_loc, false); //Debug
            Restrict_To_Map = !Global.game_map.is_off_map(loc) && !Global.game_map.is_off_map(target_loc);
            //Prepare pathfinding variables
            OpenList <Vector2>        open_list   = new OpenList <Vector2>();
            ClosedListRoute <Vector2> closed_list = new ClosedListRoute <Vector2>();

            int temp_parent = -1;

            Vector2 temp_loc        = Vector2.Zero;
            int     temp_f          = 0;
            int     temp_g          = 0;
            int     temp_h          = 0;
            bool    temp_accessible = true;

            Vector2[] check_loc = new Vector2[] {
                new Vector2(0, -1), new Vector2(0, 1), new Vector2(-1, 0), new Vector2(1, 0)
            };
            Vector2 test_loc;
            bool    route_found = false;

            bool use_euclidean_distance = mov == -1;

            // Start pathfinding
            temp_g = 0;
            temp_h = distance(loc, target_loc, use_euclidean_distance);
            temp_f = temp_g + temp_h;
            open_list.add_item(loc, temp_parent, temp_f, temp_g, temp_accessible);
            for (; ;)
            {
                if (open_list.size <= 0)
                {
                    break;
                }
                OpenItem <Vector2> lowest_f_item = open_list.get_lowest_f_item();
                temp_loc        = lowest_f_item.Loc;
                temp_parent     = lowest_f_item.Parent;
                temp_f          = lowest_f_item.Fcost;
                temp_g          = lowest_f_item.Gcost;
                temp_accessible = lowest_f_item.Accessible;

                temp_parent = closed_list.add_item(temp_loc, temp_parent, temp_f, temp_g, temp_accessible);
                open_list.remove_open_item();
                if (temp_loc == target_loc)
                {
                    route_found = true;
                    break;
                }
                else
                {
                    for (int i = 0; i < check_loc.Length; i++)
                    {
                        test_loc = temp_loc + check_loc[i];
#if DEBUG
                        if (Global.game_map.is_off_map(test_loc, Restrict_To_Map))
                        {
                            int test = 0;
                        }
#endif
                        // If the checked location isn't the target but is off the map, and off the map is not allowed
                        if (test_loc != target_loc && Global.game_map.is_off_map(test_loc, Restrict_To_Map))
                        {
                            continue;
                        }
                        // If the location is already on the closed list
                        if (closed_list.already_added(test_loc))
                        {
                            continue;
                        }
                        check_tile(unit, test_loc, temp_parent, mov, target_loc, open_list, closed_list, use_euclidean_distance: use_euclidean_distance);
                    }
                }
            }
            unit_distance = 0;
            if (route_found)
            {
                unit_distance = closed_list.get_g(temp_parent) / 10;
                var route = closed_list
                            .get_route(temp_parent)
                            .ToArray();
                return(Enumerable.Range(0, route.Length - 1)
                       .Select(x => route[x] - route[x + 1])
                       .ToList());
            }
            return(null);
        }