Changed the structure of savegames to only contain the data necessary.
Old savegames are loaded via a conversion method.
This commit is contained in:
parent
86de023177
commit
8f6a3a5490
9 changed files with 303 additions and 301 deletions
|
@ -40,6 +40,10 @@
|
|||
#include "map.hpp"
|
||||
#include "pathfind/pathfind.hpp"
|
||||
#include "whiteboard/side_actions.hpp"
|
||||
#include "sound.hpp"
|
||||
#include "soundsource.hpp"
|
||||
#include "game_events.hpp"
|
||||
#include "map_label.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -819,12 +823,10 @@ void game_data::write_snapshot(config& cfg){
|
|||
wml_menu_items_.to_config(cfg);
|
||||
}
|
||||
|
||||
void game_data::write_config(config_writer& out, bool write_variables){
|
||||
void game_data::write_config(config_writer& out){
|
||||
out.write_key_val("random_seed", lexical_cast<std::string>(rng_.get_random_seed()));
|
||||
out.write_key_val("random_calls", lexical_cast<std::string>(rng_.get_random_calls()));
|
||||
if (write_variables) {
|
||||
out.write_child("variables", variables_);
|
||||
}
|
||||
out.write_child("variables", variables_);
|
||||
|
||||
config cfg;
|
||||
wml_menu_items_.to_config(cfg);
|
||||
|
@ -956,9 +958,9 @@ config game_classification::to_config() const
|
|||
|
||||
game_state::game_state() :
|
||||
replay_data(),
|
||||
starting_pos(),
|
||||
snapshot(),
|
||||
carryover_sides(carryover_info().to_config()),
|
||||
carryover_sides(),
|
||||
carryover_sides_start(carryover_info().to_config()),
|
||||
classification_(),
|
||||
mp_settings_()
|
||||
{}
|
||||
|
@ -973,9 +975,9 @@ void write_players(game_state& gamestate, config& cfg, const bool use_snapshot,
|
|||
|
||||
config *source = NULL;
|
||||
if (use_snapshot) {
|
||||
source = &gamestate.snapshot;
|
||||
source = &gamestate.carryover_sides_start;
|
||||
} else {
|
||||
source = &gamestate.starting_pos;
|
||||
source = &gamestate.replay_start();
|
||||
}
|
||||
|
||||
if (merge_side) {
|
||||
|
@ -1047,66 +1049,43 @@ void write_players(game_state& gamestate, config& cfg, const bool use_snapshot,
|
|||
|
||||
game_state::game_state(const config& cfg, bool show_replay) :
|
||||
replay_data(),
|
||||
starting_pos(),
|
||||
snapshot(),
|
||||
// carryover_sides(cfg.child_or_empty("carryover_sides")),
|
||||
carryover_sides(),
|
||||
carryover_sides_start(),
|
||||
replay_start_(),
|
||||
classification_(cfg),
|
||||
mp_settings_(cfg)
|
||||
{
|
||||
n_unit::id_manager::instance().set_save_id(cfg["next_underlying_unit_id"]);
|
||||
log_scope("read_game");
|
||||
|
||||
carryover_info sides(cfg.child_or_empty("carryover_sides"));
|
||||
if(cfg.has_child("carryover_sides")){
|
||||
carryover_sides = cfg.child("carryover_sides");
|
||||
}
|
||||
if(cfg.has_child("carryover_sides_start")){
|
||||
carryover_sides_start = cfg.child("carryover_sides_start");
|
||||
}
|
||||
|
||||
const config &snapshot = cfg.child("snapshot");
|
||||
const config &replay_start = cfg.child("replay_start");
|
||||
// We're loading a snapshot if we have it and the user didn't request a replay.
|
||||
bool load_snapshot = !show_replay && snapshot && !snapshot.empty();
|
||||
|
||||
if (load_snapshot) {
|
||||
this->snapshot = snapshot;
|
||||
//for backwards compatibility
|
||||
if(snapshot.has_child("variables")){
|
||||
sides.set_variables(snapshot.child("variables"));
|
||||
if(show_replay){
|
||||
//If replay_start and replay_data couldn't be loaded
|
||||
if(!load_replay(cfg)){
|
||||
//TODO: notify user of failure
|
||||
ERR_NG<<"Could not load as replay \n";
|
||||
}
|
||||
} else {
|
||||
assert(replay_start);
|
||||
//for backwards compatibility
|
||||
if(replay_start.has_child("variables")){
|
||||
sides.set_variables(replay_start.child("variables"));
|
||||
if(const config& snapshot = cfg.child("snapshot")){
|
||||
this->snapshot = snapshot;
|
||||
load_replay(cfg);
|
||||
} else if(carryover_sides_start.empty() && !carryover_sides.empty()){
|
||||
//if we are loading a start of scenario save and don't have carryover_sides_start, use carryover_sides
|
||||
carryover_sides_start = carryover_sides;
|
||||
}
|
||||
//TODO: check if loading fails completely
|
||||
}
|
||||
|
||||
//for backwards compatibility
|
||||
if(cfg.has_child("variables")){
|
||||
sides.set_variables(cfg.child("variables"));
|
||||
}
|
||||
|
||||
carryover_sides = sides.to_config();
|
||||
|
||||
LOG_NG << "scenario: '" << classification_.scenario << "'\n";
|
||||
LOG_NG << "next_scenario: '" << classification_.next_scenario << "'\n";
|
||||
|
||||
if (const config &replay = cfg.child("replay")) {
|
||||
replay_data = replay;
|
||||
}
|
||||
|
||||
if (replay_start) {
|
||||
starting_pos = replay_start;
|
||||
//This is a quick hack to make replays for campaigns work again:
|
||||
//The [player] information needs to be stored somewhere within the gamestate,
|
||||
//because we need it later on when creating the replay savegame.
|
||||
//We therefore put it inside the starting_pos, so it doesn't get lost.
|
||||
//See also playcampaign::play_game, where after finishing the scenario the replay
|
||||
//will be saved.
|
||||
if(!starting_pos.empty()) {
|
||||
BOOST_FOREACH(const config &p, cfg.child_range("player")) {
|
||||
config& cfg_player = starting_pos.add_child("player");
|
||||
cfg_player.merge_with(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (const config &stats = cfg.child("statistics")) {
|
||||
statistics::fresh_stats();
|
||||
statistics::read_stats(stats);
|
||||
|
@ -1114,9 +1093,124 @@ game_state::game_state(const config& cfg, bool show_replay) :
|
|||
|
||||
}
|
||||
|
||||
void game_state::write_snapshot(config& cfg) const
|
||||
bool game_state::load_replay(const config& cfg){
|
||||
bool replay_loaded = false;
|
||||
|
||||
if(const config& replay_start = cfg.child("replay_start")){
|
||||
replay_start_ = replay_start;
|
||||
if(const config& replay = cfg.child("replay")){
|
||||
this->replay_data = replay;
|
||||
replay_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return replay_loaded;
|
||||
}
|
||||
|
||||
void convert_old_saves(config& cfg){
|
||||
if(!cfg.has_child("snapshot")){
|
||||
return;
|
||||
}
|
||||
|
||||
const config& snapshot = cfg.child("snapshot");
|
||||
const config& replay_start = cfg.child("replay_start");
|
||||
const config& replay = cfg.child("replay");
|
||||
|
||||
if(!cfg.has_child("carryover_sides") && !cfg.has_child("carryover_sides_start")){
|
||||
config carryover;
|
||||
//copy rng and menu items from toplevel to new carryover_sides
|
||||
carryover["random_seed"] = cfg["random_seed"];
|
||||
carryover["random_calls"] = cfg["random_calls"];
|
||||
BOOST_FOREACH(const config& menu_item, cfg.child_range("menu_item")){
|
||||
carryover.add_child("menu_item", menu_item);
|
||||
}
|
||||
|
||||
config carryover_start = carryover;
|
||||
|
||||
//copy sides from either snapshot or replay_start to new carryover_sides
|
||||
if(!snapshot.empty()){
|
||||
BOOST_FOREACH(const config& side, snapshot.child_range("side")){
|
||||
carryover.add_child("side", side);
|
||||
}
|
||||
//for compatibility with old savegames that use player instead of side
|
||||
BOOST_FOREACH(const config& side, snapshot.child_range("player")){
|
||||
carryover.add_child("side", side);
|
||||
}
|
||||
//save the sides from replay_start in carryover_sides_start
|
||||
BOOST_FOREACH(const config& side, replay_start.child_range("side")){
|
||||
carryover_start.add_child("side", side);
|
||||
}
|
||||
//for compatibility with old savegames that use player instead of side
|
||||
BOOST_FOREACH(const config& side, replay_start.child_range("player")){
|
||||
carryover_start.add_child("side", side);
|
||||
}
|
||||
} else if (!replay_start.empty()){
|
||||
BOOST_FOREACH(const config& side, replay_start.child_range("side")){
|
||||
carryover.add_child("side", side);
|
||||
carryover_start.add_child("side", side);
|
||||
}
|
||||
//for compatibility with old savegames that use player instead of side
|
||||
BOOST_FOREACH(const config& side, replay_start.child_range("player")){
|
||||
carryover.add_child("side", side);
|
||||
carryover_start.add_child("side", side);
|
||||
}
|
||||
}
|
||||
|
||||
//get variables according to old hierarchy and copy them to new carryover_sides
|
||||
if(!snapshot.empty()){
|
||||
if(const config& variables = snapshot.child("variables")){
|
||||
carryover.add_child("variables", variables);
|
||||
carryover_start.add_child("variables", replay_start.child_or_empty("variables"));
|
||||
} else if (const config& variables = cfg.child("variables")){
|
||||
carryover.add_child("variables", variables);
|
||||
carryover_start.add_child("variables", variables);
|
||||
}
|
||||
} else if (!replay_start.empty()){
|
||||
if(const config& variables = replay_start.child("variables")){
|
||||
carryover.add_child("variables", variables);
|
||||
carryover_start.add_child("variables", variables);
|
||||
}
|
||||
} else {
|
||||
carryover.add_child("variables", cfg.child("variables"));
|
||||
carryover_start.add_child("variables", cfg.child("variables"));
|
||||
}
|
||||
|
||||
cfg.add_child("carryover_sides", carryover);
|
||||
cfg.add_child("carryover_sides_start", carryover_start);
|
||||
}
|
||||
|
||||
//if replay and snapshot are empty we've got a start of scenario save and don't want replay_start either
|
||||
if(replay.empty() && snapshot.empty()){
|
||||
LOG_RG<<"removing replay_start \n";
|
||||
cfg.remove_child("replay_start", 0);
|
||||
}
|
||||
|
||||
//remove empty replay or snapshot so type of save can be detected more easily
|
||||
if(replay.empty()){
|
||||
LOG_RG<<"removing replay \n";
|
||||
cfg.remove_child("replay", 0);
|
||||
}
|
||||
|
||||
if(snapshot.empty()){
|
||||
LOG_RG<<"removing snapshot \n";
|
||||
cfg.remove_child("snapshot", 0);
|
||||
}
|
||||
|
||||
LOG_RG<<"cfg after conversion "<<cfg<<"\n";
|
||||
}
|
||||
|
||||
void game_state::write_snapshot(config& cfg, game_display* gui) const
|
||||
{
|
||||
log_scope("write_game");
|
||||
if(gui != NULL){
|
||||
cfg["snapshot"] = true;
|
||||
cfg["playing_team"] = str_cast(gui->playing_team());
|
||||
|
||||
game_events::write_events(cfg);
|
||||
|
||||
sound::write_music_play_list(cfg);
|
||||
}
|
||||
|
||||
cfg["label"] = classification_.label;
|
||||
cfg["history"] = classification_.history;
|
||||
cfg["abbrev"] = classification_.abbrev;
|
||||
|
@ -1142,6 +1236,10 @@ void game_state::write_snapshot(config& cfg) const
|
|||
if(resources::gamedata != NULL){
|
||||
resources::gamedata->write_snapshot(cfg);
|
||||
}
|
||||
|
||||
if(gui != NULL){
|
||||
gui->labels().write(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
void extract_summary_from_config(config& cfg_save, config& cfg_summary)
|
||||
|
@ -1241,9 +1339,10 @@ void extract_summary_from_config(config& cfg_save, config& cfg_summary)
|
|||
|
||||
game_state::game_state(const game_state& state) :
|
||||
replay_data(state.replay_data),
|
||||
starting_pos(state.starting_pos),
|
||||
snapshot(state.snapshot),
|
||||
carryover_sides(state.carryover_sides),
|
||||
carryover_sides_start(state.carryover_sides_start),
|
||||
replay_start_(state.replay_start_),
|
||||
classification_(state.classification_),
|
||||
mp_settings_(state.mp_settings_)
|
||||
{}
|
||||
|
@ -1259,20 +1358,10 @@ game_state& game_state::operator=(const game_state& state)
|
|||
}
|
||||
|
||||
|
||||
void game_state::write_config(config_writer& out, bool write_variables) const
|
||||
void game_state::write_config(config_writer& out) const
|
||||
{
|
||||
out.write(classification_.to_config());
|
||||
if (classification_.campaign_type == "multiplayer")
|
||||
out.write_child("multiplayer", mp_settings_.to_config());
|
||||
|
||||
if(resources::gamedata != NULL){
|
||||
resources::gamedata->write_config(out, write_variables);
|
||||
}
|
||||
|
||||
if (!replay_data.child("replay")) {
|
||||
out.write_child("replay", replay_data);
|
||||
}
|
||||
|
||||
out.write_child("replay_start",starting_pos);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ class scoped_wml_variable;
|
|||
class team;
|
||||
class gamemap;
|
||||
|
||||
void convert_old_saves(config& cfg);
|
||||
|
||||
namespace t_translation {
|
||||
struct t_match;
|
||||
}
|
||||
|
@ -208,7 +210,7 @@ public:
|
|||
map_location last_selected;
|
||||
|
||||
void write_snapshot(config& cfg);
|
||||
void write_config(config_writer& out, bool write_variables);
|
||||
void write_config(config_writer& out);
|
||||
|
||||
game_data& operator=(const game_data& info);
|
||||
game_data* operator=(const game_data* info);
|
||||
|
@ -264,9 +266,9 @@ public:
|
|||
game_state& operator=(const game_state& state);
|
||||
|
||||
//write the gamestate into a config object
|
||||
void write_snapshot(config& cfg) const;
|
||||
void write_snapshot(config& cfg, game_display* gui = NULL) const;
|
||||
//write the config information into a stream (file)
|
||||
void write_config(config_writer& out, bool write_variables=true) const;
|
||||
void write_config(config_writer& out) const;
|
||||
|
||||
game_classification& classification() { return classification_; }
|
||||
const game_classification& classification() const { return classification_; } //FIXME: const getter to allow use from const gamestatus::sog() (see ai.cpp:344) - remove after merge?
|
||||
|
@ -275,20 +277,16 @@ public:
|
|||
mp_game_settings& mp_settings() { return mp_settings_; }
|
||||
const mp_game_settings& mp_settings() const { return mp_settings_; }
|
||||
|
||||
bool load_replay(const config& cfg);
|
||||
|
||||
config& replay_start() { return replay_start_; }
|
||||
|
||||
/**
|
||||
* If the game is saved mid-level, we have a series of replay steps
|
||||
* to take the game up to the position it was saved at.
|
||||
*/
|
||||
config replay_data;
|
||||
|
||||
/**
|
||||
* Saved starting state of the game.
|
||||
*
|
||||
* For multiplayer games, the position the game started in may be different
|
||||
* to the scenario.
|
||||
*/
|
||||
config starting_pos;
|
||||
|
||||
/**
|
||||
* Snapshot of the game's current contents.
|
||||
*
|
||||
|
@ -300,7 +298,13 @@ public:
|
|||
/** The carryover information for all sides*/
|
||||
config carryover_sides;
|
||||
|
||||
/** The carryover information for all sides as it was before the scenario started*/
|
||||
config carryover_sides_start;
|
||||
|
||||
private:
|
||||
/** First turn snapshot for replays, contains starting position */
|
||||
config replay_start_;
|
||||
|
||||
game_classification classification_;
|
||||
mp_game_settings mp_settings_;
|
||||
};
|
||||
|
|
|
@ -1659,7 +1659,7 @@ void connect::load_game()
|
|||
}
|
||||
|
||||
level_["experience_modifier"] = params_.xp_modifier;
|
||||
level_["random_seed"] = state_.carryover_sides["random_seed"];
|
||||
level_["random_seed"] = state_.carryover_sides_start["random_seed"];
|
||||
}
|
||||
|
||||
// Add the map name to the title.
|
||||
|
@ -1720,7 +1720,7 @@ config* connect::current_config(){
|
|||
cfg_level = &snapshot;
|
||||
} else if (!level_.child("side")) {
|
||||
// Start-of-scenario save, the info has to be taken from the starting_pos
|
||||
cfg_level = &state_.starting_pos;
|
||||
cfg_level = &state_.replay_start();
|
||||
} else {
|
||||
// Fresh game, no snapshot available
|
||||
cfg_level = &level_;
|
||||
|
|
|
@ -109,7 +109,7 @@ void level_to_gamestate(config& level, game_state& state)
|
|||
}
|
||||
}
|
||||
|
||||
carryover_info sides = carryover_info(state.carryover_sides);
|
||||
carryover_info sides = carryover_info(state.carryover_sides_start);
|
||||
|
||||
//set random
|
||||
const std::string seed = level["random_seed"];
|
||||
|
@ -129,7 +129,7 @@ void level_to_gamestate(config& level, game_state& state)
|
|||
//this is important, if it does not happen, the starting position is missing and
|
||||
//will be drawn from the snapshot instead (which is not what we want since we have
|
||||
//all needed information here already)
|
||||
state.starting_pos = level.child("replay_start");
|
||||
state.replay_start() = level.child("replay_start");
|
||||
|
||||
level["campaign_type"] = "multiplayer";
|
||||
state.classification().campaign_type = "multiplayer";
|
||||
|
@ -149,7 +149,7 @@ void level_to_gamestate(config& level, game_state& state)
|
|||
//It might be a MP campaign start-of-scenario save
|
||||
//In this case, it's not entirely a new game, but not a save, either
|
||||
//Check whether it is no savegame and the starting_pos contains [player] information
|
||||
bool start_of_scenario = !saved_game && state.starting_pos.child("player");
|
||||
bool start_of_scenario = !saved_game && state.replay_start().child("player");
|
||||
|
||||
//If we start a fresh game, there won't be any snapshot information. If however this
|
||||
//is a savegame, we got a valid snapshot here.
|
||||
|
@ -166,7 +166,7 @@ void level_to_gamestate(config& level, game_state& state)
|
|||
if(saved_game || start_of_scenario){
|
||||
config::child_itors saved_sides = saved_game ?
|
||||
state.snapshot.child_range("side") :
|
||||
state.starting_pos.child_range("side");
|
||||
state.replay_start().child_range("side");
|
||||
config::const_child_itors level_sides = level.child_range("side");
|
||||
|
||||
BOOST_FOREACH(config &side, saved_sides)
|
||||
|
@ -193,7 +193,7 @@ void level_to_gamestate(config& level, game_state& state)
|
|||
LOG_NG << sides.get_variables();
|
||||
}
|
||||
|
||||
state.carryover_sides = sides.to_config();
|
||||
state.carryover_sides_start = sides.to_config();
|
||||
}
|
||||
|
||||
std::string get_color_string(int id)
|
||||
|
|
|
@ -215,7 +215,7 @@ void play_controller::init(CVideo& video){
|
|||
}
|
||||
}
|
||||
team_builder_ptr tb_ptr = gamedata_.create_team_builder(side,
|
||||
save_id, teams_, level_, map_, units_, snapshot, gamestate_.starting_pos);
|
||||
save_id, teams_, level_, map_, units_, snapshot, gamestate_.replay_start());
|
||||
++team_num;
|
||||
gamedata_.build_team_stage_one(tb_ptr);
|
||||
team_builders.push_back(tb_ptr);
|
||||
|
@ -393,7 +393,7 @@ void play_controller::status_table(){
|
|||
void play_controller::save_game(){
|
||||
if(save_blocker::try_block()) {
|
||||
save_blocker::save_unblocker unblocker;
|
||||
savegame::game_savegame save(gamestate_, *gui_, to_config(), preferences::compress_saves());
|
||||
savegame::ingame_savegame save(gamestate_, *gui_, to_config(), preferences::compress_saves());
|
||||
save.save_game_interactive(gui_->video(), "", gui::OK_CANCEL);
|
||||
} else {
|
||||
save_blocker::on_unblock(this,&play_controller::save_game);
|
||||
|
|
|
@ -74,6 +74,11 @@ typedef std::map<std::string, player_controller> controller_map;
|
|||
|
||||
|
||||
static void team_init(config& level, game_state& gamestate){
|
||||
//if we are at the start of a new scenario, initialize carryover_sides
|
||||
if(gamestate.snapshot.child_or_empty("variables")["turn_number"].to_int(-1)<1){
|
||||
gamestate.carryover_sides = gamestate.carryover_sides_start;
|
||||
}
|
||||
|
||||
carryover_info sides(gamestate.carryover_sides);
|
||||
|
||||
sides.transfer_to(level);
|
||||
|
@ -151,7 +156,7 @@ static void store_carryover(game_state& gamestate, playsingle_controller& playco
|
|||
gui2::show_transient_message(disp.video(), title, report.str(), "", true);
|
||||
}
|
||||
|
||||
gamestate.carryover_sides = sides.to_config();
|
||||
gamestate.carryover_sides_start = sides.to_config();
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,17 +170,17 @@ void play_replay(display& disp, game_state& gamestate, const config& game_config
|
|||
// 'starting_pos' will contain the position we start the game from.
|
||||
config starting_pos;
|
||||
|
||||
if (gamestate.starting_pos.empty()){
|
||||
if (gamestate.replay_start().empty()){
|
||||
// Backwards compatibility code for 1.2 and 1.2.1
|
||||
const config &scenario = game_config.find_child(type,"id",gamestate.classification().scenario);
|
||||
assert(scenario);
|
||||
gamestate.starting_pos = scenario;
|
||||
gamestate.replay_start() = scenario;
|
||||
}
|
||||
starting_pos = gamestate.starting_pos;
|
||||
starting_pos = gamestate.replay_start();
|
||||
|
||||
//for replays, use the variables specified in starting_pos
|
||||
if (const config &vars = starting_pos.child("variables")) {
|
||||
gamestate.carryover_sides["variables"] = vars;
|
||||
gamestate.carryover_sides_start["variables"] = vars;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -318,7 +323,7 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
// 'starting_pos' will contain the position we start the game from.
|
||||
config starting_pos;
|
||||
|
||||
carryover_info sides = carryover_info(gamestate.carryover_sides);
|
||||
carryover_info sides = carryover_info(gamestate.carryover_sides_start);
|
||||
|
||||
// Do we have any snapshot data?
|
||||
// yes => this must be a savegame
|
||||
|
@ -330,29 +335,36 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
// If the gamestate already contains a starting_pos,
|
||||
// then we are starting a fresh multiplayer game.
|
||||
// Otherwise this is the start of a campaign scenario.
|
||||
if(gamestate.starting_pos["id"].empty() == false) {
|
||||
LOG_G << "loading starting position...\n";
|
||||
starting_pos = gamestate.starting_pos;
|
||||
if(gamestate.replay_start()["id"].empty() == false) {
|
||||
starting_pos = gamestate.replay_start();
|
||||
scenario = &starting_pos;
|
||||
} else {
|
||||
//reload of the scenario, as starting_pos contains carryover information only
|
||||
LOG_G << "loading scenario: '" << gamestate.classification().scenario << "'\n";
|
||||
scenario = &game_config.find_child(type, "id", gamestate.classification().scenario);
|
||||
if (*scenario) {
|
||||
starting_pos = *scenario;
|
||||
config temp(starting_pos);
|
||||
write_players(gamestate, temp, false, true);
|
||||
gamestate.starting_pos = temp;
|
||||
starting_pos = temp;
|
||||
scenario = &starting_pos;
|
||||
} else
|
||||
|
||||
if(!*scenario){
|
||||
scenario = NULL;
|
||||
}
|
||||
LOG_G << "scenario found: " << (scenario != NULL ? "yes" : "no") << "\n";
|
||||
|
||||
//TODO: remove when replay_start is confirmed
|
||||
// if (*scenario) {
|
||||
// starting_pos = *scenario;
|
||||
// config temp(starting_pos);
|
||||
// write_players(gamestate, temp, false, true);
|
||||
// gamestate.replay_start() = temp;
|
||||
// starting_pos = temp;
|
||||
// scenario = &starting_pos;
|
||||
// } else {
|
||||
// scenario = NULL;
|
||||
// }
|
||||
// LOG_G << "scenario found: " << (scenario != NULL ? "yes" : "no") << "\n";
|
||||
}
|
||||
} else {
|
||||
// This game was started from a savegame
|
||||
LOG_G << "loading snapshot...\n";
|
||||
starting_pos = gamestate.starting_pos;
|
||||
starting_pos = gamestate.replay_start();
|
||||
scenario = &gamestate.snapshot;
|
||||
// When starting wesnoth --multiplayer there might be
|
||||
// no variables which leads to a segfault
|
||||
|
@ -366,7 +378,7 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
}
|
||||
}
|
||||
|
||||
gamestate.carryover_sides = sides.to_config();
|
||||
gamestate.carryover_sides_start = sides.to_config();
|
||||
|
||||
controller_map controllers;
|
||||
|
||||
|
@ -433,9 +445,11 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
//TODO comment or remove
|
||||
//level_ = scenario;
|
||||
//merge carryover information into the newly generated scenario
|
||||
config temp(scenario2);
|
||||
write_players(gamestate, temp, false, true);
|
||||
gamestate.starting_pos = temp;
|
||||
|
||||
//TODO: remove when replay_start is confirmed
|
||||
// config temp(scenario2);
|
||||
// write_players(gamestate, temp, false, true);
|
||||
// gamestate.starting_pos = temp;
|
||||
scenario = &scenario2;
|
||||
}
|
||||
|
||||
|
@ -458,19 +472,20 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
scenario = &new_level;
|
||||
|
||||
//merge carryover information into the scenario
|
||||
config temp(new_level);
|
||||
write_players(gamestate, temp, false, true);
|
||||
gamestate.starting_pos = temp;
|
||||
//TODO: remove when replay_start is confirmed
|
||||
// config temp(new_level);
|
||||
// write_players(gamestate, temp, false, true);
|
||||
// gamestate.starting_pos = temp;
|
||||
LOG_G << "generated map\n";
|
||||
}
|
||||
|
||||
sound::empty_playlist();
|
||||
|
||||
//add the variables to the starting_pos unless they are already there
|
||||
const config &wmlvars = gamestate.starting_pos.child("variables");
|
||||
const config &wmlvars = gamestate.replay_start().child("variables");
|
||||
if (!wmlvars || wmlvars.empty()){
|
||||
gamestate.starting_pos.clear_children("variables");
|
||||
gamestate.starting_pos.add_child("variables", gamestate.carryover_sides.child_or_empty("variables"));
|
||||
gamestate.replay_start().clear_children("variables");
|
||||
gamestate.replay_start().add_child("variables", gamestate.carryover_sides_start.child_or_empty("variables"));
|
||||
}
|
||||
|
||||
switch (io_type){
|
||||
|
@ -519,6 +534,7 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
|
||||
recorder.clear();
|
||||
gamestate.replay_data.clear();
|
||||
gamestate.replay_start().clear();
|
||||
|
||||
// On DEFEAT, QUIT, or OBSERVER_END, we're done now
|
||||
if (res != VICTORY)
|
||||
|
@ -545,7 +561,10 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
|
||||
// Switch to the next scenario.
|
||||
gamestate.classification().scenario = gamestate.classification().next_scenario;
|
||||
|
||||
sides = carryover_info(gamestate.carryover_sides_start);
|
||||
sides.rng().rotate_random();
|
||||
gamestate.carryover_sides_start = sides.to_config();
|
||||
|
||||
if(io_type == IO_CLIENT) {
|
||||
if (gamestate.classification().next_scenario.empty()) {
|
||||
|
@ -619,7 +638,8 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
scenario2 = random_generate_scenario((*scenario)["scenario_generation"], scenario->child("generator"));
|
||||
//TODO comment or remove
|
||||
//level_ = scenario;
|
||||
gamestate.starting_pos = scenario2;
|
||||
//TODO: remove once replay_start is confirmed
|
||||
//gamestate.starting_pos = scenario2;
|
||||
scenario = &scenario2;
|
||||
}
|
||||
std::string map_data = (*scenario)["map_data"];
|
||||
|
@ -639,8 +659,8 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
map["usage"] = "map";
|
||||
map["border_size"] = 1;
|
||||
scenario = &new_level;
|
||||
|
||||
gamestate.starting_pos = new_level;
|
||||
//TODO: remove once replay_start is confirmed
|
||||
//gamestate.starting_pos = new_level;
|
||||
LOG_G << "generated map\n";
|
||||
}
|
||||
|
||||
|
@ -655,14 +675,14 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
next_cfg.add_child("snapshot");
|
||||
//move the player information into the hosts gamestate
|
||||
write_players(gamestate, starting_pos, true, true);
|
||||
gamestate.starting_pos = *scenario;
|
||||
|
||||
next_cfg.add_child("multiplayer", gamestate.mp_settings().to_config());
|
||||
next_cfg.add_child("replay_start", gamestate.starting_pos);
|
||||
next_cfg.add_child("replay_start", gamestate.replay_start());
|
||||
//move side information from gamestate into the config that is sent to the other clients
|
||||
next_cfg.clear_children("side");
|
||||
BOOST_FOREACH(config& side, gamestate.starting_pos.child_range("side"))
|
||||
BOOST_FOREACH(config& side, starting_pos.child_range("side")){
|
||||
next_cfg.add_child("side", side);
|
||||
}
|
||||
|
||||
network::send_data(cfg, 0);
|
||||
}
|
||||
|
@ -687,30 +707,30 @@ LEVEL_RESULT play_game(display& disp, game_state& gamestate, const config& game_
|
|||
// start-of-scenario save and the
|
||||
// starting position needs to be empty,
|
||||
// to force a reload of the scenario config.
|
||||
if (gamestate.classification().campaign_type != "multiplayer"){
|
||||
gamestate.starting_pos = config();
|
||||
}
|
||||
|
||||
//TODO: remove once replay_start is confirmed
|
||||
//if (gamestate.classification().campaign_type != "multiplayer"){
|
||||
// gamestate.starting_pos = config();
|
||||
//}
|
||||
//add the variables to the starting position
|
||||
gamestate.starting_pos.add_child("variables", sides.get_variables());
|
||||
//gamestate.starting_pos.add_child("variables", sides.get_variables());
|
||||
|
||||
savegame::scenariostart_savegame save(gamestate, preferences::compress_saves());
|
||||
|
||||
save.save_game_automatic(disp.video());
|
||||
}
|
||||
|
||||
if (gamestate.classification().campaign_type != "multiplayer"){
|
||||
gamestate.starting_pos = *scenario;
|
||||
//add the variables to the starting position
|
||||
gamestate.starting_pos.add_child("variables", sides.get_variables());
|
||||
write_players(gamestate, gamestate.starting_pos, true, true);
|
||||
}
|
||||
//TODO: remove once replay_start is confirmed
|
||||
// if (gamestate.classification().campaign_type != "multiplayer"){
|
||||
// gamestate.starting_pos = *scenario;
|
||||
// //add the variables to the starting position
|
||||
// gamestate.starting_pos.add_child("variables", sides.get_variables());
|
||||
// write_players(gamestate, gamestate.starting_pos, true, true);
|
||||
// }
|
||||
}
|
||||
gamestate.snapshot = config();
|
||||
}
|
||||
|
||||
gamestate.carryover_sides = sides.to_config();
|
||||
|
||||
if (!gamestate.classification().scenario.empty() && gamestate.classification().scenario != "null") {
|
||||
std::string message = _("Unknown scenario: '$scenario|'");
|
||||
utils::string_map symbols;
|
||||
|
|
|
@ -53,6 +53,9 @@ static lg::log_domain log_engine("engine");
|
|||
#define ERR_NG LOG_STREAM(err, log_engine)
|
||||
#define LOG_NG LOG_STREAM(info, log_engine)
|
||||
|
||||
static lg::log_domain log_enginerefac("enginerefac");
|
||||
#define LOG_RG LOG_STREAM(info, log_enginerefac)
|
||||
|
||||
playsingle_controller::playsingle_controller(const config& level,
|
||||
game_state& state_of_game, const int ticks, const int num_turns,
|
||||
const config& game_config, CVideo& video, bool skip_replay) :
|
||||
|
@ -381,6 +384,12 @@ LEVEL_RESULT playsingle_controller::play_scenario(
|
|||
throw end_level_exception(SKIP_TO_LINGER);
|
||||
}
|
||||
|
||||
//before first turn, save a snapshot as replay_start
|
||||
if(gamestate_.snapshot.empty()){
|
||||
gamestate_.write_snapshot(gamestate_.replay_start(), gui_.get());
|
||||
gamestate_.replay_start().merge_with(to_config());
|
||||
}
|
||||
|
||||
// Avoid autosaving after loading, but still
|
||||
// allow the first turn to have an autosave.
|
||||
bool save = !loading_game_;
|
||||
|
@ -526,7 +535,7 @@ LEVEL_RESULT playsingle_controller::play_scenario(
|
|||
disconnect = true;
|
||||
}
|
||||
|
||||
savegame::game_savegame save(gamestate_, *gui_, to_config(), preferences::compress_saves());
|
||||
savegame::ingame_savegame save(gamestate_, *gui_, to_config(), preferences::compress_saves());
|
||||
save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO);
|
||||
if(disconnect) {
|
||||
throw network::error();
|
||||
|
@ -879,121 +888,6 @@ void playsingle_controller::check_time_over(){
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: remove store_recalls() and store_gold() once everything is moved and works correctly
|
||||
|
||||
//void playsingle_controller::store_recalls() {
|
||||
// std::set<std::string> side_ids;
|
||||
// std::vector<team>::iterator i;
|
||||
// for(i=teams_.begin(); i!=teams_.end(); ++i) {
|
||||
// side_ids.insert(i->save_id());
|
||||
// if (i->persistent()) {
|
||||
// config& new_side = gamestate_.snapshot.add_child("side");
|
||||
// new_side["save_id"] = i->save_id();
|
||||
// new_side["name"] = i->current_player();
|
||||
// std::stringstream can_recruit;
|
||||
// std::copy(i->recruits().begin(),i->recruits().end(),std::ostream_iterator<std::string>(can_recruit,","));
|
||||
// std::string can_recruit_str = can_recruit.str();
|
||||
// // Remove the trailing comma
|
||||
// if(can_recruit_str.empty() == false) {
|
||||
// can_recruit_str.resize(can_recruit_str.size()-1);
|
||||
// }
|
||||
// new_side["previous_recruits"] = can_recruit_str;
|
||||
// LOG_NG << "stored side in snapshot:\n" << new_side["save_id"] << std::endl;
|
||||
// //add the units of the recall list
|
||||
// BOOST_FOREACH(const unit& u, i->recall_list()) {
|
||||
// config& new_unit = new_side.add_child("unit");
|
||||
// u.write(new_unit);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //add any players from starting_pos that do not have a team in the current scenario
|
||||
// BOOST_FOREACH(const config &player_cfg, gamestate_.starting_pos.child_range("player")) {
|
||||
// if (side_ids.count(player_cfg["save_id"]) == 0) {
|
||||
// LOG_NG << "stored inactive side in snapshot:\n" << player_cfg["save_id"] << std::endl;
|
||||
// gamestate_.snapshot.add_child("side", player_cfg);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void playsingle_controller::store_gold(bool obs)
|
||||
//{
|
||||
// bool has_next_scenario = !gamestate_.classification().next_scenario.empty() &&
|
||||
// gamestate_.classification().next_scenario != "null";
|
||||
//
|
||||
// std::ostringstream report;
|
||||
// std::string title;
|
||||
//
|
||||
// if (obs) {
|
||||
// title = _("Scenario Report");
|
||||
// } else {
|
||||
// persist_.end_transaction();
|
||||
// title = _("Victory");
|
||||
// report << "<b>" << _("You have emerged victorious!") << "</b>\n\n";
|
||||
// }
|
||||
//
|
||||
// int persistent_teams = 0;
|
||||
// BOOST_FOREACH(const team &t, teams_) {
|
||||
// if (t.persistent()) ++persistent_teams;
|
||||
// }
|
||||
//
|
||||
// const end_level_data &end_level = get_end_level_data_const();
|
||||
//
|
||||
// if (persistent_teams > 0 && (has_next_scenario ||
|
||||
// gamestate_.classification().campaign_type == "test"))
|
||||
// {
|
||||
// int finishing_bonus_per_turn =
|
||||
// map_.villages().size() * game_config::village_income +
|
||||
// game_config::base_income;
|
||||
// int turns_left = std::max<int>(0, tod_manager_.number_of_turns() - turn());
|
||||
// int finishing_bonus = (end_level.gold_bonus && turns_left > -1) ?
|
||||
// finishing_bonus_per_turn * turns_left : 0;
|
||||
// BOOST_FOREACH(const team &t, teams_)
|
||||
// {
|
||||
// if (!t.persistent()) continue;
|
||||
// int carryover_gold = div100rounded((t.gold() + finishing_bonus) * end_level.carryover_percentage);
|
||||
// config::child_itors side_range = gamestate_.snapshot.child_range("side");
|
||||
// config::child_iterator side_it = side_range.first;
|
||||
//
|
||||
// // Check if this side already exists in the snapshot.
|
||||
// while (side_it != side_range.second) {
|
||||
// if ((*side_it)["save_id"] == t.save_id()) {
|
||||
// (*side_it)["gold"] = str_cast<int>(carryover_gold);
|
||||
// (*side_it)["gold_add"] = end_level.carryover_add;
|
||||
// (*side_it)["color"] = t.color();
|
||||
// (*side_it)["current_player"] = t.current_player();
|
||||
// (*side_it)["name"] = t.name();
|
||||
// break;
|
||||
// }
|
||||
// ++side_it;
|
||||
// }
|
||||
//
|
||||
// // If it doesn't, add a new child.
|
||||
// if (side_it == side_range.second) {
|
||||
// config &new_side = gamestate_.snapshot.add_child("side");
|
||||
// new_side["save_id"] = t.save_id();
|
||||
// new_side["gold"] = str_cast<int>(carryover_gold);
|
||||
// new_side["gold_add"] = end_level.carryover_add;
|
||||
// new_side["color"] = t.color();
|
||||
// new_side["current_player"] = t.current_player();
|
||||
// new_side["name"] = t.name();
|
||||
// }
|
||||
//
|
||||
// // Only show the report for ourselves.
|
||||
// if (!t.is_human()) continue;
|
||||
//
|
||||
// if (persistent_teams > 1) {
|
||||
// report << "\n<b>" << t.current_player() << "</b>\n";
|
||||
// }
|
||||
//
|
||||
// report_victory(report, carryover_gold, t.gold(), finishing_bonus_per_turn, turns_left, finishing_bonus);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (end_level.carryover_report) {
|
||||
// gui2::show_transient_message(gui_->video(), title, report.str(), "", true);
|
||||
// }
|
||||
//}
|
||||
|
||||
bool playsingle_controller::can_execute_command(hotkey::HOTKEY_COMMAND command, int index) const
|
||||
{
|
||||
bool res = true;
|
||||
|
|
|
@ -684,6 +684,7 @@ void loadgame::check_version_compatibility()
|
|||
|
||||
void loadgame::set_gamestate()
|
||||
{
|
||||
convert_old_saves(load_config_);
|
||||
gamestate_ = game_state(load_config_, show_replay_);
|
||||
|
||||
// Get the status of the random in the snapshot.
|
||||
|
@ -692,13 +693,13 @@ void loadgame::set_gamestate()
|
|||
// For normal loading also restore the call count.
|
||||
int seed = load_config_["random_seed"].to_int(42);
|
||||
if(seed == 42){
|
||||
config cfg = load_config_.child_or_empty("carryover_sides");
|
||||
config cfg = load_config_.child_or_empty("carryover_sides_start");
|
||||
seed = cfg["random_seed"].to_int(42);
|
||||
}
|
||||
unsigned calls = show_replay_ ? 0 : gamestate_.snapshot["random_calls"].to_int();
|
||||
carryover_info sides(gamestate_.carryover_sides);
|
||||
carryover_info sides(gamestate_.carryover_sides_start);
|
||||
sides.rng().seed_random(seed, calls);
|
||||
gamestate_.carryover_sides = sides.to_config();
|
||||
gamestate_.carryover_sides_start = sides.to_config();
|
||||
}
|
||||
|
||||
void loadgame::load_multiplayer_game()
|
||||
|
@ -739,7 +740,7 @@ void loadgame::fill_mplevel_config(config& level){
|
|||
|
||||
// If we have a start of scenario MP campaign scenario the snapshot
|
||||
// is empty the starting position contains the wanted info.
|
||||
const config& start_data = !gamestate_.snapshot.empty() ? gamestate_.snapshot : gamestate_.starting_pos;
|
||||
const config& start_data = !gamestate_.snapshot.empty() ? gamestate_.snapshot : gamestate_.replay_start();
|
||||
|
||||
level.add_child("map", start_data.child_or_empty("map"));
|
||||
level["id"] = start_data["id"];
|
||||
|
@ -764,7 +765,7 @@ void loadgame::fill_mplevel_config(config& level){
|
|||
level.add_child("snapshot") = config();
|
||||
} else {
|
||||
level.add_child("snapshot") = start_data;
|
||||
level.add_child("replay_start") = gamestate_.starting_pos;
|
||||
level.add_child("replay_start") = gamestate_.replay_start();
|
||||
}
|
||||
level["random_seed"] = start_data["random_seed"];
|
||||
level["random_calls"] = start_data["random_calls"];
|
||||
|
@ -792,7 +793,6 @@ void loadgame::copy_era(config &cfg)
|
|||
savegame::savegame(game_state& gamestate, const bool compress_saves, const std::string& title)
|
||||
: gamestate_(gamestate)
|
||||
, snapshot_()
|
||||
, carryover_sides_(gamestate.carryover_sides)
|
||||
, filename_()
|
||||
, title_(title)
|
||||
, error_message_(_("The game could not be saved: "))
|
||||
|
@ -995,15 +995,14 @@ void savegame::write_game_to_disk(const std::string& filename)
|
|||
}
|
||||
}
|
||||
|
||||
void savegame::write_game(config_writer &out) const
|
||||
void savegame::write_game(config_writer &out)
|
||||
{
|
||||
log_scope("write_game");
|
||||
|
||||
out.write_key_val("version", game_config::version);
|
||||
out.write_key_val("next_underlying_unit_id", lexical_cast<std::string>(n_unit::id_manager::instance().get_save_id()));
|
||||
gamestate_.write_config(out, false);
|
||||
out.write_child("snapshot",snapshot_);
|
||||
out.write_child("carryover_sides",carryover_sides_);
|
||||
|
||||
gamestate_.write_config(out);
|
||||
out.open_child("statistics");
|
||||
statistics::write_stats(out);
|
||||
out.close_child("statistics");
|
||||
|
@ -1040,18 +1039,10 @@ scenariostart_savegame::scenariostart_savegame(game_state &gamestate, const bool
|
|||
set_filename(gamestate.classification().label);
|
||||
}
|
||||
|
||||
void scenariostart_savegame::before_save()
|
||||
{
|
||||
//Add the player section to the starting position so we can get the correct recall list
|
||||
//when loading the replay later on
|
||||
// if there is no scenario information in the starting pos, add the (persistent) sides from the snapshot
|
||||
// else do nothing, as persistence information was already added at the end of the previous scenario
|
||||
if (gamestate().starting_pos["id"].empty()) {
|
||||
BOOST_FOREACH(const config &snapshot_side, gamestate().snapshot.child_range("side")) {
|
||||
//add all side tags (assuming they only contain carryover information)
|
||||
gamestate().starting_pos.add_child("side", snapshot_side);
|
||||
}
|
||||
}
|
||||
void scenariostart_savegame::write_game(config_writer &out){
|
||||
savegame::write_game(out);
|
||||
|
||||
out.write_child("carryover_sides_start", gamestate().carryover_sides_start);
|
||||
}
|
||||
|
||||
replay_savegame::replay_savegame(game_state &gamestate, const bool compress_saves)
|
||||
|
@ -1069,9 +1060,18 @@ void replay_savegame::create_filename()
|
|||
set_filename(stream.str());
|
||||
}
|
||||
|
||||
void replay_savegame::write_game(config_writer &out) {
|
||||
savegame::write_game(out);
|
||||
|
||||
out.write_child("carryover_sides_start", gamestate().carryover_sides_start);
|
||||
out.write_child("carryover_sides", gamestate().carryover_sides);
|
||||
out.write_child("replay_start", gamestate().replay_start());
|
||||
out.write_child("replay", gamestate().replay_data);
|
||||
}
|
||||
|
||||
autosave_savegame::autosave_savegame(game_state &gamestate,
|
||||
game_display& gui, const config& snapshot_cfg, const bool compress_saves)
|
||||
: game_savegame(gamestate, gui, snapshot_cfg, compress_saves)
|
||||
: ingame_savegame(gamestate, gui, snapshot_cfg, compress_saves)
|
||||
{
|
||||
set_error_message(_("Could not auto save the game. Please save the game manually."));
|
||||
}
|
||||
|
@ -1098,7 +1098,7 @@ void autosave_savegame::create_filename()
|
|||
}
|
||||
|
||||
oos_savegame::oos_savegame(const config& snapshot_cfg)
|
||||
: game_savegame(*resources::state_of_game, *resources::screen, snapshot_cfg, preferences::compress_saves())
|
||||
: ingame_savegame(*resources::state_of_game, *resources::screen, snapshot_cfg, preferences::compress_saves())
|
||||
{}
|
||||
|
||||
int oos_savegame::show_save_dialog(CVideo& video, const std::string& message, const gui::DIALOG_TYPE /*dialog_type*/)
|
||||
|
@ -1120,7 +1120,7 @@ int oos_savegame::show_save_dialog(CVideo& video, const std::string& message, co
|
|||
return res;
|
||||
}
|
||||
|
||||
game_savegame::game_savegame(game_state &gamestate,
|
||||
ingame_savegame::ingame_savegame(game_state &gamestate,
|
||||
game_display& gui, const config& snapshot_cfg, const bool compress_saves)
|
||||
: savegame(gamestate, compress_saves, _("Save Game")),
|
||||
gui_(gui)
|
||||
|
@ -1128,7 +1128,7 @@ game_savegame::game_savegame(game_state &gamestate,
|
|||
snapshot().merge_with(snapshot_cfg);
|
||||
}
|
||||
|
||||
void game_savegame::create_filename()
|
||||
void ingame_savegame::create_filename()
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
||||
|
@ -1138,24 +1138,21 @@ void game_savegame::create_filename()
|
|||
set_filename(stream.str());
|
||||
}
|
||||
|
||||
void game_savegame::before_save()
|
||||
void ingame_savegame::before_save()
|
||||
{
|
||||
savegame::before_save();
|
||||
write_game_snapshot();
|
||||
gamestate().write_snapshot(snapshot(), &gui_);
|
||||
}
|
||||
|
||||
void game_savegame::write_game_snapshot()
|
||||
{
|
||||
snapshot()["snapshot"] = true;
|
||||
snapshot()["playing_team"] = str_cast(gui_.playing_team());
|
||||
void ingame_savegame::write_game(config_writer &out) {
|
||||
log_scope("write_game");
|
||||
|
||||
write_events(snapshot());
|
||||
|
||||
write_music_play_list(snapshot());
|
||||
|
||||
gamestate().write_snapshot(snapshot());
|
||||
|
||||
gui_.labels().write(snapshot());
|
||||
savegame::write_game(out);
|
||||
out.write_child("snapshot",snapshot());
|
||||
out.write_child("replay_start", gamestate().replay_start());
|
||||
out.write_child("carryover_sides", gamestate().carryover_sides);
|
||||
out.write_child("carryover_sides_start", gamestate().carryover_sides_start);
|
||||
out.write_child("replay", gamestate().replay_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -167,14 +167,16 @@ protected:
|
|||
/** Customize the standard error message */
|
||||
void set_error_message(const std::string& error_message) { error_message_ = error_message; }
|
||||
|
||||
const std::string& title() const { return title_; }
|
||||
game_state& gamestate() const { return gamestate_; }
|
||||
const std::string& title() { return title_; }
|
||||
game_state& gamestate() { return gamestate_; }
|
||||
config& snapshot() { return snapshot_; }
|
||||
config& carryover_sides() { return carryover_sides_; }
|
||||
|
||||
/** If there needs to be some data fiddling before saving the game, this is the place to go. */
|
||||
virtual void before_save();
|
||||
|
||||
/** Writing the savegame config to a file. */
|
||||
virtual void write_game(config_writer &out);
|
||||
|
||||
private:
|
||||
/** Checks if a certain character is allowed in a savefile name. */
|
||||
static bool is_illegal_file_char(char c);
|
||||
|
@ -191,8 +193,6 @@ private:
|
|||
data manipulation has to happen before calling this method. */
|
||||
void write_game_to_disk(const std::string& filename);
|
||||
|
||||
/** Writing the savegame config to a file. */
|
||||
void write_game(config_writer &out) const;
|
||||
/** Update the save_index */
|
||||
void finish_save_game(const config_writer &out);
|
||||
/** Throws game::save_game_failed. */
|
||||
|
@ -205,8 +205,6 @@ private:
|
|||
even if it is empty the code relies on it to be there. */
|
||||
config snapshot_;
|
||||
|
||||
config carryover_sides_;
|
||||
|
||||
std::string filename_; /** Filename of the savegame file on disk */
|
||||
|
||||
const std::string title_; /** Title of the savegame dialog */
|
||||
|
@ -220,10 +218,10 @@ private:
|
|||
|
||||
/** Class for "normal" midgame saves. The additional members are needed for creating the snapshot
|
||||
information. */
|
||||
class game_savegame : public savegame
|
||||
class ingame_savegame : public savegame
|
||||
{
|
||||
public:
|
||||
game_savegame(game_state& gamestate,
|
||||
ingame_savegame(game_state& gamestate,
|
||||
game_display& gui, const config& snapshot_cfg, const bool compress_saves);
|
||||
|
||||
private:
|
||||
|
@ -233,8 +231,7 @@ private:
|
|||
/** Builds the snapshot config. */
|
||||
virtual void before_save();
|
||||
|
||||
/** For normal game saves. Builds a snapshot config object out of the relevant information. */
|
||||
void write_game_snapshot();
|
||||
void write_game(config_writer &out);
|
||||
|
||||
protected:
|
||||
game_display& gui_;
|
||||
|
@ -249,10 +246,12 @@ public:
|
|||
private:
|
||||
/** Create a filename for automatic saves */
|
||||
virtual void create_filename();
|
||||
|
||||
void write_game(config_writer &out);
|
||||
};
|
||||
|
||||
/** Class for autosaves. */
|
||||
class autosave_savegame : public game_savegame
|
||||
class autosave_savegame : public ingame_savegame
|
||||
{
|
||||
public:
|
||||
autosave_savegame(game_state &gamestate,
|
||||
|
@ -264,7 +263,7 @@ private:
|
|||
virtual void create_filename();
|
||||
};
|
||||
|
||||
class oos_savegame : public game_savegame
|
||||
class oos_savegame : public ingame_savegame
|
||||
{
|
||||
public:
|
||||
oos_savegame(const config& snapshot_cfg);
|
||||
|
@ -281,8 +280,7 @@ public:
|
|||
scenariostart_savegame(game_state& gamestate, const bool compress_saves);
|
||||
|
||||
private:
|
||||
/** Adds the player information to the starting position (= [replay_start]). */
|
||||
virtual void before_save();
|
||||
void write_game(config_writer &out);
|
||||
};
|
||||
|
||||
} //end of namespace savegame
|
||||
|
|
Loading…
Add table
Reference in a new issue