From b2c2c8269bf2461f7b600aaf4eb35985f0c5ccd5 Mon Sep 17 00:00:00 2001 From: Jason Jones Date: Mon, 10 Dec 2018 19:55:01 -0900 Subject: [PATCH 1/2] Add tracking of overmap special for placed terrain --- src/overmap.cpp | 1 + src/overmap.h | 5 ++++ src/savegame.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/src/overmap.cpp b/src/overmap.cpp index 572e9f4c08026..17ca4440dc8dd 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -3286,6 +3286,7 @@ void overmap::place_special( const overmap_special &special, const tripoint &p, const tripoint location = p + om_direction::rotate( elem.p, dir ); const oter_id tid = elem.terrain->get_rotated( dir ); + overmap_special_placements[location] = special.id; ter( location.x, location.y, location.z ) = tid; if( blob ) { diff --git a/src/overmap.h b/src/overmap.h index 2efaad3fa9970..2226cb3b244ae 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -265,6 +265,11 @@ class overmap std::array layer; std::unordered_map scents; + // Records the locations where a given overmap special was placed, which + // can be used after placement to lookup whether a given location was created + // as part of a special. + std::unordered_map overmap_special_placements; + regional_settings settings; oter_id get_default_terrain( int z ) const; diff --git a/src/savegame.cpp b/src/savegame.cpp index 9b96c0b1e52f3..238b1185d48f8 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -971,10 +971,46 @@ void overmap::unserialize( std::istream &fin ) } npcs.push_back( new_npc ); } + } else if( name == "overmap_special_placements" ) { + jsin.start_array(); + while( !jsin.end_array() ) { + jsin.start_object(); + overmap_special_id s; + while( !jsin.end_object() ) { + std::string name = jsin.get_member_name(); + if( name == "special" ) { + jsin.read( s ); + } else if( name == "placements" ) { + jsin.start_array(); + while( !jsin.end_array() ) { + jsin.start_object(); + while( !jsin.end_object() ) { + std::string name = jsin.get_member_name(); + if( name == "points" ) { + jsin.start_array(); + while( !jsin.end_array() ) { + jsin.start_object(); + tripoint p; + while( !jsin.end_object() ) { + std::string name = jsin.get_member_name(); + if( name == "p" ) { + jsin.read( p ); + overmap_special_placements[p] = s; + } + } + } + } + } + } + } + } + } } } } + + static void unserialize_array_from_compacted_sequence( JsonIn &jsin, bool ( &array )[OMAPX][OMAPY] ) { int count = 0; @@ -1316,6 +1352,39 @@ void overmap::serialize( std::ostream &fout ) const json.end_array(); fout << std::endl; + // Condense the overmap special placements so that all placements of a given special + // are grouped under a single key for that special. + std::map> condensed_overmap_special_placements; + for( const auto &placement : overmap_special_placements ) { + condensed_overmap_special_placements[placement.second].emplace_back( placement.first ); + } + + json.member( "overmap_special_placements" ); + json.start_array(); + for( const auto &placement : condensed_overmap_special_placements ) { + json.start_object(); + json.member( "special", placement.first ); + json.member( "placements" ); + json.start_array(); + // When we have a discriminator for different instances of a given special, + // we'd use that that group them, but since that doesn't exist yet we'll + // dump all the points of a given special into a single entry. + json.start_object(); + json.member( "points" ); + json.start_array(); + for( const tripoint &pos : placement.second ) { + json.start_object(); + json.member( "p", pos ); + json.end_object(); + } + json.end_array(); + json.end_object(); + json.end_array(); + json.end_object(); + } + json.end_array(); + fout << std::endl; + json.end_object(); fout << std::endl; } From 4945075206e57e5511ab19a72d233d9fe04a66e0 Mon Sep 17 00:00:00 2001 From: Jason Jones Date: Mon, 10 Dec 2018 19:55:45 -0900 Subject: [PATCH 2/2] Add function to check if location was from special --- src/overmap.cpp | 15 +++++++++++++++ src/overmap.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/overmap.cpp b/src/overmap.cpp index 17ca4440dc8dd..fe9fca5ced864 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -2988,6 +2988,21 @@ bool overmap::check_ot_subtype( const std::string &otype, int x, int y, int z ) return is_ot_subtype( otype.c_str(), oter ); } +bool overmap::check_overmap_special_type( const overmap_special_id &id, + const tripoint &location ) const +{ + // Try and find the special associated with this location. + auto found_id = overmap_special_placements.find( location ); + + // There was no special here, so bail. + if( found_id == overmap_special_placements.end() ) { + return false; + } + + // Return whether the found special was a match with our requested id. + return found_id->second == id; +} + void overmap::good_river( int x, int y, int z ) { if( !is_ot_type( "river", get_ter( x, y, z ) ) ) { diff --git a/src/overmap.h b/src/overmap.h index 2226cb3b244ae..f7919aa0d6c82 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -351,6 +351,7 @@ class overmap // Polishing bool check_ot_type( const std::string &otype, int x, int y, int z ) const; bool check_ot_subtype( const std::string &otype, int x, int y, int z ) const; + bool check_overmap_special_type( const overmap_special_id &id, const tripoint &location ) const; void chip_rock( int x, int y, int z ); void polish_river();