Skip to content

Commit

Permalink
Adjust zones save/load cycle
Browse files Browse the repository at this point in the history
  • Loading branch information
Menschheit authored and kevingranade committed Jan 18, 2022
1 parent dc02e84 commit cf7abd2
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 5 deletions.
77 changes: 73 additions & 4 deletions src/clzones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "cursesdef.h"
#include "debug.h"
#include "faction.h"
#include "filesystem.h"
#include "generic_factory.h"
#include "iexamine.h"
#include "item.h"
Expand All @@ -43,6 +44,8 @@
#include "visitable.h"
#include "vpart_position.h"

static const faction_id faction_your_followers( "your_followers" );

static const item_category_id item_category_food( "food" );

static const itype_id itype_disassembly( "disassembly" );
Expand Down Expand Up @@ -137,6 +140,8 @@ void zone_manager::clear()
// Do not clear types since it is needed for the next games.
area_cache.clear();
vzone_cache.clear();
// Invalidate cache
loaded = false;
}

std::string zone_type::name() const
Expand Down Expand Up @@ -1049,6 +1054,11 @@ void zone_manager::add( const std::string &name, const zone_type_id &type, const

//Create a regular zone
zones.push_back( new_zone );

//If not player defined, save them immediately
if( fac != faction_your_followers ) {
save_world_zones();
}
if( personal ) {
num_personal_zones++;
}
Expand Down Expand Up @@ -1197,7 +1207,11 @@ bool zone_manager::has_personal_zones() const

void zone_manager::serialize( JsonOut &json ) const
{
json.write( zones );
std::vector<zone_data> tmp;
std::copy_if( zones.begin(), zones.end(), std::back_inserter( tmp ), []( zone_data z ) {
return z.get_faction() == faction_your_followers;
} );
json.write( tmp );
}

void zone_manager::deserialize( const JsonValue &jv )
Expand All @@ -1213,6 +1227,9 @@ void zone_manager::deserialize( const JsonValue &jv )
zones.erase( it );
debugmsg( "Invalid zone type: %s", zone_type.c_str() );
}
if( it->get_faction() != faction_your_followers ) {
zones.erase( it );
}
}
}

Expand Down Expand Up @@ -1281,7 +1298,7 @@ void zone_data::deserialize( const JsonObject &data )

bool zone_manager::save_zones()
{
std::string savefile = PATH_INFO::player_base_save_path() + ".zones.json";
std::string savefile = PATH_INFO::player_base_save_path() + ".zones_cache.json";

added_vzones.clear();
changed_vzones.clear();
Expand All @@ -1294,19 +1311,71 @@ bool zone_manager::save_zones()

void zone_manager::load_zones()
{
std::string cache = PATH_INFO::player_base_save_path() + ".zones_cache.json";
std::string savefile = PATH_INFO::player_base_save_path() + ".zones.json";

read_from_file_optional( savefile, [&]( std::istream & fin ) {
const auto reader = [&]( std::istream & fin ) {
JsonIn jsin( fin );
deserialize( jsin.get_value() );
} );
};
if( !read_from_file_optional( loaded ? cache : savefile, reader ) ) {
// If no such file or failed to load, clear zones.
zones.clear();
}
load_world_zones();
revert_vzones();
added_vzones.clear();
changed_vzones.clear();
removed_vzones.clear();

cache_data();
cache_vzones();
if( !loaded ) {
// validate cache.
remove_file( cache );
copy_file( savefile, cache );
}
loaded = true;
}

bool zone_manager::save_world_zones()
{
std::string savefile = PATH_INFO::world_base_save_path() + "/zones_cache.json";
std::vector<zone_data> tmp;
std::copy_if( zones.begin(), zones.end(), std::back_inserter( tmp ), []( zone_data z ) {
return z.get_faction() != faction_your_followers;
} );
return write_to_file( savefile, [&]( std::ostream & fout ) {
JsonOut jsout( fout );
jsout.write( tmp );
}, _( "zones date" ) );
}

void zone_manager::load_world_zones()
{
std::string savefile = PATH_INFO::world_base_save_path() + "/zones.json";
std::string cache = PATH_INFO::world_base_save_path() + "/zones_cache.json";
std::vector<zone_data> tmp;
read_from_file_optional( loaded ? cache : savefile, [&]( std::istream & fin ) {
JsonIn jsin( fin );
jsin.read( tmp );
for( auto it = tmp.begin(); it != tmp.end(); ++it ) {
const zone_type_id zone_type = it->get_type();
if( !has_type( zone_type ) ) {
tmp.erase( it );
debugmsg( "Invalid zone type: %s", zone_type.c_str() );
}
if( it->get_faction() == faction_your_followers ) {
tmp.erase( it );
}
}
std::copy( tmp.begin(), tmp.end(), std::back_inserter( zones ) );
} );
if( !loaded ) {
//validate cache
remove_file( cache );
copy_file( savefile, cache );
}
}

void zone_manager::zone_edited( zone_data &zone )
Expand Down
4 changes: 3 additions & 1 deletion src/clzones.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ class zone_manager
const faction_id &fac = your_fac ) const;
std::unordered_set<tripoint_abs_ms> get_vzone_set( const zone_type_id &type,
const faction_id &fac = your_fac ) const;

bool loaded = false; // NOLINT(cata-serialize)
public:
zone_manager();
~zone_manager() = default;
Expand Down Expand Up @@ -485,7 +485,9 @@ class zone_manager
bool has_personal_zones() const;

bool save_zones();
bool save_world_zones();
void load_zones();
void load_world_zones();
void zone_edited( zone_data &zone );
void revert_vzones();
void serialize( JsonOut &json ) const;
Expand Down
12 changes: 12 additions & 0 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2880,6 +2880,16 @@ bool game::save_player_data()
;
}

bool game::save_zones()
{
return ( !file_exist( PATH_INFO::world_base_save_path() + "/zones_cache.json" ) ||
copy_file( PATH_INFO::world_base_save_path() + "/zones_cache.json",
PATH_INFO::world_base_save_path() + "/zones.json" ) ) &&
( !file_exist( PATH_INFO::player_base_save_path() + ".zones_cache.json" ) ||
copy_file( PATH_INFO::player_base_save_path() + ".zones_cache.json",
PATH_INFO::player_base_save_path() + ".zones.json" ) );
}

event_bus &game::events()
{
return *event_bus_ptr;
Expand Down Expand Up @@ -2919,10 +2929,12 @@ bool game::save()
!get_auto_pickup().save_character() ||
!get_auto_notes_settings().save() ||
!get_safemode().save_character() ||
!save_zones() ||
!write_to_file( PATH_INFO::world_base_save_path() + "/uistate.json", [&]( std::ostream & fout ) {
JsonOut jsout( fout );
uistate.serialize( jsout );
}, _( "uistate data" ) ) ) {
debugmsg( "game not saved" );
return false;
} else {
world_generator->active_world->add_save( save_t::from_save_id( u.get_save_id() ) );
Expand Down
1 change: 1 addition & 0 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ class game
void serialize_master( std::ostream &fout );
// returns false if saving failed for whatever reason
bool save_maps();
bool save_zones();
#if defined(__ANDROID__)
void save_shortcuts( std::ostream &fout );
#endif
Expand Down

0 comments on commit cf7abd2

Please sign in to comment.