Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(port): unhardcode oter_id migrations #3840

Merged
merged 3 commits into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions data/json/mapgen/dummy/dummy.json
Original file line number Diff line number Diff line change
@@ -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" }
}
]
40 changes: 40 additions & 0 deletions data/json/obsoletion/migration_oter_ids.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
]
33 changes: 0 additions & 33 deletions data/json/obsoletion/terrains.json

This file was deleted.

9 changes: 9 additions & 0 deletions data/json/overmap/overmap_terrain/overmap_terrain.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
18 changes: 18 additions & 0 deletions doc/src/content/docs/en/mod/json/reference/json_info.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
```
2 changes: 1 addition & 1 deletion lang/extract_json_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def warning_supressed(filename):
"monstergroup",
"MONSTER_WHITELIST",
"mutation_type",
"obsolete_terrain",
"oter_id_migration",
"overlay_order",
"overmap_connection",
"overmap_location",
Expand Down
4 changes: 2 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -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();
Expand Down
36 changes: 36 additions & 0 deletions src/overmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3457,6 +3457,42 @@ void overmap::clear_connections_out()
connections_out.clear();
}

static std::map<std::string, std::string> 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<tripoint_om_omt, std::string> &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<coords::sm>( 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 )
{
Expand Down
9 changes: 4 additions & 5 deletions src/overmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<tripoint_om_omt, std::string> &needs_conversion );

// Overall terrain
void place_river( point_om_omt pa, point_om_omt pb );
void place_forests();
Expand Down Expand Up @@ -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<tripoint_om_omt, std::string> &points );
};

bool is_river( const oter_id &ter );
Expand Down
91 changes: 8 additions & 83 deletions src/savegame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
extern std::map<std::string, std::list<input_event>> 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.
Expand Down Expand Up @@ -344,81 +346,6 @@ void game::save_shortcuts( std::ostream &fout )
}
#endif

std::unordered_set<std::string> 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<tripoint_om_omt, std::string> &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<convert_nearby> nearby;
std::vector<std::pair<tripoint, std::string>> 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<tripoint, std::string> &conv : convert_unrelated_adjacent_tiles ) {
ter_set( pos + conv.first, oter_id( conv.second ) );
}
}
}

void overmap::load_monster_groups( JsonIn &jsin )
{
jsin.start_array();
Expand Down Expand Up @@ -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<tripoint_om_omt, std::string> needs_conversion;
std::unordered_map<tripoint_om_omt, std::string> oter_id_migrations;
jsin.start_array();
for( int z = 0; z < OVERMAP_LAYERS; ++z ) {
jsin.start_array();
Expand All @@ -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--;
Expand All @@ -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 );
Expand Down
Loading