1 #pragma once 2 #ifndef CATA_SRC_OVERMAPBUFFER_H 3 #define CATA_SRC_OVERMAPBUFFER_H 4 5 #include <array> 6 #include <functional> 7 #include <iosfwd> 8 #include <memory> 9 #include <new> 10 #include <set> 11 #include <unordered_map> 12 #include <utility> 13 #include <vector> 14 15 #include "coordinates.h" 16 #include "enums.h" 17 #include "memory_fast.h" 18 #include "omdata.h" 19 #include "optional.h" 20 #include "overmap_types.h" 21 #include "type_id.h" 22 23 class basecamp; 24 class character_id; 25 class map_extra; 26 class monster; 27 class npc; 28 class overmap; 29 class overmap_special_batch; 30 class vehicle; 31 struct mongroup; 32 struct om_vehicle; 33 struct radio_tower; 34 struct regional_settings; 35 36 struct path_type { 37 bool only_road = false; 38 bool only_water = false; 39 bool amphibious = false; 40 bool only_air = false; 41 bool avoid_danger = false; 42 bool only_known_by_player = false; 43 }; 44 45 struct radio_tower_reference { 46 /** The radio tower itself, points into @ref overmap::radios */ 47 radio_tower *tower; 48 /** The global absolute position of the tower (in submap coordinates) */ 49 point_abs_sm abs_sm_pos; 50 /** Perceived signal strength (tower output strength minus distance) */ 51 int signal_strength; 52 explicit operator bool() const { 53 return tower != nullptr; 54 } 55 }; 56 57 struct city_reference { 58 static const city_reference invalid; 59 /** The city itself, points into @ref overmap::cities */ 60 const struct city *city; 61 /** The global absolute position of the city (in submap coordinates!) */ 62 tripoint_abs_sm abs_sm_pos; 63 /** Distance to center of the search */ 64 int distance; 65 66 explicit operator bool() const { 67 return city != nullptr; 68 } 69 70 int get_distance_from_bounds() const; 71 }; 72 73 struct camp_reference { 74 static const camp_reference invalid; 75 /** The camp itself, points into @ref overmap::camps */ 76 basecamp *camp; 77 /** The global absolute position of the camp (in submap coordinates!) */ 78 tripoint_abs_sm abs_sm_pos; 79 /** Distance to center of the search */ 80 int distance; 81 82 explicit operator bool() const { 83 return camp != nullptr; 84 } 85 86 int get_distance_from_bounds() const; 87 }; 88 89 struct overmap_with_local_coords { 90 overmap *om; 91 tripoint_om_omt local; 92 93 bool operator!() const { 94 return !om; 95 } 96 97 explicit operator bool() const { 98 return !!om; 99 } 100 }; 101 102 /* 103 * Standard arguments for finding overmap terrain 104 * @param origin Location of search 105 * @param types vector of Terrain type/matching rule to use to find the type 106 * @param search_range The maximum search distance. If 0, OMAPX is used. 107 * @param min_distance Matches within min_distance are ignored. 108 * @param must_see If true, only terrain seen by the player should be searched. 109 * @param cant_see If true, only terrain not seen by the player should be searched 110 * @param existing_overmaps_only If true, will restrict searches to existing overmaps only. This 111 * is particularly useful if we want to attempt to add a missing overmap special to an existing 112 * overmap rather than creating many overmaps in an attempt to find it. 113 * @param om_special If set, the terrain must be part of the specified overmap special. 114 */ 115 struct omt_find_params { 116 std::vector<std::pair<std::string, ot_match_type>> types; 117 int search_range = 0; 118 int min_distance = 0; 119 bool must_see = false; 120 bool cant_see = false; 121 bool existing_only = false; 122 cata::optional<overmap_special_id> om_special = cata::nullopt; 123 }; 124 125 class overmapbuffer 126 { 127 public: 128 overmapbuffer(); 129 130 static std::string terrain_filename( const point_abs_om & ); 131 static std::string player_filename( const point_abs_om & ); 132 133 /** 134 * Uses overmap coordinates, that means x and y are directly 135 * compared with the position of the overmap. 136 */ 137 overmap &get( const point_abs_om & ); 138 void save(); 139 void clear(); 140 void create_custom_overmap( const point_abs_om &, overmap_special_batch &specials ); 141 142 /** 143 * Uses global overmap terrain coordinates, creates the 144 * overmap if needed. 145 */ 146 const oter_id &ter( const tripoint_abs_omt &p ); 147 void ter_set( const tripoint_abs_omt &p, const oter_id &id ); 148 /** 149 * Uses global overmap terrain coordinates. 150 */ 151 bool has_note( const tripoint_abs_omt &p ); 152 bool is_marked_dangerous( const tripoint_abs_omt &p ); 153 const std::string ¬e( const tripoint_abs_omt &p ); 154 void add_note( const tripoint_abs_omt &, const std::string &message ); 155 void delete_note( const tripoint_abs_omt &p ); 156 void mark_note_dangerous( const tripoint_abs_omt &p, int radius, bool is_dangerous ); 157 bool has_extra( const tripoint_abs_omt &p ); 158 const string_id<map_extra> &extra( const tripoint_abs_omt &p ); 159 void add_extra( const tripoint_abs_omt &p, const string_id<map_extra> &id ); 160 void delete_extra( const tripoint_abs_omt &p ); 161 bool is_explored( const tripoint_abs_omt &p ); 162 void toggle_explored( const tripoint_abs_omt &p ); 163 bool seen( const tripoint_abs_omt &p ); 164 void set_seen( const tripoint_abs_omt &p, bool seen = true ); 165 bool has_camp( const tripoint_abs_omt &p ); 166 bool has_vehicle( const tripoint_abs_omt &p ); 167 bool has_horde( const tripoint_abs_omt &p ); 168 int get_horde_size( const tripoint_abs_omt &p ); 169 std::vector<om_vehicle> get_vehicle( const tripoint_abs_omt &p ); 170 const regional_settings &get_settings( const tripoint_abs_omt &p ); 171 /** 172 * Accessors for horde introspection into overmaps. 173 * Probably also useful for NPC overmap-scale navigation. 174 */ 175 /** 176 * Returns the 3x3 array of scent values surrounding the origin point. 177 * @param origin is in world-global omt coordinates. 178 */ 179 std::array<std::array<scent_trace, 3>, 3> scents_near( const tripoint_abs_omt &origin ); 180 /** 181 * Method to retrieve the scent at a given location. 182 **/ 183 scent_trace scent_at( const tripoint_abs_omt &pos ); 184 /** 185 * Method to set a scent trace. 186 * @param loc is in world-global omt coordinates. 187 * @param strength sets the intensity of the scent trace, 188 * used for determining if a monster can detect the scent. 189 */ 190 void set_scent( const tripoint_abs_omt &loc, int strength ); 191 /** 192 * Check for any dangerous monster groups at the global overmap terrain coordinates. 193 * If there are any, it's not safe. 194 */ 195 bool is_safe( const tripoint_abs_omt &p ); 196 197 /** 198 * Move the tracking mark of the given vehicle. 199 * @param veh The vehicle whose tracking device is active and 200 * that has been moved. 201 * @param old_msp The previous position (before the movement) of the 202 * vehicle. In map square coordinates (see vehicle::real_global_pos), it's 203 * used to remove the vehicle from the old overmap if the new position is 204 * on another overmap. 205 */ 206 void move_vehicle( vehicle *veh, const point_abs_ms &old_msp ); 207 /** 208 * Add the vehicle to be tracked in the overmap. 209 */ 210 void add_vehicle( vehicle *veh ); 211 /** 212 * Remove basecamp 213 */ 214 void remove_camp( const basecamp &camp ); 215 /** 216 * Remove the vehicle from being tracked in the overmap. 217 */ 218 void remove_vehicle( const vehicle *veh ); 219 /** 220 * Add Basecamp to overmapbuffer 221 */ 222 void add_camp( const basecamp &camp ); 223 224 cata::optional<basecamp *> find_camp( const point_abs_omt &p ); 225 /** 226 * Get all npcs in a area with given radius around given central point. 227 * Only npcs on the given z-level are considered. 228 * Uses square_dist for distance calculation. 229 * @param p Central point in submap coordinates. 230 * @param radius Maximal distance of npc from (x,y). If the npc 231 * is at most this far away from (x,y) it will be returned. 232 * A radius of 0 returns only those npcs that are on the 233 * specific submap. 234 */ 235 236 std::vector<shared_ptr_fast<npc>> get_npcs_near( const tripoint_abs_sm &p, int radius ); 237 /** 238 * Get all (currently loaded!) npcs that have a companion 239 * mission set. 240 */ 241 std::vector<shared_ptr_fast<npc>> get_companion_mission_npcs( int range = 100 ); 242 /** 243 * Uses overmap terrain coordinates, this also means radius is 244 * in overmap terrain. 245 * A radius of 0 returns all npcs that are on that specific 246 * overmap terrain tile. 247 */ 248 std::vector<shared_ptr_fast<npc>> get_npcs_near_omt( const tripoint_abs_omt &p, int radius ); 249 /** 250 * Same as @ref get_npcs_near(int,int,int,int) but uses 251 * player position as center. 252 */ 253 std::vector<shared_ptr_fast<npc>> get_npcs_near_player( int radius ); 254 /** 255 * Find the npc with the given ID. 256 * Returns NULL if the npc could not be found. 257 * Searches all loaded overmaps. 258 */ 259 shared_ptr_fast<npc> find_npc( character_id id ); 260 /** 261 * Get all NPCs active on the overmap 262 */ 263 std::vector<shared_ptr_fast<npc>> get_overmap_npcs(); 264 /** 265 * Find npc by id and if found, erase it from the npc list 266 * and return it ( or return nullptr if not found ). 267 */ 268 shared_ptr_fast<npc> remove_npc( const character_id &id ); 269 /** 270 * Adds the npc to an overmap ( based on the npcs current location ) 271 * and stores it there. The overmap takes ownership of the pointer. 272 */ 273 void insert_npc( const shared_ptr_fast<npc> &who ); 274 275 /** 276 * Find all places with the specific overmap terrain type. 277 * The function only searches on the z-level indicated by 278 * origin. 279 * This function may create a new overmap if needed. 280 * @param origin Location of search 281 * see omt_find_params for definitions of the terms 282 */ 283 std::vector<tripoint_abs_omt> find_all( const tripoint_abs_omt &origin, 284 const omt_find_params ¶ms ); 285 std::vector<tripoint_abs_omt> find_all( 286 const tripoint_abs_omt &origin, const std::string &type, 287 int dist, bool must_be_seen, ot_match_type match_type = ot_match_type::type, 288 bool existing_overmaps_only = false, 289 const cata::optional<overmap_special_id> &om_special = cata::nullopt ); 290 291 /** 292 * Returns a random point of specific terrain type among those found in certain search 293 * radius. 294 * This function may create new overmaps if needed. 295 * @param origin Location of search 296 * see omt_find_params for definitions of the terms 297 */ 298 tripoint_abs_omt find_random( const tripoint_abs_omt &origin, 299 const omt_find_params ¶ms ); 300 tripoint_abs_omt find_random( 301 const tripoint_abs_omt &origin, const std::string &type, int dist, 302 bool must_be_seen, ot_match_type match_type = ot_match_type::type, 303 bool existing_overmaps_only = false, 304 const cata::optional<overmap_special_id> &om_special = cata::nullopt ); 305 /** 306 * Mark a square area around center on Z-level z 307 * as seen. 308 * @param center is in absolute overmap terrain coordinates. 309 * @param radius The half size of the square to make visible. 310 * A value of 0 makes only center visible, radius 1 makes a 311 * square 3x3 visible. 312 * @param z Z level to make area on 313 * @return true if something has actually been revealed. 314 */ 315 bool reveal( const point_abs_omt ¢er, int radius, int z ); 316 bool reveal( const tripoint_abs_omt ¢er, int radius ); 317 bool reveal( const tripoint_abs_omt ¢er, int radius, 318 const std::function<bool( const oter_id & )> &filter ); 319 std::vector<tripoint_abs_omt> get_npc_path( const tripoint_abs_omt &src, 320 const tripoint_abs_omt &dest ); 321 std::vector<tripoint_abs_omt> get_npc_path( 322 const tripoint_abs_omt &src, const tripoint_abs_omt &dest, path_type &ptype ); 323 bool reveal_route( const tripoint_abs_omt &source, const tripoint_abs_omt &dest, 324 int radius = 0, bool road_only = false ); 325 /** 326 * Returns the closest point of terrain type. 327 * @param origin Location of search 328 * see omt_find_params for definitions of the terms 329 */ 330 tripoint_abs_omt find_closest( const tripoint_abs_omt &origin, 331 const omt_find_params ¶ms ); 332 tripoint_abs_omt find_closest( 333 const tripoint_abs_omt &origin, const std::string &type, int radius, bool must_be_seen, 334 ot_match_type match_type = ot_match_type::type, bool existing_overmaps_only = false, 335 const cata::optional<overmap_special_id> &om_special = cata::nullopt ); 336 337 /* These functions return the overmap that contains the given 338 * overmap terrain coordinate, and the local coordinates of that point 339 * within the overmap (for use with overmap APIs). 340 * get_existing_om_global will not create a new overmap and 341 * if the requested overmap does not yet exist it returns 342 * { nullptr, tripoint_zero }. 343 * get_om_global creates a new overmap if needed. 344 */ 345 overmap_with_local_coords get_existing_om_global( const point_abs_omt &p ); 346 overmap_with_local_coords get_existing_om_global( const tripoint_abs_omt &p ); 347 overmap_with_local_coords get_om_global( const point_abs_omt &p ); 348 overmap_with_local_coords get_om_global( const tripoint_abs_omt &p ); 349 350 /** 351 * Pass global overmap coordinates (same as @ref get). 352 * @returns true if the buffer has a overmap with 353 * the given coordinates. 354 */ 355 bool has( const point_abs_om &p ); 356 /** 357 * Get an existing overmap, does not create a new one 358 * and may return NULL if the requested overmap does not 359 * exist. 360 * (x,y) are global overmap coordinates (same as @ref get). 361 */ 362 overmap *get_existing( const point_abs_om &p ); 363 /** 364 * Returns whether or not the location has been generated (e.g. mapgen has run). 365 * @param loc is in world-global omt coordinates. 366 * @returns True if the location has been generated. 367 */ 368 bool is_omt_generated( const tripoint_abs_omt &loc ); 369 370 using t_point_with_note = std::pair<point_abs_omt, std::string>; 371 using t_notes_vector = std::vector<t_point_with_note>; get_all_notes(int z)372 t_notes_vector get_all_notes( int z ) { 373 return get_notes( z, nullptr ); // NULL => don't filter notes 374 } find_notes(int z,const std::string & pattern)375 t_notes_vector find_notes( int z, const std::string &pattern ) { 376 return get_notes( z, &pattern ); // filter with pattern 377 } 378 using t_point_with_extra = std::pair<point_abs_omt, string_id<map_extra>>; 379 using t_extras_vector = std::vector<t_point_with_extra>; get_all_extras(int z)380 t_extras_vector get_all_extras( int z ) { 381 return get_extras( z, nullptr ); // NULL => don't filter extras 382 } find_extras(int z,const std::string & pattern)383 t_extras_vector find_extras( int z, const std::string &pattern ) { 384 return get_extras( z, &pattern ); // filter with pattern 385 } 386 /** 387 * Signal nearby hordes to move to given location. 388 * @param center The origin of the signal, hordes (that recognize the signal) want to go 389 * to there. In global submap coordinates. 390 * @param sig_power The signal strength, higher values means it visible farther away. 391 */ 392 void signal_hordes( const tripoint_abs_sm ¢er, int sig_power ); 393 /** 394 * Process nearby monstergroups (dying mostly). 395 */ 396 void process_mongroups(); 397 /** 398 * Let hordes move a step. Note that this may move monster groups inside the reality bubble, 399 * therefore you should probably call @ref map::spawn_monsters to spawn them. 400 */ 401 void move_hordes(); 402 // hordes -- this uses overmap terrain coordinates! 403 std::vector<mongroup *> monsters_at( const tripoint_abs_omt &p ); 404 /** 405 * Monster groups at p - absolute submap coordinates. 406 * Groups with no population are not included. 407 */ 408 std::vector<mongroup *> groups_at( const tripoint_abs_sm &p ); 409 410 /** 411 * Spawn monsters from the overmap onto the main map (game::m). 412 * p is an absolute *submap* coordinate. 413 */ 414 void spawn_monster( const tripoint_abs_sm &p ); 415 /** 416 * Despawn the monster back onto the overmap. The monsters position 417 * (monster::pos()) is interpreted as relative to the main map. 418 */ 419 void despawn_monster( const monster &critter ); 420 /** 421 * Find radio station with given frequency, search an unspecified area around 422 * the current player location. 423 * If no matching tower has been found, it returns an object with the tower pointer set 424 * to null. 425 */ 426 radio_tower_reference find_radio_station( int frequency ); 427 /** 428 * Find all radio stations that can be received around the current player location. 429 * All entries in the returned vector are valid (have a valid tower pointer). 430 */ 431 std::vector<radio_tower_reference> find_all_radio_stations(); 432 std::vector<camp_reference> get_camps_near( const tripoint_abs_sm &location, int radius ); 433 /** 434 * Find all cities within the specified @ref radius. 435 * Result is sorted by proximity to @ref location in ascending order. 436 */ 437 std::vector<city_reference> get_cities_near( const tripoint_abs_sm &location, int radius ); 438 /** 439 * Find the closest city. If no city is close, returns an object with city set to nullptr. 440 * @param center The center of the search, the distance for determining the closest city is 441 * calculated as distance to this point. In global submap coordinates! 442 */ 443 city_reference closest_city( const tripoint_abs_sm ¢er ); 444 445 city_reference closest_known_city( const tripoint_abs_sm ¢er ); 446 447 std::string get_description_at( const tripoint_abs_sm &where ); 448 449 /** 450 * Place the specified overmap special directly on the map using the provided location and rotation. 451 * Intended to be used when you have a special in hand, the desired location and rotation are known 452 * and the special should be directly placed rather than using the overmap's placement algorithm. 453 * @param special The overmap special to place. 454 * @param p The location to place the overmap special. Absolute overmap terrain coordinates. 455 * @param dir The direction to rotate the overmap special before placement. 456 * @param must_be_unexplored If true, will require that all of the terrains where the special would be 457 * placed are unexplored. 458 * @param force If true, placement will bypass the checks for valid placement. 459 * @returns True if the special was placed, else false. 460 */ 461 bool place_special( const overmap_special &special, const tripoint_abs_omt &p, 462 om_direction::type dir, 463 bool must_be_unexplored, bool force ); 464 /** 465 * Place the specified overmap special using the overmap's placement algorithm. Intended to be used 466 * when you have a special that you want placed but it should be placed similarly to as if it were 467 * created during overmap generation. 468 * @param special_id The id of overmap special to place. 469 * @param center Used in conjunction with radius to search the specified and adjacent overmaps for 470 * a valid placement location. Absolute overmap terrain coordinates. 471 * @param radius Used in conjunction with center. Absolute overmap terrain units. 472 * @returns True if the special was placed, else false. 473 */ 474 bool place_special( const overmap_special_id &special_id, const tripoint_abs_omt ¢er, 475 int radius ); 476 477 private: 478 /** 479 * Common function used by the find_closest/all/random to determine if the location is 480 * findable based on the specified criteria. 481 * @param location Location of search 482 * see omt_find_params for definitions of the terms 483 */ 484 bool is_findable_location( const tripoint_abs_omt &location, const omt_find_params ¶ms ); 485 486 std::unordered_map< point_abs_om, std::unique_ptr< overmap > > overmaps; 487 /** 488 * Set of overmap coordinates of overmaps that are known 489 * to not exist on disk. See @ref get_existing for usage. 490 */ 491 mutable std::set<point_abs_om> known_non_existing; 492 // Cached result of previous call to overmapbuffer::get_existing 493 overmap mutable *last_requested_overmap; 494 495 /** 496 * Get a list of notes in the (loaded) overmaps. 497 * @param z only this specific z-level is search for notes. 498 * @param pattern only notes that contain this pattern are returned. 499 * If the pattern is NULL, every note matches. 500 */ 501 t_notes_vector get_notes( int z, const std::string *pattern ); 502 /** 503 * Get a list of map extras in the (loaded) overmaps. 504 * @param z only this specific z-level is search for map extras. 505 * @param pattern only map extras that contain this pattern are returned. 506 * If the pattern is NULL, every map extra matches. 507 */ 508 t_extras_vector get_extras( int z, const std::string *pattern ); 509 public: 510 /** 511 * See overmap::check_ot, this uses global 512 * overmap terrain coordinates. 513 * This function may create a new overmap if needed. 514 */ 515 bool check_ot( const std::string &otype, ot_match_type match_type, 516 const tripoint_abs_omt &p ); 517 bool check_overmap_special_type( const overmap_special_id &id, const tripoint_abs_omt &loc ); 518 519 /** 520 * These versions of the check_* methods will only check existing overmaps, and 521 * return false if the overmap doesn't exist. They do not create new overmaps. 522 */ 523 bool check_ot_existing( const std::string &otype, ot_match_type match_type, 524 const tripoint_abs_omt &loc ); 525 bool check_overmap_special_type_existing( const overmap_special_id &id, 526 const tripoint_abs_omt &loc ); 527 private: 528 /** 529 * Go thorough the monster groups of the overmap and move out-of-bounds 530 * groups to the correct overmap (if it exists), also removes empty groups. 531 */ 532 void fix_mongroups( overmap &new_overmap ); 533 /** 534 * Moves out-of-bounds NPCs to the overmaps they should be in. 535 */ 536 void fix_npcs( overmap &new_overmap ); 537 /** 538 * Retrieve overmaps that overlap the bounding box defined by the location and radius. 539 * The location is in absolute submap coordinates, the radius is in the same system. 540 * The overmaps are returned sorted by distance from the provided location (closest first). 541 */ 542 std::vector<overmap *> get_overmaps_near( const point_abs_sm &p, int radius ); 543 std::vector<overmap *> get_overmaps_near( const tripoint_abs_sm &location, int radius ); 544 }; 545 546 extern overmapbuffer overmap_buffer; 547 548 #endif // CATA_SRC_OVERMAPBUFFER_H 549