1 /* Copyright (C) 2017 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. 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  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_GAME
19 #define INCLUDED_GAME
20 
21 #include <vector>
22 
23 #include "ps/Errors.h"
24 #include "ps/Filesystem.h"
25 #include "scriptinterface/ScriptVal.h"
26 #include "simulation2/helpers/Player.h"
27 
28 class CWorld;
29 class CSimulation2;
30 class CGameView;
31 class CTurnManager;
32 class IReplayLogger;
33 struct CColor;
34 
35 /**
36  * The container that holds the rules, resources and attributes of the game.
37  * The CGame object is responsible for creating a game that is defined by
38  * a set of attributes provided. The CGame object is also responsible for
39  * maintaining the relations between CPlayer and CWorld, CSimulation and CWorld.
40  **/
41 class CGame
42 {
43 	NONCOPYABLE(CGame);
44 
45 	/**
46 	 * pointer to the CWorld object representing the game world.
47 	 **/
48 	CWorld *m_World;
49 
50 	/**
51 	 * pointer to the CSimulation2 object operating on the game world.
52 	 **/
53 	CSimulation2 *m_Simulation2;
54 
55 	/**
56 	 * pointer to the CGameView object representing the view into the game world.
57 	 **/
58 	CGameView *m_GameView;
59 
60 	/**
61 	 * the game has been initialized and ready for use if true.
62 	 **/
63 	bool m_GameStarted;
64 
65 	/**
66 	 * Timescale multiplier for simulation rate.
67 	 **/
68 	float m_SimRate;
69 
70 	/**
71 	 * Index assigned to the current player.
72 	 * 1-8 to control players, 0 for gaia, -1 for observer.
73 	 */
74 	player_id_t m_PlayerID;
75 
76 	/**
77 	 * Differs from m_PlayerID if a defeated player or observer views another player.
78 	 */
79 	player_id_t m_ViewedPlayerID;
80 
81 	CTurnManager* m_TurnManager;
82 
83 public:
84 	CGame(bool disableGraphics = false, bool replayLog = true);
85 	~CGame();
86 
87 	/**
88 	 * the game is paused and no updates will be performed if true.
89 	 **/
90 	bool m_Paused;
91 
92 	void StartGame(JS::MutableHandleValue attribs, const std::string& savedState);
93 	PSRETURN ReallyStartGame();
94 
95 	bool StartVisualReplay(const OsPath& replayPath);
96 
97 	/**
98 	 * Periodic heartbeat that controls the process. performs all per-frame updates.
99 	 * Simulation update is called and game status update is called.
100 	 *
101 	 * @param deltaRealTime Elapsed real time since last beat/frame, in seconds.
102 	 * @param doInterpolate Perform graphics interpolation if true.
103 	 * @return bool false if it can't keep up with the desired simulation rate
104 	 *	indicating that you might want to render less frequently.
105 	 */
106 	void Update(const double deltaRealTime, bool doInterpolate = true);
107 
108 	void Interpolate(float simFrameLength, float realFrameLength);
109 
110 	int GetPlayerID();
111 	void SetPlayerID(player_id_t playerID);
112 
113 	int GetViewedPlayerID();
114 	void SetViewedPlayerID(player_id_t playerID);
115 
116 	/**
117 	 * Check if the game is finished by testing if there's a winner.
118 	 * It is used to end a non visual autostarted game.
119 	 *
120 	 * @return true if there's a winner, false otherwise.
121 	 */
122 	bool IsGameFinished() const;
123 
124 	/**
125 	 * Retrieving player colors from scripts is slow, so this updates an
126 	 * internal cache of all players' colors.
127 	 * Call this just before rendering, so it will always have the latest
128 	 * colors.
129 	 */
130 	void CachePlayerColors();
131 
132 	CColor GetPlayerColor(player_id_t player) const;
133 
134 	/**
135 	 * Get m_GameStarted.
136 	 *
137 	 * @return bool the value of m_GameStarted.
138 	 **/
IsGameStarted()139 	inline bool IsGameStarted() const
140 	{
141 		return m_GameStarted;
142 	}
143 
144 	/**
145 	 * Get if the graphics is disabled.
146 	 *
147 	 * @return bool true if the m_GameView is NULL, false otherwise.
148 	 */
IsGraphicsDisabled()149 	inline bool IsGraphicsDisabled() const
150 	{
151 		return !m_GameView;
152 	}
153 
154 	/**
155 	 * Get m_IsVisualReplay.
156 	 *
157 	 * @return bool the value of m_IsVisualReplay.
158 	 **/
IsVisualReplay()159 	inline bool IsVisualReplay() const
160 	{	return m_IsVisualReplay; }
161 
162 	/**
163 	 * Get the pointer to the game world object.
164 	 *
165 	 * @return CWorld * the value of m_World.
166 	 **/
GetWorld()167 	inline CWorld *GetWorld()
168 	{	return m_World; }
169 
170 	/**
171 	 * Get the pointer to the game view object.
172 	 *
173 	 * @return CGameView * the value of m_GameView.
174 	 **/
GetView()175 	inline CGameView *GetView()
176 	{	return m_GameView; }
177 
178 	/**
179 	 * Get the pointer to the simulation2 object.
180 	 *
181 	 * @return CSimulation2 * the value of m_Simulation2.
182 	 **/
GetSimulation2()183 	inline CSimulation2 *GetSimulation2()
184 	{	return m_Simulation2; }
185 
186 	/**
187 	 * Set the simulation scale multiplier.
188 	 *
189 	 * @param simRate Float value to set m_SimRate to.
190 	 *						Because m_SimRate is also used to
191 	 *						scale TimeSinceLastFrame it must be
192 	 *						clamped to 0.0f.
193 	 **/
SetSimRate(float simRate)194 	inline void SetSimRate(float simRate)
195 	{	if (isfinite(simRate)) m_SimRate = std::max(simRate, 0.0f); }
196 
GetSimRate()197 	inline float GetSimRate() const
198 	{	return m_SimRate; }
199 
GetReplayPath()200 	inline OsPath GetReplayPath() const
201 	{	return m_ReplayPath; }
202 
203 	/**
204 	 * Replace the current turn manager.
205 	 * This class will take ownership of the pointer.
206 	 */
207 	void SetTurnManager(CTurnManager* turnManager);
208 
GetTurnManager()209 	CTurnManager* GetTurnManager() const
210 	{	return m_TurnManager; }
211 
GetReplayLogger()212 	IReplayLogger& GetReplayLogger() const
213 	{	return *m_ReplayLogger; }
214 
215 private:
216 	void RegisterInit(const JS::HandleValue attribs, const std::string& savedState);
217 	IReplayLogger* m_ReplayLogger;
218 
219 	std::vector<CColor> m_PlayerColors;
220 
221 	int LoadInitialState();
222 	std::string m_InitialSavedState; // valid between RegisterInit and LoadInitialState
223 	bool m_IsSavedGame; // true if loading a saved game; false for a new game
224 
225 	int LoadVisualReplayData();
226 	OsPath m_ReplayPath;
227 	bool m_IsVisualReplay;
228 	std::istream* m_ReplayStream;
229 	u32 m_FinalReplayTurn;
230 };
231 
232 extern CGame *g_Game;
233 
234 #endif
235