From c0a3d2321f89d44ff0c88e5d0378f8ab55a44b11 Mon Sep 17 00:00:00 2001 From: Vollch Date: Sat, 9 Dec 2023 04:17:40 +0300 Subject: [PATCH] refactor(port): unhardcode `oter_id` migrations (#3840) * Unhardcode oter_id migrations (#64564) Co-authored-by: Brambor * Style & strings extract --------- Co-authored-by: Alexey Co-authored-by: Brambor Co-authored-by: scarf --- data/json/mapgen/dummy/dummy.json | 9 ++ data/json/obsoletion/migration_oter_ids.json | 40 ++++++++ data/json/obsoletion/terrains.json | 33 ------- .../overmap_terrain/overmap_terrain.json | 9 ++ .../docs/en/mod/json/reference/json_info.md | 18 ++++ lang/extract_json_strings.py | 2 +- src/init.cpp | 4 +- src/overmap.cpp | 36 ++++++++ src/overmap.h | 9 +- src/savegame.cpp | 91 ++----------------- 10 files changed, 127 insertions(+), 124 deletions(-) create mode 100644 data/json/mapgen/dummy/dummy.json create mode 100644 data/json/obsoletion/migration_oter_ids.json delete mode 100644 data/json/obsoletion/terrains.json diff --git a/data/json/mapgen/dummy/dummy.json b/data/json/mapgen/dummy/dummy.json new file mode 100644 index 000000000000..62fe97d25d2c --- /dev/null +++ b/data/json/mapgen/dummy/dummy.json @@ -0,0 +1,9 @@ +[ + { + "type": "mapgen", + "om_terrain": [ "omt_obsolete" ], + "method": "json", + "//": "this mapgen is used for replacing obsoleted overmap terrain, normally it shouldn't spawn", + "object": { "fill_ter": "t_dirt" } + } +] diff --git a/data/json/obsoletion/migration_oter_ids.json b/data/json/obsoletion/migration_oter_ids.json new file mode 100644 index 000000000000..cb43cd2bd714 --- /dev/null +++ b/data/json/obsoletion/migration_oter_ids.json @@ -0,0 +1,40 @@ +[ + { + "type": "oter_id_migration", + "//": "obsoleted in 0.1", + "oter_ids": { + "mass_grave_north": "field", + "mass_grave_south": "field", + "mass_grave_east": "field", + "mass_grave_west": "field", + "fema": "fema_north", + "fema_entrance": "fema_entrance_north", + "fema_1_3": "fema_1_3_north", + "fema_2_1": "fema_2_1_north", + "fema_2_2": "fema_2_2_north", + "fema_2_3": "fema_2_3_north", + "fema_3_1": "fema_3_1_north", + "fema_3_2": "fema_3_2_north", + "fema_3_3": "fema_3_3_north", + "mine_entrance": "mine_entrance_north", + "mine_shaft": "mine_shaft_middle_north", + "spiral": "omt_obsolete", + "spiral_hub": "omt_obsolete" + } + }, + { + "type": "oter_id_migration", + "//": "obsoleted in 0.4", + "oter_ids": { + "underground_sub_station": "underground_sub_station_north", + "sewer_sub_station": "sewer_sub_station_north", + "anthill": "anthill_north", + "acid_anthill": "anthill_north", + "ants_food": "ants_food_north", + "ants_larvae": "ants_larvae_north", + "ants_larvae_acid": "acid_ants_larvae_north", + "ants_queen": "ants_queen_north", + "ants_queen_acid": "acid_ants_queen_north" + } + } +] diff --git a/data/json/obsoletion/terrains.json b/data/json/obsoletion/terrains.json deleted file mode 100644 index 51c44c8ead4e..000000000000 --- a/data/json/obsoletion/terrains.json +++ /dev/null @@ -1,33 +0,0 @@ -[ - { - "type": "obsolete_terrain", - "terrains": [ - "mass_grave_north", - "mass_grave_south", - "mass_grave_east", - "mass_grave_west", - "fema", - "fema_entrance", - "fema_1_3", - "fema_2_1", - "fema_2_2", - "fema_2_3", - "fema_3_1", - "fema_3_2", - "fema_3_3", - "mine_entrance", - "mine_shaft", - "spiral", - "spiral_hub", - "underground_sub_station", - "sewer_sub_station", - "anthill", - "acid_anthill", - "ants_food", - "ants_larvae", - "ants_larvae_acid", - "ants_queen", - "ants_queen_acid" - ] - } -] diff --git a/data/json/overmap/overmap_terrain/overmap_terrain.json b/data/json/overmap/overmap_terrain/overmap_terrain.json index dc8206b798b3..a517acb209ef 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain.json @@ -7,6 +7,15 @@ "color": "white", "flags": [ "NO_ROTATE" ] }, + { + "type": "overmap_terrain", + "id": "omt_obsolete", + "//": "this omt is used for replacing obsoleted overmap terrain", + "name": "nether-chewed field", + "sym": "%", + "color": "dark_gray", + "flags": [ "NO_ROTATE" ] + }, { "type": "overmap_terrain", "abstract": "generic_city_building_no_sidewalk", diff --git a/doc/src/content/docs/en/mod/json/reference/json_info.md b/doc/src/content/docs/en/mod/json/reference/json_info.md index 2f362e5fcbac..94c31fc154b0 100644 --- a/doc/src/content/docs/en/mod/json/reference/json_info.md +++ b/doc/src/content/docs/en/mod/json/reference/json_info.md @@ -3126,3 +3126,21 @@ give more produce from harvest, for numbers less than one it will give less prod } ] ``` + +## Obsoletion and migration + +For maps, you remove the item from all the places it can spawn, remove the mapgen entries, and add +the overmap terrain id into `data/json/obsoletion/migration_oter_ids.json`, to migrate oter_id +`underground_sub_station` and `sewer_sub_station` into their rotatable versions, note that if mapgen +has already generated this area this will only alter the tile shown on the overmap: + +```json +{ + "type": "oter_id_migration", + "//": "obsoleted in 0.4", + "oter_ids": { + "underground_sub_station": "underground_sub_station_north", + "sewer_sub_station": "sewer_sub_station_north" + } +} +``` diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 7995cbdf69d7..ddf4b0dbca1a 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -107,7 +107,7 @@ def warning_supressed(filename): "monstergroup", "MONSTER_WHITELIST", "mutation_type", - "obsolete_terrain", + "oter_id_migration", "overlay_order", "overmap_connection", "overmap_location", diff --git a/src/init.cpp b/src/init.cpp index 458925204e0d..7a43911a07e3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -397,7 +397,7 @@ void DynamicDataLoader::initialize() add( "weapon_category", &weapon_category::load_weapon_categories ); add( "martial_art", &load_martial_art ); add( "effect_type", &load_effect_type ); - add( "obsolete_terrain", &overmap::load_obsolete_terrains ); + add( "oter_id_migration", &overmap::load_oter_id_migration ); add( "overmap_terrain", &overmap_terrains::load ); add( "construction_category", &construction_categories::load ); add( "construction_group", &construction_groups::load ); @@ -598,7 +598,7 @@ void DynamicDataLoader::unload_data() overmap_locations::reset(); overmap_specials::reset(); overmap_terrains::reset(); - overmap::reset_obsolete_terrains(); + overmap::reset_oter_id_migrations(); profession::reset(); quality::reset(); recipe_dictionary::reset(); diff --git a/src/overmap.cpp b/src/overmap.cpp index 679fcee2da8e..a4e0333e2045 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -3575,6 +3575,42 @@ void overmap::clear_connections_out() connections_out.clear(); } +static std::map oter_id_migrations; + +void overmap::load_oter_id_migration( const JsonObject &jo ) +{ + for( const JsonMember &kv : jo.get_object( "oter_ids" ) ) { + oter_id_migrations.emplace( kv.name(), kv.get_string() ); + } +} + +void overmap::reset_oter_id_migrations() +{ + oter_id_migrations.clear(); +} + +bool overmap::is_oter_id_obsolete( const std::string &oterid ) +{ + return oter_id_migrations.count( oterid ) > 0; +} + +void overmap::migrate_oter_ids( const std::unordered_map &points ) +{ + for( const auto&[pos, old_id] : points ) { + const oter_str_id new_id = oter_str_id( oter_id_migrations.at( old_id ) ); + const tripoint_abs_sm pos_abs = project_to( project_combine( this->pos(), pos ) ); + + if( new_id.is_valid() ) { + DebugLog( DL::Warn, DC::Map ) << "migrated oter_id '" << old_id << "' at " << pos_abs + << " to '" << new_id.str() << "'"; + + ter_set( pos, new_id ); + } else { + debugmsg( "oter_id migration defined from '%s' to invalid ter_id '%s'", old_id, new_id.str() ); + } + } +} + void overmap::place_special_forced( const overmap_special_id &special_id, const tripoint_om_omt &p, om_direction::type dir ) { diff --git a/src/overmap.h b/src/overmap.h index e59daaef44b5..265be35dd71c 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -415,9 +415,6 @@ class overmap void process_mongroups(); void move_hordes(); - static bool is_obsolete_terrain( const std::string &ter ); - void convert_terrain( const std::unordered_map &needs_conversion ); - // Overall terrain void place_river( point_om_omt pa, point_om_omt pb ); void place_forests(); @@ -511,8 +508,10 @@ class overmap void load_legacy_monstergroups( JsonIn &jsin ); void save_monster_groups( JsonOut &jo ) const; public: - static void load_obsolete_terrains( const JsonObject &jo ); - static void reset_obsolete_terrains(); + static void load_oter_id_migration( const JsonObject &jo ); + static void reset_oter_id_migrations(); + static bool is_oter_id_obsolete( const std::string &oterid ); + void migrate_oter_ids( const std::unordered_map &points ); }; bool is_river( const oter_id &ter ); diff --git a/src/savegame.cpp b/src/savegame.cpp index dcf6eb8ae911..a69860c3e334 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -50,6 +50,8 @@ extern std::map> quick_shortcuts_map; #endif +static const oter_str_id oter_omt_obsolete( "omt_obsolete" ); + /* * Changes that break backwards compatibility should bump this number, so the game can * load a legacy format loader. @@ -344,81 +346,6 @@ void game::save_shortcuts( std::ostream &fout ) } #endif -std::unordered_set obsolete_terrains; - -void overmap::load_obsolete_terrains( const JsonObject &jo ) -{ - for( const std::string line : jo.get_array( "terrains" ) ) { - obsolete_terrains.emplace( line ); - } -} - -void overmap::reset_obsolete_terrains() -{ - obsolete_terrains.clear(); -} - -bool overmap::is_obsolete_terrain( const std::string &ter ) -{ - return obsolete_terrains.find( ter ) != obsolete_terrains.end(); -} - -/* - * Complex conversion of outdated overmap terrain ids. - * This is used when loading saved games with old oter_ids. - */ -void overmap::convert_terrain( - const std::unordered_map &needs_conversion ) -{ - for( const auto &convert : needs_conversion ) { - const tripoint_om_omt pos = convert.first; - const std::string old = convert.second; - - struct convert_nearby { - point offset; - std::string x_id; - std::string y_id; - std::string new_id; - }; - - std::vector nearby; - std::vector> convert_unrelated_adjacent_tiles; - - if( old == "fema" || old == "fema_entrance" || old == "fema_1_3" || - old == "fema_2_1" || old == "fema_2_2" || old == "fema_2_3" || - old == "fema_3_1" || old == "fema_3_2" || old == "fema_3_3" || - old == "mine_entrance" || old == "underground_sub_station" || - old == "sewer_sub_station" || old == "anthill" || - old == "ants_larvae" || old == "ants_queen" || old == "ants_food" ) { - ter_set( pos, oter_id( old + "_north" ) ); - } else if( old.compare( 0, 10, "mass_grave" ) == 0 ) { - ter_set( pos, oter_id( "field" ) ); - } else if( old == "mine_shaft" ) { - ter_set( pos, oter_id( "mine_shaft_middle_north" ) ); - } else if( old == "ants_larvae_acid" ) { - ter_set( pos, oter_id( "acid_ants_larvae_north" ) ); - } else if( old == "ants_queen_acid" ) { - ter_set( pos, oter_id( "acid_ants_queen_north" ) ); - } else if( old == "acid_anthill" ) { - ter_set( pos, oter_id( "anthill_north" ) ); - } - - for( const auto &conv : nearby ) { - const auto x_it = needs_conversion.find( pos + point( conv.offset.x, 0 ) ); - const auto y_it = needs_conversion.find( pos + point( 0, conv.offset.y ) ); - if( x_it != needs_conversion.end() && x_it->second == conv.x_id && - y_it != needs_conversion.end() && y_it->second == conv.y_id ) { - ter_set( pos, oter_id( conv.new_id ) ); - break; - } - } - - for( const std::pair &conv : convert_unrelated_adjacent_tiles ) { - ter_set( pos + conv.first, oter_id( conv.second ) ); - } - } -} - void overmap::load_monster_groups( JsonIn &jsin ) { jsin.start_array(); @@ -459,7 +386,7 @@ void overmap::unserialize( std::istream &fin, const std::string &file_path ) while( !jsin.end_object() ) { const std::string name = jsin.get_member_name(); if( name == "layers" ) { - std::unordered_map needs_conversion; + std::unordered_map oter_id_migrations; jsin.start_array(); for( int z = 0; z < OVERMAP_LAYERS; ++z ) { jsin.start_array(); @@ -473,17 +400,15 @@ void overmap::unserialize( std::istream &fin, const std::string &file_path ) jsin.read( tmp_ter ); jsin.read( count ); jsin.end_array(); - if( is_obsolete_terrain( tmp_ter ) ) { + if( is_oter_id_obsolete( tmp_ter ) ) { for( int p = i; p < i + count; p++ ) { - needs_conversion.emplace( - tripoint_om_omt( p, j, z - OVERMAP_DEPTH ), tmp_ter ); + oter_id_migrations.emplace( tripoint_om_omt( p, j, z - OVERMAP_DEPTH ), tmp_ter ); } - tmp_otid = oter_id( 0 ); } else if( oter_str_id( tmp_ter ).is_valid() ) { tmp_otid = oter_id( tmp_ter ); } else { - debugmsg( "Loaded bad ter! ter %s", tmp_ter.c_str() ); - tmp_otid = oter_id( 0 ); + debugmsg( "Loaded invalid oter_id '%s'", tmp_ter.c_str() ); + tmp_otid = oter_omt_obsolete; } } count--; @@ -493,7 +418,7 @@ void overmap::unserialize( std::istream &fin, const std::string &file_path ) jsin.end_array(); } jsin.end_array(); - convert_terrain( needs_conversion ); + migrate_oter_ids( oter_id_migrations ); } else if( name == "region_id" ) { std::string new_region_id; jsin.read( new_region_id );