/
gamesession.h
222 lines (189 loc) · 7.75 KB
/
gamesession.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/** @file gamesession.h Logical game session and saved session marshalling.
*
* @authors Copyright © 2014 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>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; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/
#ifndef LIBCOMMON_GAMESESSION_H
#define LIBCOMMON_GAMESESSION_H
#include <de/game/Session>
#include <de/String>
#include <doomsday/uri.h>
#include "doomsday.h"
#include "gamerules.h"
namespace common {
/**
* Implements high level logic for the manipulation and configuration of the logical game session.
*
* An internal backing store is used to record player progress automatically, whenever the current
* map changes while the session is in progress. This occurs irrespective of the user's savegame
* preferences. Additionally, the user may configure the game so that the internal backing store
* is periodically (e.g., when the map changes) copied to a new "autosave" automatically.
*
* The "scope" of a continous game session progression depends on the configuration of the Episode
* and the maps within it. Upon leaving one map and entering another, if both are attributed to
* the same logical "hub" then the current state of the map is written to the backing store so
* that it may be reloaded later if the player(s) decide to revisit. However, if the new map is
* in another hub, or no hub is defined, then all saved map progress for current hub is discarded.
*
* Note that the use of hubs is not required and some games may not use them at all (e.g., DOOM).
*
* @ingroup libcommon
*/
class GameSession : public de::game::Session
{
public:
GameSession();
virtual ~GameSession();
/// Returns the singleton instance.
static GameSession &gameSession();
/// Register the commands and variables of this module.
static void consoleRegister();
bool hasBegun();
bool savingPossible();
bool loadingPossible();
/**
* Returns the current Episode definition for the game session in progress. If the session
* has not yet begun then @c nullptr is returned.
*/
de::Record *episodeDef();
/**
* Returns the current episode id for the game session in progress. If the session has not
* yet begun then a zero-length string is returned.
*/
de::String episodeId();
/**
* Returns the current MapGraphNode definition for the game session in progress. If the
* session has not yet begun then @c nullptr is returned.
*/
de::Record *mapGraphNodeDef();
/**
* Returns the current MapInfo definition for the game session in progress. If the session
* has not yet begun, or no definition exists for the current map then @c nullptr is returned.
*/
de::Record *mapInfo();
/**
* Returns the current map URI for the game session in progress. If the session has not
* yet begun then an empty URI is returned.
*/
de::Uri mapUri();
/**
* Returns the player entry point for the current map, for the game session in progress.
* The entry point determines where players will be reborn.
*/
uint mapEntryPoint();
/**
* Resolves a named exit according to the map progression.
*/
de::Uri mapUriForNamedExit(de::String name);
/**
* Returns the current ruleset for the game session.
*/
GameRuleset const &rules() const;
/**
* To be called when a new game begins to effect the game rules. Note that some of the rules
* may be overridden here (e.g., in a networked game).
*
* @todo Prevent this outright if the game session is already in progress!
*/
void applyNewRules(GameRuleset const &rules);
/**
* Determines whether saved game progress will be restored when the current map is reloaded,
* according to the current game state and user configuration.
*/
bool progressRestoredOnReload() const;
/**
* End the game session (if in progress).
* @see hasBegun()
*/
void end();
/**
* End the game session (if in progress) and begin the title sequence.
* @see end(), hasBegun()
*/
void endAndBeginTitle();
/**
* Configure and begin a new game session. Note that a @em new session cannot @em begin if
* one already @ref hasBegun() (if so, the session must be ended first).
*
* @param rules Game rules to apply.
* @param episodeId Episode identifier.
* @param mapUri Map identifier.
* @param mapEntryPoint Map entry point number, for player reborn.
*
* @throws InProgressError if the session has already begun.
*/
void begin(GameRuleset const &rules, de::String const &episodeId, de::Uri const &mapUri,
uint mapEntryPoint = 0);
/**
* Reload the @em current map, automatically loading any saved progress from the backing
* store if @ref progressRestoredOnReload(). If no saved progress exists then the map will
* be in the default state.
*/
void reloadMap();
/**
* Leave the @em current map (automatically saving progress to the backing store) and then
* load up the next map according to the defined game progression.
*/
void leaveMap();
/**
* Convenient method of looking up the user description of the game session in progress.
*
* @return User description of the session if it @ref hasBegun() or a zero-length string.
*/
de::String userDescription();
public: // Saved session management ----------------------------------------------------------
/**
* Save the current game state to a new @em user saved session.
*
* @param saveName Name of the new saved session.
* @param userDescription Textual description of the current game state provided either
* by the user or possibly generated automatically.
*/
void save(de::String const &saveName, de::String const &userDescription);
/**
* Load the game state from the @em user saved session specified.
*
* @param saveName Name of the saved session to be loaded.
*/
void load(de::String const &saveName);
/**
* Makes a copy of the @em user saved session specified in /home/savegames/<gameId>
*
* @param destName Name of the new/replaced saved session.
* @param sourceName Name of the saved session to be copied.
*/
void copySaved(de::String const &destName, de::String const &sourceName);
/**
* Removes the @em user saved session /home/savegames/<gameId>/<@a saveName>.save
*/
void removeSaved(de::String const &saveName);
/**
* Convenient method of looking up the @em user description of an existing saved session.
*
* @param saveName Name of the saved session to lookup.
*
* @return User description of the named session or a zero-length string if not found.
*/
de::String savedUserDescription(de::String const &saveName);
private:
DENG2_PRIVATE(d)
};
} // namespace common
/**
* Macro for conveniently accessing the common::GameSession singleton instance.
*/
#define COMMON_GAMESESSION (&common::GameSession::gameSession())
#endif // LIBCOMMON_GAMESESSION_H