The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
saved_game.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by the Battle for Wesnoth Project http://www.wesnoth.org/
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY.
10 
11  See the COPYING file for more details.
12 */
13 
14 /**
15  Some information about savefiles:
16  A saveile can contain:
17  * General information (toplevel atributes, [multiplayer])
18  This is present in all savefiles
19  * [statistics]
20  This is present in all savefiles but it's not handled by playcampaign/play_controller/saved_game.
21  It's handled by savegame.cpp
22  * [snapshot]
23  If a savegame was saved during a scenario this contains a snapshot of the game at the point when it was saved.
24  * [carryover_sides_start]
25  At start-of-scenrio saves this contains data from the previous scenario that was preserved
26  * [carryover_sides]
27  In savefile made during the game, this tag contains data from [carryover_sides_start] that was not used in the current scenario but should be saved for a next scenario
28  * [replay_start]
29  A snapshot made very early to replay the game from.
30  * [replay]
31  A record of game actions that was made between the creation of [replay_start] and [snapshot].
32 
33 
34 
35  The following types of savegames are known:
36  * Start of scenario savefiles
37  These files only contain general information, statistics, and [carryover_sides_start]
38  When these saves are loaded, the scenario data is loaded form the game config using the next_scenario attribute from [carryover_sides_start]
39  * Expanded Start of scenario savefiles
40  Similar to normal Start-of-scenario savefiles, but the also contain a [scenario] that contains the scenario data.
41  This type is only used internally and usually doesn't get written to the disk.
42  * Ingame savefile
43  These files contain general information, statistics, [snapshot], [replay], [replay_start], [snapshot], [carryover_sides]
44  These files don't contain a [carryover_sides_start] because both starting points ([replay_start] and [snapshot])
45  were made after [carryover_sides_start] was merged into the scenario.
46  * Replay savefiles
47  Like a Ingame save made during linger mode, but without the [snapshot]
48 */
49 
50 #include "saved_game.hpp"
51 #include "carryover.hpp"
52 #include "config_assign.hpp"
53 #include "cursor.hpp"
54 #include "log.hpp"
55 #include "game_config_manager.hpp"
57 #include "statistics.hpp"
59 #include "util.hpp"
60 #include "variable_info.hpp"
61 #include "formula/string_utils.hpp"
62 #include "config.hpp" //Also for variable_set
63 
64 #include <boost/range/adaptors.hpp>
65 #include <boost/range/algorithm/copy.hpp>
66 #include <cassert>
67 
68 static lg::log_domain log_engine("engine");
69 #define ERR_NG LOG_STREAM(err, log_engine)
70 #define WRN_NG LOG_STREAM(warn, log_engine)
71 #define LOG_NG LOG_STREAM(info, log_engine)
72 #define DBG_NG LOG_STREAM(debug, log_engine)
73 
75  : has_carryover_expanded_(false)
76  , carryover_(carryover_info().to_config())
77  , replay_start_()
78  , classification_()
79  , mp_settings_()
80  , starting_pos_type_(STARTINGPOS_NONE)
81  , starting_pos_()
82  , replay_data_()
83 {
84 
85 }
86 
88  : has_carryover_expanded_(false)
89  , carryover_()
90  , replay_start_()
91  , classification_(cfg)
92  , mp_settings_()
93  , starting_pos_type_(STARTINGPOS_NONE)
94  , starting_pos_()
95  , replay_data_()
96 
97 {
98  set_data(cfg);
99 }
100 
102  : has_carryover_expanded_(state.has_carryover_expanded_)
103  , carryover_(state.carryover_)
104  , replay_start_(state.replay_start_)
105  , classification_(state.classification_)
106  , mp_settings_(state.mp_settings_)
107  , starting_pos_type_(state.starting_pos_type_)
108  , starting_pos_(state.starting_pos_)
109  , replay_data_(state.replay_data_)
110 {
111 }
112 
114 {
115  carryover_.swap(carryover_sides_start);
116  has_carryover_expanded_ = false;
117 }
118 
120 {
121  if(has_carryover_expanded_ || !carryover_["random_seed"].empty())
122  {
123  return;
124  }
125  carryover_["random_seed"] = rand();
126  carryover_["random_calls"] = 0;
127 }
128 
130 {
131  write_general_info(out);
132  write_starting_pos(out);
133  if(!this->replay_start_.empty())
134  {
135  out.write_child("replay_start", replay_start_);
136  }
137  out.open_child("replay");
138  replay_data_.write(out);
139  out.close_child("replay");
140  write_carryover(out);
141 }
142 
144 {
146  {
147  out.write_child("snapshot", starting_pos_);
148  }
150  {
151  out.write_child("scenario", starting_pos_);
152  }
153 }
155 {
156  assert(not_corrupt());
157  out.write_child(has_carryover_expanded_ ? "carryover_sides" : "carryover_sides_start", carryover_);
158 }
159 
160 
162 {
164  out.write_child("multiplayer", mp_settings_.to_config());
165 }
166 
168 {
169  const bool is_loaded_game = this->starting_pos_type_ != STARTINGPOS_SCENARIO;
170  const bool is_multiplayer_tag = classification().get_tagname() == "multiplayer";
171  static const std::vector<std::string> team_defaults = {
172  "carryover_percentage",
173  "carryover_add",
174  };
175  for(config& side : starting_pos_.child_range("side"))
176  {
177  // Set save_id default value directly after loading to its default to prevent different default behaviour in mp_connect code and sp code.
178  if(side["save_id"].empty())
179  {
180  side["save_id"] = side["id"];
181  }
182  if(!is_multiplayer_tag && side["side_name"].blank())
183  {
184  side["side_name"] = side["name"];
185  }
186  if(!is_loaded_game && !side["current_player"].empty())
187  {
188  ERR_NG << "Removed invalid 'current_player' attribute from [side] while loading a scenario. Consider using 'side_name' instead\n";
189  side["current_player"] = config::attribute_value();
190  }
191  // Set some team specific values to their defaults specified in scenario
192  for(const std::string& att_name : team_defaults)
193  {
194  const config::attribute_value* scenario_value = starting_pos_.get(att_name);
195  config::attribute_value& team_value = side[att_name];
196  if(scenario_value && team_value.empty())
197  {
198  team_value = *scenario_value;
199  }
200  }
201  }
202 }
203 
205 {
207  {
210  const config& scenario = game_config.find_child(classification().get_tagname(), "id", carryover_["next_scenario"]);
211  if(scenario)
212  {
214  this->starting_pos_ = scenario;
215  // A hash has to be generated using an unmodified scenario data.
216  mp_settings_.hash = scenario.hash();
217 
218  // Add addon_id information if it exists.
219  if (!scenario["addon_id"].empty() && scenario["require_scenario"].to_bool(false)) {
220  mp_settings_.update_addon_requirements(config_of("id",scenario["addon_id"])("version", scenario["addon_version"])("min_version", scenario["addon_min_version"]));
221  }
222 
223  update_label();
224  set_defaults();
225  }
226  else
227  {
229  this->starting_pos_ = config();
230  }
231  }
232 }
233 namespace
234 {
235  struct config_variable_set : public variable_set
236  {
237  const config& cfg_;
238  config_variable_set(const config& cfg) : cfg_(cfg) {}
240  {
241  try
242  {
244  return variable.as_scalar();
245  }
246  catch(const invalid_variablename_exception&)
247  {
248  ERR_NG << "invalid variablename " << id << "\n";
249  return config::attribute_value();
250  }
251  };
252  };
253 
254  bool variable_to_bool(const config& vars, const std::string& expression)
255  {
256  std::string res = utils::interpolate_variables_into_string(expression, config_variable_set(vars));
257  return res == "true" || res == "yes" || res == "1";
258  }
259 
260  //helper objects for saved_game::expand_mp_events()
261  struct modevents_entry
262  {
263  modevents_entry(const std::string& _type, const std::string& _id) : type(_type), id(_id) {}
265  std::string id;
266  };
267  struct modevents_entry_for
268  {
269  //this typedef is used by boost.
270  typedef modevents_entry result_type;
271  modevents_entry_for(const std::string& type ) : type_(type) {}
272  modevents_entry operator()(const std::string& id) const
273  {
274  return modevents_entry(type_, id);
275  }
276  private:
277  std::string type_;
278  };
279 }
280 
282 {
283  if(const config& cfg = game_config_manager::get()->
284  game_config().find_child(type, "id", id))
285  {
286  // Note the addon_id if this mod is required to play the game in mp
287  std::string require_attr = "require_" + type;
288  bool require_default = (type == "era"); // By default, eras have "require_era = true", and mods have "require_modification = false"
289  if (!cfg["addon_id"].empty() && cfg[require_attr].to_bool(require_default)) {
290  mp_settings_.update_addon_requirements(config_of("id",cfg["addon_id"])("version", cfg["addon_version"])("min_version", cfg["addon_min_version"]));
291  }
292 
293  // Copy events
294  for(const config& modevent : cfg.child_range("event"))
295  {
296  if(modevent["enable_if"].empty() || variable_to_bool(carryover_.child_or_empty("variables"), modevent["enable_if"]))
297  {
298  this->starting_pos_.add_child("event", modevent);
299  }
300  }
301  // Copy lua
302  for(const config& modlua : cfg.child_range("lua"))
303  {
304  this->starting_pos_.add_child("lua", modlua);
305  }
306  // Copy load_resource
307  for(const config& load_resource : cfg.child_range("load_resource"))
308  {
309  this->starting_pos_.add_child("load_resource", load_resource);
310  }
311  }
312  else
313  {
314  //TODO: A user message instead?
315  ERR_NG << "Couldn't find [" << type<< "] with id=" << id <<std::endl;
316  }
317 }
318 
319 // Gets the ids of the mp_era and modifications which were set to be active, then fetches these configs from the game_config and copies their [event] and [lua] to the starting_pos_.
320 // At this time, also collect the addon_id attributes which appeared in them and put this list in the addon_ids attribute of the mp_settings.
322 {
323  expand_scenario();
324  if(this->starting_pos_type_ == STARTINGPOS_SCENARIO && !this->starting_pos_["has_mod_events"].to_bool(false))
325  {
326  std::vector<modevents_entry> mods;
327  std::set<std::string> loaded_resources;
328  boost::copy( mp_settings_.active_mods
329  | boost::adaptors::transformed(modevents_entry_for("modification"))
330  , std::back_inserter(mods) );
331  if(mp_settings_.mp_era != "") //We don't want the error message below if there is no era (= if this is a sp game)
332  { mods.push_back(modevents_entry("era", mp_settings_.mp_era)); }
333  if(classification_.campaign != "")
334  { mods.push_back(modevents_entry("campaign", classification_.campaign)); }
335 
336  // In the first iteration mod contains no [resource]s in all other iterations, mods contains only [resource]s
337  do {
338  for(modevents_entry& mod : mods)
339  {
340  load_mod(mod.type, mod.id);
341  }
342  mods.clear();
343  for(const config& cfg : starting_pos_.child_range("load_resource"))
344  {
345  if(loaded_resources.find(cfg["id"].str()) == loaded_resources.end()) {
346  mods.push_back(modevents_entry("resource", cfg["id"].str()));
347  loaded_resources.insert(cfg["id"].str());
348  }
349  }
350  starting_pos_.clear_children("load_resource");
351  } while(!mods.empty());
352  this->starting_pos_["has_mod_events"] = true;
353  }
354 }
355 
357 {
359  {
360  std::vector<modevents_entry> mods;
361 
362  boost::copy( mp_settings_.active_mods
363  | boost::adaptors::transformed(modevents_entry_for("modification"))
364  , std::back_inserter(mods) );
365  mods.push_back(modevents_entry("era", mp_settings_.mp_era));
366  mods.push_back(modevents_entry("multiplayer", get_scenario_id()));
367  mods.push_back(modevents_entry("campaign", classification().campaign));
368 
369  config& variables = carryover_.child_or_add("variables");
370  for(modevents_entry& mod : mods)
371  {
372  if(const config& cfg = this->mp_settings().options.find_child(mod.type, "id", mod.id))
373  {
374  for(const config& option : cfg.child_range("option"))
375  {
376  variables[option["id"]] = option["value"];
377  }
378  }
379  else
380  {
381  LOG_NG << "Couldn't find [" << mod.type<< "] with id=" << mod.id << " for [option]s" << std::endl;
382  }
383  }
384  }
385 }
386 
388 {
389  expand_scenario();
391  {
392  // If the entire scenario should be randomly generated
393  if(!starting_pos_["scenario_generation"].empty())
394  {
395  LOG_NG << "randomly generating scenario...\n";
396  const cursor::setter cursor_setter(cursor::WAIT);
397 
398  config scenario_new = random_generate_scenario(starting_pos_["scenario_generation"],
399  starting_pos_.child("generator"));
400  //Preserve "story" form the scenario toplevel.
401  for(config& story : starting_pos_.child_range("story"))
402  {
403  scenario_new.add_child("story", story);
404  }
405  scenario_new["id"] = starting_pos_["id"];
406  starting_pos_ = scenario_new;
407  update_label();
408  set_defaults();
409  }
410 
411  // If no map_data is provided, try to load the specified file directly
412  if(starting_pos_["map_data"].empty() && !starting_pos_["map_file"].empty()) {
413  starting_pos_["map_data"] = filesystem::read_map(starting_pos_["map_file"]);
414  }
415 
416  // If the map should be randomly generated
417  // We don’t want that we accidentally to this twice so we check for starting_pos_["map_data"].empty()
418  if(starting_pos_["map_data"].empty() && !starting_pos_["map_generation"].empty()) {
419  LOG_NG << "randomly generating map...\n";
420  const cursor::setter cursor_setter(cursor::WAIT);
421 
422  starting_pos_["map_data"] = random_generate_map(
423  starting_pos_["map_generation"], starting_pos_.child("generator"));
424  }
425  }
426 }
427 
429 {
430  expand_scenario();
432  {
433  carryover_info sides(carryover_);
434 
435  sides.transfer_to(get_starting_pos());
436  for(config& side_cfg : get_starting_pos().child_range("side"))
437  {
438  sides.transfer_all_to(side_cfg);
439  }
440 
441  carryover_ = sides.to_config();
443  }
444 }
445 
447 {
448  return this->starting_pos_type_ != STARTINGPOS_INVALID;
449 }
450 
452 {
454  this->starting_pos_.swap(snapshot);
455  return this->starting_pos_;
456 }
457 
459 {
461  this->starting_pos_.swap(scenario);
462  has_carryover_expanded_ = false;
463  update_label();
464 }
465 
467 {
469  this->starting_pos_ = config();
470 }
471 
473 {
474  return starting_pos_;
475 }
476 
477 
479 {
480  if(!replay_start_.empty())
481  {
482  return replay_start_;
483  }
485  {
486  //Try to load the scenario form game config or from [scenario] if there is no [replay_start]
487  expand_scenario();
489  }
491  {
492  return starting_pos_;
493  }
494  return this->replay_start_.child("some_non_existet_invalid");
495 }
496 
498 {
500  carryover_info sides(starting_pos_, true);
502  sides.rng().rotate_random();
503  carryover_ = sides.to_config();
504  has_carryover_expanded_ = false;
506  replay_start_ = config();
507  remove_snapshot();
508 }
509 
511 {
512  //TODO: remove this code dublication with write_... functions.
514  if(!this->replay_start_.empty())
515  {
516  r.add_child("replay_start", replay_start_);
517  }
518  replay_data_.write(r.add_child("replay"));
519 
521  {
522  r.add_child("snapshot", starting_pos_);
523  }
525  {
526  r.add_child("scenario", starting_pos_);
527  }
528  r.add_child(has_carryover_expanded_ ? "carryover_sides" : "carryover_sides_start" , carryover_);
529  r.add_child("multiplayer", mp_settings_.to_config());
530  return r;
531 }
532 
534 {
535  std::string scenario_id;
538  {
539  scenario_id = starting_pos_["id"].str();
540  }
541  else if(!has_carryover_expanded_)
542  {
543  scenario_id = carryover_["next_scenario"].str();
544  }
545  else
546  {
547  assert(!"cannot figure out scenario_id");
548  throw "assertion ingnored";
549  }
550  return scenario_id == "null" ? "" : scenario_id;
551 }
552 
554 {
555  return true;
556 }
557 
559 {
560  if (classification().abbrev.empty())
561  classification().label = starting_pos_["name"].str();
562  else {
564  }
565 }
566 
568 {
569  for(config &side : this->starting_pos_.child_range("side"))
570  {
571  // for humans "goto_x/y" is used for multi-turn-moves
572  // for the ai "goto_x/y" is a way for wml to order the ai to move a unit to a certain place.
573  // we want to cancel human order but not to break wml.
574  if (side["controller"] != "human" && side["controller"] != "network") continue;
575  for(config &unit : side.child_range("unit"))
576  {
577  unit["goto_x"] = -999;
578  unit["goto_y"] = -999;
579  }
580  }
581 }
582 
584 {
585  for(config &side : this->starting_pos_.child_range("side"))
586  {
587  if (side["controller"] == "network")
588  side["controller"] = "human";
589  if (side["controller"] == "network_ai")
590  side["controller"] = "ai";
591  }
592 }
593 
595 {
596  this->swap(other);
597  return *this;
598 }
599 
601 {
602  carryover_.swap(other.carryover_);
610 }
611 
613 {
614  log_scope("read_game");
615 
616  if(config & caryover_sides = cfg.child("carryover_sides"))
617  {
618  carryover_.swap(caryover_sides);
620  }
621  else if(config & caryover_sides_start = cfg.child("carryover_sides_start"))
622  {
623  carryover_.swap(caryover_sides_start);
624  has_carryover_expanded_ = false;
625  }
626  else
627  {
628  carryover_ = config();
629  has_carryover_expanded_ = false;
630  }
631 
632  if(config & replay_start = cfg.child("replay_start"))
633  {
635  }
636  else
637  {
638  replay_start_ = config();
639  }
641  //Serversided replays can contain multiple [replay]
642  for(config& replay : cfg.child_range("replay"))
643  {
645  }
647  if(config& snapshot = cfg.child("snapshot"))
648  {
650  this->starting_pos_.swap(snapshot);
651  }
652  else if(config& scenario = cfg.child("scenario"))
653  {
655  this->starting_pos_.swap(scenario);
656  }
657  else
658  {
660  this->starting_pos_ = config();
661  }
662 
663  LOG_NG << "scenario: '" << carryover_["next_scenario"].str() << "'\n";
664 
665  if (const config &stats = cfg.child("statistics")) {
667  statistics::read_stats(stats);
668  }
669 
671  mp_settings_ = mp_game_settings(cfg.child_or_empty("multiplayer"));
672  cfg.clear();
673 }
void rotate_random()
Resets the random to the 0 calls and the seed to the random this way we stay in the same sequence but...
Definition: mt_rng.cpp:74
child_itors child_range(const std::string &key)
Definition: config.cpp:613
config replay_start_
snapshot made before the start event.
Definition: saved_game.hpp:128
std::string random_generate_map(const std::string &parms, const config &cfg)
Definition: map_create.cpp:46
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
void write(const config &cfg)
void write_starting_pos(config_writer &out) const
Definition: saved_game.cpp:143
std::string label
Name of the game (e.g.
Definition: unit.hpp:95
std::string get_tagname() const
void expand_scenario()
copies the content of a [scenario] with the correct id attribute from the game config into this objec...
Definition: saved_game.cpp:204
config to_config() const
Definition: saved_game.cpp:510
config to_config() const
config & replay_start()
Definition: saved_game.hpp:104
void set_scenario(config scenario)
Definition: saved_game.cpp:458
const config to_config()
Definition: carryover.cpp:234
void set_defaults()
does some post loading stuff must be used before passing the data to connect_engine ...
Definition: saved_game.cpp:167
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
We failed to get a starting pos in expand_scenario.
Definition: saved_game.hpp:36
There is no scenario stating pos data (start-of-scenario).
Definition: saved_game.hpp:30
config & child_or_add(const std::string &key)
Returns a reference to the first child with the given key.
Definition: config.cpp:734
bool not_corrupt() const
Definition: saved_game.cpp:553
void unify_controllers()
Definition: saved_game.cpp:583
STARTING_POS_TYPE starting_pos_type_
Definition: saved_game.hpp:133
void expand_random_scenario()
takes care of generate_map=, generate_scenario=, map= attributes This should be called before expandi...
Definition: saved_game.cpp:387
#define LOG_NG
Definition: saved_game.cpp:71
void fresh_stats()
Definition: statistics.cpp:617
void merge_old_carryover(const carryover_info &old_carryover)
Definition: carryover.cpp:265
config & set_snapshot(config snapshot)
Definition: saved_game.cpp:451
void clear()
Definition: config.cpp:1055
const config & child_or_empty(const std::string &key) const
Returns the first child with the given key, or an empty config if there is none.
Definition: config.cpp:722
void clear_children(const std::string &key)
Definition: config.cpp:820
GLuint GLenum option
Definition: glew.h:2815
void transfer_to(config &level)
Definition: carryover.cpp:203
bool empty() const
Definition: config.cpp:1105
bool empty() const
Tests for an attribute that either was never set or was set to "".
Definition: config.cpp:375
void write_general_info(config_writer &out) const
Definition: saved_game.cpp:161
Definitions for the interface to Wesnoth Markup Language (WML).
Variant for storing WML attributes.
Definition: config.hpp:223
void write_config(config_writer &out) const
writes the config information into a stream (file)
Definition: saved_game.cpp:129
void write_child(const std::string &key, const config &cfg)
void transfer_all_to(config &side_cfg)
Definition: carryover.cpp:177
const config & options()
std::vector< std::string > active_mods
static game_config_manager * get()
void swap(config &cfg)
Definition: config.cpp:1518
#define ERR_NG
Definition: saved_game.cpp:69
void load_mod(const std::string &type, const std::string &id)
helper for expand_mp_events();
Definition: saved_game.cpp:281
GLuint id
Definition: glew.h:1647
void close_child(const std::string &key)
void set_random_seed()
sets the random seed if that didn't already happen.
Definition: saved_game.cpp:119
void expand_mp_options()
adds values of [option]s into [carryover_sides_start][variables] so that they are applied in the next...
Definition: saved_game.cpp:356
Class for writing a config out to a file in pieces.
config random_generate_scenario(const std::string &parms, const config &cfg)
Definition: map_create.cpp:63
void open_child(const std::string &key)
void update_label()
sets classification().label to the correct value.
Definition: saved_game.cpp:558
void update_addon_requirements(const config &addon_cfg)
void write(config_writer &out) const
config & add_child(const std::string &key)
Definition: config.cpp:743
We have a [snapshot] (mid-game-savefile).
Definition: saved_game.hpp:32
void read_stats(const config &cfg)
Definition: statistics.cpp:607
config carryover_
depends on has_carryover_expanded_: if true: The carryover information for all sides from the previou...
Definition: saved_game.hpp:126
const rand_rng::mt_rng & rng() const
Definition: carryover.hpp:81
std::string campaign
the campaign being played
config & get_starting_pos()
Definition: saved_game.cpp:472
void set_data(config &cfg)
destroys the passed config.
Definition: saved_game.cpp:612
Templates and utility-routines for strings and numbers.
std::string read_map(const std::string &name)
GLenum GLenum variable
Definition: glew.h:10668
game_classification classification_
some general information of the game that doesn't change during the game
Definition: saved_game.hpp:130
std::string abbrev
the campaign abbreviation
GLuint res
Definition: glew.h:9258
Game configuration data as global variables.
Definition: build_info.cpp:38
mp_game_settings mp_settings_
Definition: saved_game.hpp:131
const config & game_config() const
config starting_pos_
The starting pos where the (non replay) game will be started from.
Definition: saved_game.hpp:138
void append_config(const config &data)
Information on a WML variable.
#define log_scope(description)
Definition: log.hpp:185
std::string get_scenario_id()
Definition: saved_game.cpp:533
void expand_mp_events()
adds [event]s from [era] and [modification] into this scenario does NOT expand [option]s because vari...
Definition: saved_game.cpp:321
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
void expand_carryover()
merges [carryover_sides_start] into [scenario] and saves the rest into [carryover_sides] Removes [car...
Definition: saved_game.cpp:428
saved_game & operator=(saved_game other)
Definition: saved_game.cpp:594
void swap(replay_recorder_base &other)
const attribute_value * get(const std::string &key) const
Returns a pointer to the attribute with the given key or nullptr if it does not exist.
Definition: config.cpp:935
void swap(saved_game &other)
Definition: saved_game.cpp:600
std::string hash() const
Definition: config.cpp:1468
void cancel_orders()
Definition: saved_game.cpp:567
replay_recorder_base replay_data_
Definition: saved_game.hpp:140
virtual config::attribute_value get_variable_const(const std::string &id) const =0
void load_game_config_for_game(const game_classification &classification)
game_classification & classification()
Definition: saved_game.hpp:54
void set_carryover_sides_start(config carryover_sides_start)
Definition: saved_game.cpp:113
void swap(game_board &one, game_board &other)
Definition: game_board.cpp:56
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
config & find_child(const std::string &key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
Definition: config.cpp:1010
Standard logging facilities (interface).
void convert_to_start_save()
converts a normal savegame form the end of a scenaio to a start-of-scenario savefile for the next sce...
Definition: saved_game.cpp:497
void remove_snapshot()
Definition: saved_game.cpp:466
bool valid()
Definition: saved_game.cpp:446
static lg::log_domain log_engine("engine")
Some information about savefiles: A saveile can contain: General information (toplevel atributes...
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
void write_carryover(config_writer &out) const
Definition: saved_game.cpp:154
bool has_carryover_expanded_
Definition: saved_game.hpp:120
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
Definition: saved_game.hpp:58
We have a [scenario] (start-of-scenario) savefile.
Definition: saved_game.hpp:34
GLsizei const GLcharARB ** string
Definition: glew.h:4503
const config & get_replay_starting_pos()
Definition: saved_game.cpp:478