1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _GAME_H
5 #define _GAME_H
6 
7 #include "JsonFwd.h"
8 #include "galaxy/Galaxy.h"
9 #include "galaxy/SystemPath.h"
10 #include "gameconsts.h"
11 #include <string>
12 
13 class GameLog;
14 class HyperspaceCloud;
15 class Player;
16 class Space;
17 
18 namespace Graphics {
19 	class Renderer;
20 }
21 
22 struct CannotSaveCurrentGameState {};
23 struct CannotSaveInHyperspace : public CannotSaveCurrentGameState {};
24 struct CannotSaveDeadPlayer : public CannotSaveCurrentGameState {};
25 struct InvalidGameStartLocation {
26 	std::string error;
InvalidGameStartLocationInvalidGameStartLocation27 	InvalidGameStartLocation(const std::string &error_) :
28 		error(error_) {}
29 };
30 
31 class View;
32 class SectorView;
33 class SystemInfoView;
34 class SystemView;
35 class WorldView;
36 class DeathView;
37 class ObjectViewerView;
38 
39 class Game {
40 public:
41 	static Json LoadGameToJson(const std::string &filename);
42 	// LoadGame and SaveGame throw exceptions on failure
43 	static Game *LoadGame(const std::string &filename);
44 	static bool CanLoadGame(const std::string &filename);
45 	// XXX game arg should be const, and this should probably be a member function
46 	// (or LoadGame/SaveGame should be somewhere else entirely)
47 	static void SaveGame(const std::string &filename, Game *game);
48 
49 	// start docked in station referenced by path or nearby to body if it is no station
50 	Game(const SystemPath &path, const double startDateTime = 0.0);
51 
52 	// load game
53 	Game(const Json &jsonObj);
54 
55 	~Game();
56 
57 	// save game
58 	void ToJson(Json &jsonObj);
59 
60 	// various game states
IsNormalSpace()61 	bool IsNormalSpace() const { return m_state == State::NORMAL; }
IsHyperspace()62 	bool IsHyperspace() const { return m_state == State::HYPERSPACE; }
63 
GetGalaxy()64 	RefCountedPtr<Galaxy> GetGalaxy() const { return m_galaxy; }
GetSpace()65 	Space *GetSpace() const { return m_space.get(); }
GetTime()66 	double GetTime() const { return m_time; }
GetPlayer()67 	Player *GetPlayer() const { return m_player.get(); }
68 
69 	// physics step
70 	void TimeStep(float step);
71 
72 	// update time acceleration once per render frame
73 	// returns true if timeaccel was changed
74 	bool UpdateTimeAccel();
75 
76 	// request switch to hyperspace
77 	void WantHyperspace();
78 
79 	// hyperspace parameters. only meaningful when IsHyperspace() is true
GetHyperspaceProgress()80 	float GetHyperspaceProgress() const { return m_hyperspaceProgress; }
GetHyperspaceDuration()81 	double GetHyperspaceDuration() const { return m_hyperspaceDuration; }
GetHyperspaceEndTime()82 	double GetHyperspaceEndTime() const { return m_hyperspaceEndTime; }
83 	double GetHyperspaceArrivalProbability() const;
GetHyperspaceDest()84 	const SystemPath &GetHyperspaceDest() const { return m_hyperspaceDest; }
GetHyperspaceSource()85 	const SystemPath &GetHyperspaceSource() const { return m_hyperspaceSource; }
86 	void RemoveHyperspaceCloud(HyperspaceCloud *);
87 
88 	enum TimeAccel {
89 		TIMEACCEL_PAUSED,
90 		TIMEACCEL_1X,
91 		TIMEACCEL_10X,
92 		TIMEACCEL_100X,
93 		TIMEACCEL_1000X,
94 		TIMEACCEL_10000X,
95 		TIMEACCEL_HYPERSPACE
96 	};
97 
98 	void SetTimeAccel(TimeAccel t);
99 	void RequestTimeAccel(TimeAccel t, bool force = false);
100 
101 	/// Requests an increase in time acceleration
102 	/// @param force if set to false the system can reject the request under certain conditions
103 	void RequestTimeAccelInc(bool force = false);
104 	/// Requests a decrease in time acceleration
105 	/// @param force if set to false the system can reject the request under certain conditions
106 	void RequestTimeAccelDec(bool force = false);
107 
GetTimeAccel()108 	TimeAccel GetTimeAccel() const { return m_timeAccel; }
GetRequestedTimeAccel()109 	TimeAccel GetRequestedTimeAccel() const { return m_requestedTimeAccel; }
IsPaused()110 	bool IsPaused() const { return m_timeAccel == TIMEACCEL_PAUSED; }
111 
GetTimeAccelRate()112 	float GetTimeAccelRate() const { return s_timeAccelRates[m_timeAccel]; }
GetInvTimeAccelRate()113 	float GetInvTimeAccelRate() const { return s_timeInvAccelRates[m_timeAccel]; }
114 
GetTimeStep()115 	float GetTimeStep() const { return s_timeAccelRates[m_timeAccel] * (1.0f / PHYSICS_HZ); }
116 
GetSectorView()117 	SectorView *GetSectorView() const { return m_gameViews->m_sectorView; }
GetSystemInfoView()118 	SystemInfoView *GetSystemInfoView() const { return m_gameViews->m_systemInfoView; }
GetSystemView()119 	SystemView *GetSystemView() const { return m_gameViews->m_systemView; }
GetWorldView()120 	WorldView *GetWorldView() const { return m_gameViews->m_worldView; }
GetDeathView()121 	DeathView *GetDeathView() const { return m_gameViews->m_deathView; }
GetSpaceStationView()122 	View *GetSpaceStationView() const { return m_gameViews->m_spaceStationView; }
GetInfoView()123 	View *GetInfoView() const { return m_gameViews->m_infoView; }
124 
125 	/* Only use #if WITH_OBJECTVIEWER */
126 	ObjectViewerView *GetObjectViewerView() const;
127 
128 	GameLog *log;
129 
130 private:
131 	class Views {
132 	public:
133 		Views();
134 		void Init(Game *game);
135 		void LoadFromJson(const Json &jsonObj, Game *game);
136 		~Views();
137 
138 		void SetRenderer(Graphics::Renderer *r);
139 
140 		SectorView *m_sectorView;
141 		SystemInfoView *m_systemInfoView;
142 		SystemView *m_systemView;
143 		WorldView *m_worldView;
144 		DeathView *m_deathView;
145 		View *m_spaceStationView;
146 		View *m_infoView;
147 
148 		/* Only use #if WITH_OBJECTVIEWER */
149 		ObjectViewerView *m_objectViewerView;
150 	};
151 
152 	void CreateViews();
153 	void LoadViewsFromJson(const Json &jsonObj);
154 	void DestroyViews();
155 
156 	static void EmitPauseState(bool paused);
157 
158 	void SwitchToHyperspace();
159 	void SwitchToNormalSpace();
160 
161 	RefCountedPtr<Galaxy> m_galaxy;
162 	std::unique_ptr<Views> m_gameViews;
163 	std::unique_ptr<Space> m_space;
164 	double m_time;
165 
166 	std::unique_ptr<Player> m_player;
167 
168 	enum class State {
169 		NORMAL,
170 		HYPERSPACE,
171 	};
172 	State m_state;
173 
174 	bool m_wantHyperspace;
175 
176 	std::list<HyperspaceCloud *> m_hyperspaceClouds;
177 	SystemPath m_hyperspaceSource;
178 	SystemPath m_hyperspaceDest;
179 	double m_hyperspaceProgress;
180 	double m_hyperspaceDuration;
181 	double m_hyperspaceEndTime;
182 
183 	TimeAccel m_timeAccel;
184 	TimeAccel m_requestedTimeAccel;
185 	bool m_forceTimeAccel;
186 	static const float s_timeAccelRates[];
187 	static const float s_timeInvAccelRates[];
188 };
189 
190 #endif
191