void mapbuffer::load() { if (!master_game) { debugmsg("Can't load mapbuffer without a master_game"); return; } std::map<tripoint, submap*>::iterator it; std::ifstream fin; fin.open("save/maps.txt"); if (!fin.is_open()) return; int itx, ity, t, d, a, num_submaps, num_loaded = 0; item it_tmp; std::string databuff; fin >> num_submaps; while (!fin.eof()) { if (num_loaded % 100 == 0) popup_nowait(_("Please wait as the map loads [%d/%d]"), num_loaded, num_submaps); int locx, locy, locz, turn; submap* sm = new submap; fin >> locx >> locy >> locz >> turn; sm->turn_last_touched = turn; int turndif = (master_game ? int(master_game->turn) - turn : 0); if (turndif < 0) turndif = 0; // Load terrain for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { int tmpter; fin >> tmpter; sm->ter[i][j] = ter_id(tmpter); sm->frn[i][j] = f_null; sm->itm[i][j].clear(); sm->trp[i][j] = tr_null; //sm->fld[i][j] = field(); //not needed now sm->graf[i][j] = graffiti(); } } // Load irradiation for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { int radtmp; fin >> radtmp; radtmp -= int(turndif / 100); // Radiation slowly decays if (radtmp < 0) radtmp = 0; sm->rad[i][j] = radtmp; } } // Load items and traps and fields and spawn points and vehicles std::string string_identifier; do { fin >> string_identifier; // "----" indicates end of this submap t = 0; if (string_identifier == "I") { fin >> itx >> ity; getline(fin, databuff); // Clear out the endline getline(fin, databuff); it_tmp.load_info(databuff, master_game); sm->itm[itx][ity].push_back(it_tmp); if (it_tmp.active) sm->active_item_count++; } else if (string_identifier == "C") { getline(fin, databuff); // Clear out the endline getline(fin, databuff); int index = sm->itm[itx][ity].size() - 1; it_tmp.load_info(databuff, master_game); sm->itm[itx][ity][index].put_in(it_tmp); if (it_tmp.active) sm->active_item_count++; } else if (string_identifier == "T") { fin >> itx >> ity >> t; sm->trp[itx][ity] = trap_id(t); } else if (string_identifier == "f") {
// We're reading in way too many entities here to mess around with creating sub-objects and // seeking around in them, so we're using the json streaming API. submap *mapbuffer::unserialize_submaps( const tripoint &p ) { // Map the tripoint to the submap quad that stores it. const tripoint om_addr = overmapbuffer::sm_to_omt_copy( p ); const tripoint segment_addr = overmapbuffer::omt_to_seg_copy( om_addr ); std::stringstream quad_path; quad_path << world_generator->active_world->world_path << "/maps/" << segment_addr.x << "." << segment_addr.y << "." << segment_addr.z << "/" << om_addr.x << "." << om_addr.y << "." << om_addr.z << ".map"; std::ifstream fin( quad_path.str().c_str() ); if( !fin.is_open() ) { // If it doesn't exist, trigger generating it. return NULL; } JsonIn jsin( fin ); jsin.start_array(); while( !jsin.end_array() ) { std::unique_ptr<submap> sm(new submap()); tripoint submap_coordinates; jsin.start_object(); while( !jsin.end_object() ) { std::string submap_member_name = jsin.get_member_name(); if( submap_member_name == "version" ) { // We aren't using the version number for anything at the moment. jsin.skip_value(); } else if( submap_member_name == "coordinates" ) { jsin.start_array(); int locx = jsin.get_int(); int locy = jsin.get_int(); int locz = jsin.get_int(); jsin.end_array(); submap_coordinates = tripoint( locx, locy, locz ); } else if( submap_member_name == "turn_last_touched" ) { sm->turn_last_touched = jsin.get_int(); } else if( submap_member_name == "temperature" ) { sm->temperature = jsin.get_int(); } else if( submap_member_name == "terrain" ) { // TODO: try block around this to error out if we come up short? jsin.start_array(); for( int j = 0; j < SEEY; j++ ) { for( int i = 0; i < SEEX; i++ ) { sm->ter[i][j] = termap[ jsin.get_string() ].loadid; } } jsin.end_array(); } else if( submap_member_name == "radiation" ) { int rad_cell = 0; jsin.start_array(); while( !jsin.end_array() ) { int rad_strength = jsin.get_int(); int rad_num = jsin.get_int(); for( int i = 0; i < rad_num; ++i ) { // A little array trick here, assign to it as a 1D array. // If it's not in bounds we're kinda hosed anyway. sm->set_radiation(0, rad_cell, rad_strength); rad_cell++; } } } else if( submap_member_name == "furniture" ) { jsin.start_array(); while( !jsin.end_array() ) { jsin.start_array(); int i = jsin.get_int(); int j = jsin.get_int(); sm->frn[i][j] = furnmap[ jsin.get_string() ].loadid; jsin.end_array(); } } else if( submap_member_name == "items" ) { jsin.start_array(); while( !jsin.end_array() ) { int i = jsin.get_int(); int j = jsin.get_int(); jsin.start_array(); while( !jsin.end_array() ) { item tmp; jsin.read( tmp ); sm->itm[i][j].push_back( tmp ); } } } else if( submap_member_name == "traps" ) { jsin.start_array(); while( !jsin.end_array() ) { jsin.start_array(); int i = jsin.get_int(); int j = jsin.get_int(); sm->trp[i][j] = trapmap[ jsin.get_string() ]; jsin.end_array(); } } else if( submap_member_name == "fields" ) { jsin.start_array(); while( !jsin.end_array() ) { // Coordinates loop int i = jsin.get_int(); int j = jsin.get_int(); jsin.start_array(); while( !jsin.end_array() ) { int type = jsin.get_int(); int density = jsin.get_int(); int age = jsin.get_int(); if (sm->fld[i][j].findField(field_id(type)) == NULL) { sm->field_count++; } sm->fld[i][j].addField(field_id(type), density, age); } } } else if( submap_member_name == "griffiti" ) { jsin.start_array(); while( !jsin.end_array() ) { jsin.start_array(); int i = jsin.get_int(); int j = jsin.get_int(); sm->set_graffiti(i, j, graffiti( jsin.get_string() )); jsin.end_array(); } } else if(submap_member_name == "cosmetics") { jsin.start_array(); while (!jsin.end_array()) { jsin.start_array(); int i = jsin.get_int(); int j = jsin.get_int(); jsin.read(sm->cosmetics[i][j]); jsin.end_array(); } } else if( submap_member_name == "spawns" ) { jsin.start_array(); while( !jsin.end_array() ) { jsin.start_array(); std::string type = jsin.get_string(); int count = jsin.get_int(); int i = jsin.get_int(); int j = jsin.get_int(); int faction_id = jsin.get_int(); int mission_id = jsin.get_int(); bool friendly = jsin.get_bool(); std::string name = jsin.get_string(); jsin.end_array(); spawn_point tmp( type, count, i, j, faction_id, mission_id, friendly, name ); sm->spawns.push_back( tmp ); } } else if( submap_member_name == "vehicles" ) { jsin.start_array(); while( !jsin.end_array() ) { vehicle *tmp = new vehicle(); jsin.read( *tmp ); sm->vehicles.push_back( tmp ); } } else if( submap_member_name == "computers" ) { std::string computer_data = jsin.get_string(); sm->comp.load_data( computer_data ); } else if( submap_member_name == "camp" ) { std::string camp_data = jsin.get_string(); sm->camp.load_data( camp_data ); } else { jsin.skip_value(); } } if( !add_submap( submap_coordinates, sm ) ) { debugmsg( "submap %d,%d,%d was alread loaded", submap_coordinates.x, submap_coordinates.y, submap_coordinates.z ); } } if( submaps.count( p ) == 0 ) { debugmsg("file %s did not contain the expected submap %d,%d,%d", quad_path.str().c_str(), p.x, p.y, p.z); return NULL; } return submaps[ p ]; }