bool save_artifacts( const std::string &path ) { std::ofstream fout; try { fout.exceptions( std::ios::badbit | std::ios::failbit ); fopen_exclusive( fout, path.c_str(), std::ofstream::trunc ); if( !fout.is_open() ) { return true; // trick game into thinking it was saved } JsonOut json( fout ); json.start_array(); for( auto & p : item_controller->get_all_itypes() ) { it_artifact_tool *art_tool = dynamic_cast<it_artifact_tool *>( p.second ); it_artifact_armor *art_armor = dynamic_cast<it_artifact_armor *>( p.second ); if( art_tool != nullptr ) { json.write( *art_tool ); } else if( art_armor != nullptr ) { json.write( *art_armor ); } } json.end_array(); fclose_exclusive( fout, path.c_str() ); return true; } catch( std::ios::failure & ) { if( fout.is_open() ) { fclose_exclusive( fout, path.c_str() ); } popup( _( "Failed to save artifacts to %s" ), path.c_str() ); return false; } }
void ofstream_wrapper_exclusive::close() { fclose_exclusive( file_stream, path.c_str() ); if( file_stream.fail() ) { throw std::runtime_error( _( "writing to file failed" ) ); } }
bool worldfactory::save_world(WORLDPTR world, bool is_conversion) { // if world is NULL then change it to the active_world if (!world) { world = active_world; } // if the active_world is NULL then return w/o saving if (!world) { return false; } std::ofstream fout; std::stringstream woption; woption << world->world_path << "/" << WORLD_OPTION_FILE; if (!assure_dir_exist(world->world_path)) { DebugLog( D_ERROR, DC_ALL ) << "Unable to create or open world[" << world->world_name << "] directory for saving"; return false; } if (!is_conversion) { fopen_exclusive(fout, woption.str().c_str()); if (!fout.is_open()) { popup( _( "Could not open the world file %s, check file permissions." ), woption.str().c_str() ); return false; } fout << world_options_header() << std::endl; for( auto &elem : world->world_options ) { fout << "#" << elem.second.getTooltip() << std::endl; fout << "#" << elem.second.getDefaultText() << std::endl; fout << elem.first << " " << elem.second.getValue() << std::endl << std::endl; } fclose_exclusive(fout, woption.str().c_str()); if( fout.fail() ) { popup( _( "Failed to save the world file to %s." ), woption.str().c_str() ); } } mman->save_mods_list(world); return true; }
bool worldfactory::save_world(WORLDPTR world, bool is_conversion) { // if world is NULL then change it to the active_world if (!world) { world = active_world; } // if the active_world is NULL then return w/o saving if (!world) { return false; } std::ofstream fout; std::stringstream woption; woption << world->world_path << "/" << WORLD_OPTION_FILE; if (!assure_dir_exist(world->world_path)) { DebugLog( D_ERROR, DC_ALL ) << "Unable to create or open world[" << world->world_name << "] directory for saving"; return false; } if (!is_conversion) { fopen_exclusive(fout, woption.str().c_str()); if (!fout.is_open()) { fout.close(); return false; } fout << world_options_header() << std::endl; for (auto it = world->world_options.begin(); it != world->world_options.end(); ++it) { fout << "#" << it->second.getTooltip() << std::endl; fout << "#Default: " << it->second.getDefaultText() << std::endl; fout << it->first << " " << it->second.getValue() << std::endl << std::endl; } fclose_exclusive(fout, woption.str().c_str()); } mman->save_mods_list(world); return true; }
bool color_manager::save_custom() { const auto savefile = FILENAMES["custom_colors"]; try { std::ofstream fout; fout.exceptions(std::ios::badbit | std::ios::failbit); fopen_exclusive(fout, savefile.c_str()); if(!fout.is_open()) { return true; //trick game into thinking it was saved } fout << serialize(); fclose_exclusive(fout, savefile.c_str()); return true; } catch(std::ios::failure &) { popup(_("Failed to save custom colors to %s"), savefile.c_str()); return false; } return false; }
void mapbuffer::save_quad( const std::string &filename, const tripoint &om_addr, std::list<tripoint> &submaps_to_delete, bool delete_after_save ) { std::ofstream fout; fopen_exclusive(fout, filename.c_str()); if(!fout.is_open()) { return; } std::vector<point> offsets; offsets.push_back( point(0, 0) ); offsets.push_back( point(0, 1) ); offsets.push_back( point(1, 0) ); offsets.push_back( point(1, 1) ); JsonOut jsout( fout ); jsout.start_array(); for( std::vector<point>::iterator offset = offsets.begin(); offset != offsets.end(); ++offset ) { tripoint submap_addr = overmapbuffer::omt_to_sm_copy( om_addr ); submap_addr.x += offset->x; submap_addr.y += offset->y; if (submaps.count(submap_addr) == 0) { continue; } submap *sm = submaps[submap_addr]; if( sm == NULL ) { continue; } jsout.start_object(); jsout.member( "version", savegame_version); jsout.member( "coordinates" ); jsout.start_array(); jsout.write( submap_addr.x ); jsout.write( submap_addr.y ); jsout.write( submap_addr.z ); jsout.end_array(); jsout.member( "turn_last_touched", sm->turn_last_touched ); jsout.member( "temperature", sm->temperature ); jsout.member( "terrain" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save terrains jsout.write( terlist[sm->ter[i][j]].id ); } } jsout.end_array(); // Write out the radiation array in a simple RLE scheme. // written in intensity, count pairs jsout.member( "radiation" ); jsout.start_array(); int lastrad = -1; int count = 0; for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save radiation, re-examine this because it doesnt look like it works right int r = sm->get_radiation(i, j); if (r == lastrad) { count++; } else { if (count) { jsout.write( count ); } jsout.write( r ); lastrad = r; count = 1; } } } jsout.write( count ); jsout.end_array(); jsout.member("furniture"); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save furniture if( sm->get_furn( i, j ) != f_null ) { jsout.start_array(); jsout.write( i ); jsout.write( j ); jsout.write( furnlist[ sm->get_furn( i, j ) ].id ); jsout.end_array(); } } } jsout.end_array(); jsout.member( "items" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { if( sm->itm[i][j].empty() ) { continue; } jsout.write( i ); jsout.write( j ); jsout.write( sm->itm[i][j] ); } } jsout.end_array(); jsout.member( "traps" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save traps if (sm->get_trap( i, j ) != tr_null) { jsout.start_array(); jsout.write( i ); jsout.write( j ); jsout.write( traplist[ sm->get_trap( i, j ) ]->id ); jsout.end_array(); } } } jsout.end_array(); jsout.member( "fields" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save fields if (sm->fld[i][j].fieldCount() > 0) { jsout.write( i ); jsout.write( j ); jsout.start_array(); for(std::map<field_id, field_entry *>::iterator it = sm->fld[i][j].getFieldStart(); it != sm->fld[i][j].getFieldEnd(); ++it) { if(it->second != NULL) { // We don't seem to have a string identifier for fields anywhere. jsout.write( it->second->getFieldType() ); jsout.write( it->second->getFieldDensity() ); jsout.write( it->second->getFieldAge() ); } } jsout.end_array(); } } } jsout.end_array(); jsout.member( "graffiti" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save graffiti if (sm->get_graffiti(i, j).contents) { jsout.start_array(); jsout.write( i ); jsout.write( j ); jsout.write( *sm->get_graffiti(i, j).contents ); jsout.end_array(); } } } jsout.end_array(); jsout.member("cosmetics"); jsout.start_array(); for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { if (sm->cosmetics[i][j].size() > 0) { jsout.start_array(); jsout.write(i); jsout.write(j); jsout.write(sm->cosmetics[i][j]); jsout.end_array(); } } } jsout.end_array(); // Output the spawn points jsout.member( "spawns" ); jsout.start_array(); for( std::vector<spawn_point>::iterator spawn_it = sm->spawns.begin(); spawn_it != sm->spawns.end(); ++spawn_it ) { jsout.start_array(); jsout.write( spawn_it->type ); jsout.write( spawn_it->count ); jsout.write( spawn_it->posx ); jsout.write( spawn_it->posy ); jsout.write( spawn_it->faction_id ); jsout.write( spawn_it->mission_id ); jsout.write( spawn_it->friendly ); jsout.write( spawn_it->name ); jsout.end_array(); } jsout.end_array(); jsout.member( "vehicles" ); jsout.start_array(); for( std::vector<vehicle *>::iterator vehicle_it = sm->vehicles.begin(); vehicle_it != sm->vehicles.end(); ++vehicle_it ) { // json lib doesn't know how to turn a vehicle * into a vehicle, // so we have to iterate manually. jsout.write( **vehicle_it ); } jsout.end_array(); // Output the computer if (sm->comp.name != "") { jsout.member( "computers", sm->comp.save_data() ); } // Output base camp if any if (sm->camp.is_valid()) { jsout.member( "camp" ); jsout.write( sm->camp.save_data() ); } if( delete_after_save ) { submaps_to_delete.push_back( submap_addr ); } jsout.end_object(); } jsout.end_array(); fclose_exclusive(fout, filename.c_str()); }
void mapbuffer::save_quad( const std::string &dirname, const std::string &filename, const tripoint &om_addr, std::list<tripoint> &submaps_to_delete, bool delete_after_save ) { std::vector<point> offsets; std::vector<tripoint> submap_addrs; offsets.push_back( point(0, 0) ); offsets.push_back( point(0, 1) ); offsets.push_back( point(1, 0) ); offsets.push_back( point(1, 1) ); bool all_uniform = true; for( auto &offsets_offset : offsets ) { tripoint submap_addr = overmapbuffer::omt_to_sm_copy( om_addr ); submap_addr.x += offsets_offset.x; submap_addr.y += offsets_offset.y; submap_addrs.push_back( submap_addr ); submap *sm = submaps[submap_addr]; if( sm != nullptr && !sm->is_uniform ) { all_uniform = false; } } if( all_uniform ) { // Nothing to save - this quad will be regenerated faster than it would be re-read if( delete_after_save ) { for( auto &submap_addr : submap_addrs ) { if( submaps.count( submap_addr ) > 0 && submaps[submap_addr] != nullptr ) { submaps_to_delete.push_back( submap_addr ); } } } return; } // Don't create the directory if it would be empty assure_dir_exist( dirname.c_str() ); std::ofstream fout; fopen_exclusive( fout, filename.c_str() ); if( !fout.is_open() ) { return; } JsonOut jsout( fout ); jsout.start_array(); for( auto &submap_addr : submap_addrs ) { if( submaps.count( submap_addr ) == 0 ) { continue; } submap *sm = submaps[submap_addr]; if( sm == nullptr ) { continue; } jsout.start_object(); jsout.member( "version", savegame_version); jsout.member( "coordinates" ); jsout.start_array(); jsout.write( submap_addr.x ); jsout.write( submap_addr.y ); jsout.write( submap_addr.z ); jsout.end_array(); jsout.member( "turn_last_touched", sm->turn_last_touched ); jsout.member( "temperature", sm->temperature ); jsout.member( "terrain" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save terrains jsout.write( sm->ter[i][j].obj().id ); } } jsout.end_array(); // Write out the radiation array in a simple RLE scheme. // written in intensity, count pairs jsout.member( "radiation" ); jsout.start_array(); int lastrad = -1; int count = 0; for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save radiation, re-examine this because it doesn't look like it works right int r = sm->get_radiation(i, j); if (r == lastrad) { count++; } else { if (count) { jsout.write( count ); } jsout.write( r ); lastrad = r; count = 1; } } } jsout.write( count ); jsout.end_array(); jsout.member("furniture"); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save furniture if( sm->get_furn( i, j ) != f_null ) { jsout.start_array(); jsout.write( i ); jsout.write( j ); jsout.write( sm->get_furn( i, j ).obj().id ); jsout.end_array(); } } } jsout.end_array(); jsout.member( "items" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { if( sm->itm[i][j].empty() ) { continue; } jsout.write( i ); jsout.write( j ); jsout.write( sm->itm[i][j] ); } } jsout.end_array(); jsout.member( "traps" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save traps if (sm->get_trap( i, j ) != tr_null) { jsout.start_array(); jsout.write( i ); jsout.write( j ); // TODO: jsout should support writting an id like jsout.write( trap_id ) jsout.write( sm->get_trap( i, j ).id().str() ); jsout.end_array(); } } } jsout.end_array(); jsout.member( "fields" ); jsout.start_array(); for(int j = 0; j < SEEY; j++) { for(int i = 0; i < SEEX; i++) { // Save fields if (sm->fld[i][j].fieldCount() > 0) { jsout.write( i ); jsout.write( j ); jsout.start_array(); for( auto &fld : sm->fld[i][j] ) { const field_entry &cur = fld.second; // We don't seem to have a string identifier for fields anywhere. jsout.write( cur.getFieldType() ); jsout.write( cur.getFieldDensity() ); jsout.write( cur.getFieldAge() ); } jsout.end_array(); } } } jsout.end_array(); jsout.member("cosmetics"); jsout.start_array(); for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { if (sm->cosmetics[i][j].size() > 0) { jsout.start_array(); jsout.write(i); jsout.write(j); jsout.write(sm->cosmetics[i][j]); jsout.end_array(); } } } jsout.end_array(); // Output the spawn points jsout.member( "spawns" ); jsout.start_array(); for( auto &elem : sm->spawns ) { jsout.start_array(); jsout.write( elem.type.str() ); // TODO: json should know how to write string_ids jsout.write( elem.count ); jsout.write( elem.posx ); jsout.write( elem.posy ); jsout.write( elem.faction_id ); jsout.write( elem.mission_id ); jsout.write( elem.friendly ); jsout.write( elem.name ); jsout.end_array(); } jsout.end_array(); jsout.member( "vehicles" ); jsout.start_array(); for( auto &elem : sm->vehicles ) { // json lib doesn't know how to turn a vehicle * into a vehicle, // so we have to iterate manually. jsout.write( *elem ); } jsout.end_array(); // Output the computer if (sm->comp.name != "") { jsout.member( "computers", sm->comp.save_data() ); } // Output base camp if any if (sm->camp.is_valid()) { jsout.member( "camp" ); jsout.write( sm->camp.save_data() ); } if( delete_after_save ) { submaps_to_delete.push_back( submap_addr ); } jsout.end_object(); } jsout.end_array(); fclose_exclusive( fout, filename.c_str() ); }
ofstream_wrapper_exclusive::~ofstream_wrapper_exclusive() { if( file_stream.is_open() ) { fclose_exclusive( file_stream, path.c_str() ); } }