1 /*
2  * Copyright (C) 2011-2013 Me and My Shadow
3  *
4  * This file is part of Me and My Shadow.
5  *
6  * Me and My Shadow is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Me and My Shadow is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Me and My Shadow.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef GAME_H
21 #define GAME_H
22 
23 #include <SDL.h>
24 #include <array>
25 #include <vector>
26 #include <map>
27 #include <string>
28 
29 #include "CachedTexture.h"
30 #include "GameState.h"
31 #include "GUIObject.h"
32 #include "GameObjects.h"
33 #include "Scenery.h"
34 #include "SceneryLayer.h"
35 #include "Player.h"
36 #include "Render.h"
37 #include "Shadow.h"
38 
39 //This structure contains variables that make a GameObjectEvent.
40 struct typeGameObjectEvent{
41 	//The type of event.
42 	int eventType;
43 	//The type of object that should react to the event.
44 	int objectType;
45 	//Flags, 0x1 means use the id.
46 	int flags;
47 	//Blocks with this id should react to the event.
48 	std::string id;
49 
50 	//Optional pointer to the block the event should be called on.
51 	GameObject* target;
52 };
53 
54 class ThemeManager;
55 class ThemeBackground;
56 class TreeStorageNode;
57 class ScriptExecutor;
58 
59 //The different level events.
60 enum LevelEventType{
61 	//Event called when the level is created or the game is reset. This happens after all the blocks are created and their onCreate is called.
62 	LevelEvent_OnCreate=1,
63 	//Event called when the game is saved.
64 	LevelEvent_OnSave,
65 	//Event called when the game is loaded.
66 	LevelEvent_OnLoad,
67 };
68 
69 class Game : public GameState,public GUIEventCallback{
70 private:
71 	//Boolean if the game should reset. This happens when player press 'R' button.
72 	bool isReset;
73 
74 	//The script executor.
75 	ScriptExecutor *scriptExecutor;
76 
77 protected:
78 	//contains currently played level.
79 	TreeStorageNode* currentLevelNode;
80 
81 	//Array containing "tooltips" for certain block types.
82 	//It will be shown in the topleft corner of the screen.
83     std::array<TexturePtr, TYPE_MAX> bmTips;
84 
85     //Texture containing the action images (record, play, etc..)
86     SharedTexture action;
87     //Texture containing the medal image.
88     SharedTexture medals;
89 
90 	//ThemeBlockInstance containing the collectable image.
91 	ThemeBlockInstance collectable;
92 
93 	//The name of the current level.
94 	std::string levelName;
95 	//The path + file of the current level.
96 	std::string levelFile;
97 
98 	//Editor data containing information like name, size, etc...
99 	std::map<std::string,std::string> editorData;
100 
101 	//Vector used to queue the gameObjectEvents.
102 	std::vector<typeGameObjectEvent> eventQueue;
103 
104 	//The themeManager.
105 	ThemeManager* customTheme;
106 	//The themeBackground.
107 	ThemeBackground* background;
108 
109     CachedTexture<int> collectablesTexture;
110     CachedTexture<int> recordingsTexture;
111     CachedTexture<int> timeTexture;
112     CachedTexture<Block*> notificationTexture;
113 
114 	//Load a level from node.
115 	//After calling this function the ownership of
116 	//node will transfer to Game class. So don't delete
117 	//the node after calling this function!
118     virtual void loadLevelFromNode(ImageManager& imageManager, SDL_Renderer& renderer, TreeStorageNode* obj, const std::string& fileName);
119 
120 	//(internal function) Reload the music according to level music and level pack music.
121 	//This is mainly used in level editor.
122 	void reloadMusic();
123 
124 public:
125 	//Array used to convert GameObject type->string.
126 	static const char* blockName[TYPE_MAX];
127 	//Map used to convert GameObject string->type.
128 	static std::map<std::string,int> blockNameMap;
129 
130 	//Map used to convert GameObjectEventType type->string.
131 	static std::map<int,std::string> gameObjectEventTypeMap;
132 	//Map used to convert GameObjectEventType string->type.
133 	static std::map<std::string,int> gameObjectEventNameMap;
134 
135 	//Map used to convert LevelEventType type->string.
136 	static std::map<int,std::string> levelEventTypeMap;
137 	//Map used to convert LevelEventType string->type.
138 	static std::map<std::string,int> levelEventNameMap;
139 
140 	//Boolean that is set to true when a game is won.
141 	bool won;
142 
143 	//Boolean that is set to true when we should save game on next logic update.
144 	bool saveStateNextTime;
145 
146 	//Boolean that is set to true when we should load game on next logic update.
147 	bool loadStateNextTime;
148 
149 	//Boolean if the replaying currently done is for the interlevel screen.
150 	bool interlevel;
151 
152 	//Integer containing the current tip index.
153 	int gameTipIndex;
154 
155 	//Integer containing the number of ticks passed since the start of the level.
156 	int time;
157 	//Integer containing the stored value of time.
158 	int timeSaved;
159 
160 	//Integer containing the number of recordings it took to finish.
161 	int recordings;
162 	//Integer containing the stored value of recordings.
163 	int recordingsSaved;
164 
165 	//Integer keeping track of currently obtained collectables
166 	int currentCollectables;
167 	//Integer keeping track of total colletables in the level
168 	int totalCollectables;
169 	//Integer containing the stored value of current collectables
170 	int currentCollectablesSaved;
171 
172 	//Time of recent swap, for achievements. (in game-ticks)
173 	int recentSwap,recentSwapSaved;
174 
175 	//Store time of recent save/load for achievements (in millisecond)
176 	Uint32 recentLoad,recentSave;
177 
178 	//Enumeration with the different camera modes.
179 	enum CameraMode{
180 		CAMERA_PLAYER,
181 		CAMERA_SHADOW,
182 		CAMERA_CUSTOM
183 	};
184 	//The current camera mode.
185 	CameraMode cameraMode;
186 	//Rectangle containing the target for the camera.
187 	SDL_Rect cameraTarget;
188 
189 	//The saved cameraMode.
190 	CameraMode cameraModeSaved;
191 	SDL_Rect cameraTargetSaved;
192 
193 	//Level scripts.
194 	std::map<int,std::string> scripts;
195 
196 	//Compiled scripts. Use lua_rawgeti(L, LUA_REGISTRYINDEX, r) to get the function.
197 	std::map<int, int> compiledScripts, savedCompiledScripts, initialCompiledScripts;
198 
199 	//Vector containing all the levelObjects in the current game.
200 	std::vector<Block*> levelObjects;
201 
202 	//The layers for the scenery.
203 	// We utilize the fact that std::map is sorted, and we compare the layer name with "f",
204 	// If name<"f" then it's background layer, if name>="f" then it's foreground layer.
205 	// NOTE: the layer name is case sensitive, in particular if the name start with capital "F"
206 	// then it is still background layer.
207 	std::map<std::string,SceneryLayer*> sceneryLayers;
208 
209 	//The player...
210 	Player player;
211 	//... and his shadow.
212 	Shadow shadow;
213 
214 	//warning: weak reference only, may point to invalid location
215 	Block* objLastCheckPoint;
216 
217 	//Constructor.
218     Game(SDL_Renderer& renderer, ImageManager& imageManager);
219 	//If this is not empty then when next Game class is created
220 	//it will play this record file.
221 	static std::string recordFile;
222 	//Destructor.
223 	//It will call destroy();
224 	~Game();
225 
226 	//Method used to clean up the GameState.
227 	void destroy();
228 
229 	//Inherited from GameState.
230     void handleEvents(ImageManager&imageManager, SDL_Renderer&renderer) override;
231     void logic(ImageManager& imageManager, SDL_Renderer& renderer) override;
232     void render(ImageManager&,SDL_Renderer& renderer) override;
233     void resize(ImageManager& imageManager, SDL_Renderer& renderer) override;
234 
235 	//This method will load a level.
236 	//fileName: The fileName of the level.
237     virtual void loadLevel(ImageManager& imageManager, SDL_Renderer& renderer, std::string fileName);
238 
239 	//Method used to broadcast a GameObjectEvent.
240 	//eventType: The type of event.
241 	//objectType: The type of object that should react to the event.
242 	//id: The id of the blocks that should react.
243 	//target: Pointer to the object
244 	void broadcastObjectEvent(int eventType,int objectType=-1,const char* id=NULL,GameObject* target=NULL);
245 
246 	//Compile all scripts and run onCreate script.
247 	//NOTE: Call this function only after script state reset, or there will be some memory leaks.
248 	void compileScript();
249 
250 	//Method that will check if a script for a given levelEvent is present.
251 	//If that's the case the script will be executed.
252 	//eventType: The level event type to execute.
253 	void inline executeScript(int eventType);
254 
255 
256 	//Returns if the player and shadow can save the current state.
257 	bool canSaveState();
258 
259 	//Method used to store the current state.
260 	//This is used for checkpoints.
261 	//Returns: True if it succeeds without problems.
262 	bool saveState();
263 	//Method used to load the stored state.
264 	//This is used for checkpoints.
265 	//Returns: True if it succeeds without problems.
266 	bool loadState();
267 	//Method that will reset the GameState to it's initial state.
268 	//save: Boolean if the saved state should also be deleted. This also means recreate the Lua context.
269 	//noScript: Boolean if we should not compile the script at all. This is used by level editor when exiting test play.
270 	void reset(bool save,bool noScript);
271 
272 	//Save current game record to the file.
273 	//fileName: The filename of the destination file.
274 	void saveRecord(const char* fileName);
275 	//Load game record (and its level) from file and play it.
276 	//fileName: The filename of the recording file.
277     void loadRecord(ImageManager& imageManager, SDL_Renderer& renderer, const char* fileName);
278 
279 	//Method called by the player (or shadow) when he finished.
280     void replayPlay(ImageManager& imageManager, SDL_Renderer &renderer);
281 	//Method that gets called when the recording has ended.
282     void recordingEnded(ImageManager& imageManager, SDL_Renderer& renderer);
283 
284 	//get current level's auto-save record path,
285 	//using current level's MD5, file name and other information.
286 	void getCurrentLevelAutoSaveRecordPath(std::string &bestTimeFilePath,std::string &bestRecordingFilePath,bool createPath);
287 
288 	//Method that will prepare the gamestate for the next level and start it.
289 	//If it's the last level it will show the congratulations text and return to the level select screen.
290     void gotoNextLevel(ImageManager& imageManager, SDL_Renderer& renderer);
291 
292 	//Get the name of the current level.
getLevelName()293 	const std::string& getLevelName(){
294 		return levelName;
295 	}
296 
297 	//GUI event handling is done here.
298     void GUIEventCallback_OnEvent(ImageManager&imageManager, SDL_Renderer&renderer, std::string name, GUIObject* obj, int eventType) override;
299 
300 	//Get the script executor.
getScriptExecutor()301 	ScriptExecutor* getScriptExecutor() {
302 		return scriptExecutor;
303 	}
304 };
305 
306 #endif
307