point overmapbuffer::find_closest(const tripoint& origin, const std::string& type, int& dist, bool must_be_seen) { int max = (dist == 0 ? OMAPX : dist); const int z = origin.z; // expanding box for (dist = 0; dist <= max; dist++) { // each edge length is 2*dist-2, because corners belong to one edge // south is +y, north is -y for (int i = 0; i < dist*2-1; i++) { //start at northwest, scan north edge int x = origin.x - dist + i; int y = origin.y - dist; if (check_ot_type(type, x, y, z)) { if (!must_be_seen || seen(x, y, z)) { return point(x, y); } } //start at southeast, scan south x = origin.x + dist - i; y = origin.y + dist; if (check_ot_type(type, x, y, z)) { if (!must_be_seen || seen(x, y, z)) { return point(x, y); } } //start at southwest, scan west x = origin.x - dist; y = origin.y + dist - i; if (check_ot_type(type, x, y, z)) { if (!must_be_seen || seen(x, y, z)) { return point(x, y); } } //start at northeast, scan east x = origin.x + dist; y = origin.y - dist + i; if (check_ot_type(type, x, y, z)) { if (!must_be_seen || seen(x, y, z)) { return point(x, y); } } } } dist = -1; return overmap::invalid_point; }
std::vector<point> overmapbuffer::find_all(const tripoint& origin, const std::string& type, int dist, bool must_be_seen) { std::vector<point> result; int max = (dist == 0 ? OMAPX / 2 : dist); for (dist = 0; dist <= max; dist++) { for (int x = origin.x - dist; x <= origin.x + dist; x++) { for (int y = origin.y - dist; y <= origin.y + dist; y++) { if (must_be_seen && !seen(x, y, origin.z)) { continue; } if (check_ot_type(type, x, y, origin.z)) { result.push_back(point(x, y)); } } } } return result; }
std::vector<tripoint> overmapbuffer::find_all( const tripoint& origin, const std::string& type, int dist, bool must_be_seen ) { std::vector<tripoint> result; // dist == 0 means search a whole overmap diameter. dist = dist ? dist : OMAPX; for (int x = origin.x - dist; x <= origin.x + dist; x++) { for (int y = origin.y - dist; y <= origin.y + dist; y++) { if (must_be_seen && !seen(x, y, origin.z)) { continue; } if (check_ot_type(type, x, y, origin.z)) { result.push_back( tripoint( x, y, origin.z ) ); } } } return result; }
tripoint overmapbuffer::find_closest( const tripoint &origin, const std::string &type, const int radius, bool must_be_seen, bool allow_subtype_matches ) { // Check the origin before searching adjacent tiles! if( allow_subtype_matches ? check_ot_subtype( type, origin.x, origin.y, origin.z ) : check_ot_type( type, origin.x, origin.y, origin.z ) ) { return origin; } // By default search overmaps within a radius of 4, // i.e. C = current overmap, X = overmaps searched: // XXXXXXXXX // XXXXXXXXX // XXXXXXXXX // XXXXXXXXX // XXXXCXXXX // XXXXXXXXX // XXXXXXXXX // XXXXXXXXX // XXXXXXXXX // // See overmap::place_specials for how we attempt to insure specials are placed within this range. // The actual number is 5 because 1 covers the current overmap, // and each additional one expends the search to the next concentric circle of overmaps. int max = ( radius == 0 ? OMAPX * 5 : radius ); const int z = origin.z; // expanding box for( int dist = 0; dist <= max; dist++ ) { // each edge length is 2*dist-2, because corners belong to one edge // south is +y, north is -y for( int i = 0; i < dist * 2; i++ ) { //start at northwest, scan north edge int x = origin.x - dist + i; int y = origin.y - dist; if( allow_subtype_matches ? check_ot_subtype( type, x, y, z ) : check_ot_type( type, x, y, z ) ) { if( !must_be_seen || seen( x, y, z ) ) { return tripoint( x, y, z ); } } //start at southeast, scan south x = origin.x + dist - i; y = origin.y + dist; if( allow_subtype_matches ? check_ot_subtype( type, x, y, z ) : check_ot_type( type, x, y, z ) ) { if( !must_be_seen || seen( x, y, z ) ) { return tripoint( x, y, z ); } } //start at southwest, scan west x = origin.x - dist; y = origin.y + dist - i; if( allow_subtype_matches ? check_ot_subtype( type, x, y, z ) : check_ot_type( type, x, y, z ) ) { if( !must_be_seen || seen( x, y, z ) ) { return tripoint( x, y, z ); } } //start at northeast, scan east x = origin.x + dist; y = origin.y - dist + i; if( allow_subtype_matches ? check_ot_subtype( type, x, y, z ) : check_ot_type( type, x, y, z ) ) { if( !must_be_seen || seen( x, y, z ) ) { return tripoint( x, y, z ); } } } } return overmap::invalid_tripoint; }