mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-25 21:50:25 +00:00
179 lines
6.8 KiB
C++
179 lines
6.8 KiB
C++
/*
|
|
Copyright (C) 2003 - 2024
|
|
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY.
|
|
|
|
See the COPYING file for more details.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "config.hpp"
|
|
#include "game_classification.hpp"
|
|
#include "mp_game_settings.hpp"
|
|
#include "replay_recorder_base.hpp"
|
|
#include "statistics_record.hpp"
|
|
|
|
class config_writer;
|
|
|
|
class saved_game
|
|
{
|
|
enum class starting_point {
|
|
/** There is no scenario stating pos data (start-of-scenario). */
|
|
NONE,
|
|
/** We have a [snapshot] (mid-game-savefile). */
|
|
SNAPSHOT,
|
|
/** We have a [scenario] (start-of-scenario) savefile. */
|
|
SCENARIO,
|
|
/** We failed to get a starting pos in expand_scenario. */
|
|
INVALID
|
|
};
|
|
|
|
public:
|
|
saved_game();
|
|
saved_game(const saved_game& state);
|
|
explicit saved_game(config cfg);
|
|
~saved_game(){}
|
|
|
|
saved_game& operator=(const saved_game& other) = delete;
|
|
saved_game& operator=(saved_game&& other);
|
|
void swap(saved_game& other);
|
|
/** destroys the passed config. */
|
|
void set_data(config& cfg);
|
|
void clear();
|
|
/** writes the config information into a stream (file) */
|
|
void write_config(config_writer& out) const;
|
|
void write_general_info(config_writer& out) const;
|
|
void write_carryover(config_writer& out) const;
|
|
void write_starting_point(config_writer& out) const;
|
|
config to_config() const;
|
|
game_classification& classification() { return classification_; }
|
|
const game_classification& classification() const { return classification_; }
|
|
|
|
/** Multiplayer parameters for this game */
|
|
mp_game_settings& mp_settings() { return mp_settings_; }
|
|
const mp_game_settings& mp_settings() const { return mp_settings_; }
|
|
|
|
void set_carryover_sides_start(config carryover_sides_start);
|
|
|
|
/**
|
|
* copies the content of a [scenario] with the correct id attribute from the game config into this object.
|
|
* reloads the game config from disk if necessary.
|
|
*/
|
|
void expand_scenario();
|
|
/**
|
|
* merges [carryover_sides_start] into [scenario] and saves the rest into [carryover_sides]
|
|
* Removes [carryover_sides_start] afterwards
|
|
*/
|
|
void expand_carryover();
|
|
/**
|
|
* adds [event]s from [era] and [modification] into this scenario
|
|
* does NOT expand [option]s because variables are persitent anyway to we don't need it
|
|
* should be called after expand_scenario() but before expand_carryover()
|
|
*/
|
|
void expand_mp_events();
|
|
/** helper for expand_mp_events(); */
|
|
void load_non_scenario(const std::string& type, const std::string& id, size_t pos);
|
|
/**
|
|
* adds values of [option]s into [carryover_sides_start][variables] so that they are applied in the next level.
|
|
* Note that since [variabels] are persistent we only use this once at the beginning
|
|
* of a campaign but calling it multiple times is no harm eigher
|
|
*/
|
|
void expand_mp_options();
|
|
/**
|
|
* takes care of generate_map=, generate_scenario=, map= attributes
|
|
* This should be called before expanding carryover or mp_events because this might completely replace starting_point_.
|
|
*/
|
|
void expand_random_scenario();
|
|
/** copies attributes & tags from the 'outer' [scenario] to the scenario that is generated by scenario_generation= */
|
|
static void post_scenario_generation(const config& old_scenario, config& generated_scenario);
|
|
/** reads scenario["map_file"] */
|
|
static void expand_map_file(config& scenario);
|
|
/** Add addon_id information if needed. */
|
|
void check_require_scenario();
|
|
bool valid() const;
|
|
/** @return the snapshot in the savefile (get_starting_point) */
|
|
config& set_snapshot(config snapshot);
|
|
void set_scenario(config scenario);
|
|
void remove_snapshot();
|
|
|
|
bool is_mid_game_save() const
|
|
{
|
|
return starting_point_type_ == starting_point::SNAPSHOT;
|
|
}
|
|
bool is_start_of_scenario() const
|
|
{
|
|
return !has_carryover_expanded_;
|
|
}
|
|
/**
|
|
* converts a normal savegame form the end of a scenaio to a start-of-scenario savefile for the next scenaio,
|
|
* The saved_game must contain a [snapshot] made during the linger mode of the last scenaio.
|
|
*/
|
|
void convert_to_start_save();
|
|
/** sets the random seed if that didn't already happen. */
|
|
void set_random_seed();
|
|
/** @return the starting pos for replays. Usually this is [replay_start] but it can also be a [scenario] if no [replay_start] is present */
|
|
const config& get_replay_starting_point();
|
|
/** @return the id of the currently played scenario or the id of the next scenario if this is a between-scenaios-save (also called start-of-scenario-save). */
|
|
std::string get_scenario_id() const;
|
|
/** @return the config from which the game will be started. (this is [scenario] or [snapshot] in the savefile) */
|
|
config& get_starting_point();
|
|
const config& get_starting_point() const { return starting_point_; }
|
|
config& replay_start() { return replay_start_; }
|
|
const config& replay_start() const { return replay_start_; }
|
|
|
|
bool not_corrupt() const;
|
|
/** sets classification().label to the correct value. */
|
|
void update_label();
|
|
|
|
void cancel_orders();
|
|
/* removes network_ai and network controller types*/
|
|
void unify_controllers();
|
|
/** does some post loading stuff must be used before passing the data to connect_engine */
|
|
void set_defaults();
|
|
replay_recorder_base& get_replay() { return replay_data_; }
|
|
const replay_recorder_base& get_replay() const { return replay_data_; }
|
|
|
|
statistics_record::campaign_stats_t& statistics() { return statistics_; }
|
|
const statistics_record::campaign_stats_t& statistics() const { return statistics_; }
|
|
/** Whether to play [story] tags */
|
|
bool skip_story() const { return skip_story_; }
|
|
void set_skip_story(bool skip_story) { skip_story_ = skip_story; }
|
|
|
|
private:
|
|
bool has_carryover_expanded_;
|
|
/**
|
|
depends on has_carryover_expanded_:
|
|
if true: The carryover information for all sides from the previous scenario that aren't used in this scenario (to be carried over to the next scenario).
|
|
if false: The carryover information for all sides from the previous scenario.
|
|
*/
|
|
config carryover_;
|
|
/** snapshot made before the start event. To be used as a starting pos for replays */
|
|
config replay_start_;
|
|
/** some general information of the game that doesn't change during the game */
|
|
game_classification classification_;
|
|
mp_game_settings mp_settings_;
|
|
|
|
starting_point starting_point_type_;
|
|
/**
|
|
The starting pos where the (non replay) game will be started from.
|
|
This can eigher be a [scenario] for a fresh game or a [snapshot] if this is a reloaded game
|
|
*/
|
|
config starting_point_;
|
|
|
|
replay_recorder_base replay_data_;
|
|
|
|
statistics_record::campaign_stats_t statistics_;
|
|
|
|
bool skip_story_;
|
|
};
|
|
|
|
/** Implement non-member swap function for std::swap (calls @ref saved_game::swap). */
|
|
void swap(saved_game& lhs, saved_game& rhs);
|