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 LEVELPACK_H
21 #define LEVELPACK_H
22 
23 #include <vector>
24 #include <string>
25 
26 #include "libs/tinygettext/tinygettext.hpp"
27 
28 enum LevelPackType{
29 	//Main levelpacks are distibuted along with the game and located in the data path.
30 	MAIN,
31 	//Addon levelpacks are downloaded/added packs which reside in the user data path.
32 	ADDON,
33 	//Custom levelpacks are user made and are located in the
34 	CUSTOM,
35 
36 	//Collection levelpacks can contain levels from different locations.
37 	//This type is used for the Levels and Custom Levels levelpacks.
38 	//NOTE: The levelpackPath is ignored for these type of levelpacks since levels can be anywhere.
39 	COLLECTION
40 };
41 
42 class LevelPack{
43 public:
44 	//A level entry structure.
45 	struct Level{
46 		//The name of the level.
47 		std::string name;
48 		//The filename of the level.
49 		std::string file;
50 
51 		//Boolean if the level is locked.
52 		bool locked;
53 		//Boolean if the level is won.
54 		bool won;
55 
56 		//Integer containing the number of ticks (40 = 1s) it took to finish the level.
57 		//If there's no time the value will be -1.
58 		int time;
59 		//Integer containing the target time to get a medal.
60 		int targetTime;
61 
62 		//Integer containing the number of recordings used to finish the level.
63 		//When not won the value is -1.
64 		int recordings;
65 		//Integer containing the target recordings to get a medal.
66 		int targetRecordings;
67 
68 		//MD5 of level node. :/
69 		unsigned char md5Digest[16];
70 	};
71 private:
72 	//Index of the current level.
73 	int currentLevel;
74 
75 	//Boolean if the levels are loaded.
76 	bool loaded;
77 
78 	//Vector containing the filenames of the levels.
79 	std::vector<Level> levels;
80 
81 	//The file name of the level progress.
82 	std::string levelProgressFile;
83 
84 public:
85 	//The name of the levelpack.
86 	std::string levelpackName;
87 	//The location the levelpack is stored.
88 	std::string levelpackPath;
89 	//A description of the levelpack.
90 	std::string levelpackDescription;
91 
92 	//The type of levelpack.
93 	LevelPackType type;
94 
95 	//The text that will be displayed when the levels are finished.
96 	std::string congratulationText;
97 
98 	//The preferred music list to be used with this levelpack.
99 	std::string levelpackMusicList;
100 
101 	//The dictionaryManager of the levelpack, used to translate strings.
102 	tinygettext::DictionaryManager* dictionaryManager;
103 
104 	//Boolean if the levelpack has a custom theme/partial theme bundled with it.
105 	//NOTE: Themes can't be preloaded since they would be destroyed by the ThemeStack.
106 	bool customTheme;
107 
108 	//Constructor.
109 	LevelPack();
110 	//Destructor.
111 	~LevelPack();
112 
113 	//gettext function
getDictionaryManager()114 	inline tinygettext::DictionaryManager* getDictionaryManager() const{
115 		return dictionaryManager;
116 	}
117 
118 	//Method for updating the language to the configured one.
119 	//NOTE: This is called when changing the translation in the Options menu.
120 	void updateLanguage();
121 
122 	//Adds a level to the levels.
123 	//levelFileName: The filename of the level to add.
124 	//level: The index of the level to add.
125 	void addLevel(const std::string& levelFileName,int levelno=-1);
126 	//Removes a level from the levels.
127 	//level: The index of the level to remove.
128 	void removeLevel(unsigned int level);
129 	//Moves the level to a given index.
130 	//level1: The level to move.
131 	//level2: The destination.
132 	void moveLevel(unsigned int level1,unsigned int level2);
133 	//Swaps two level.
134 	//level1: The first level to swap.
135 	//level2: The second level to swap.
136 	void swapLevel(unsigned int level1,unsigned int level2);
137 
138 	//Get the levelFile for a given level.
139 	//level: The level index to get the levelFile from.
140 	//Returns: String containing the levelFileName (full path to the file).
141 	const std::string getLevelFile(int level=-1);
142 	//Get the levelpackPath of the levels.
143 	//Returns: String containing the levelpackPath.
144 	const std::string& getLevelpackPath();
145 	//Get the levelName for a given level.
146 	//level: The level index to get the levelName from.
147 	//Returns: String containing the levelName.
148 	const std::string& getLevelName(int level=-1);
149 	//Sets the levelName for a given level.
150 	//level: The level index to get the levelName from.
151 	//name: The new name of the level.
152 	void setLevelName(unsigned int level,const std::string& name);
153 	//Get the MD5 for a given level.
154 	//level: The level index.
155 	//Returns: const unsigned char[16] containing the digest.
156 	const unsigned char* getLevelMD5(int level=-1);
157 
158 	//get level's auto-save record path,
159 	//using level's MD5, file name and other information.
160 	void getLevelAutoSaveRecordPath(int level,std::string &bestTimeFilePath,std::string &bestRecordingFilePath,bool createPath);
161 
162 	//Method for getting the path to the progress file.
163 	//Returns: The path + filename to the progress file.
164 	std::string getLevelProgressPath();
165 
166 	//Set the currentLevel.
167 	//level: The new current level.
168 	void setCurrentLevel(unsigned int level);
169 	//Get the currentLevel.
170 	//Returns: The currentLevel.
getCurrentLevel()171 	inline int getCurrentLevel(){return currentLevel;}
172 	//Get the levelCount.
173 	//Returns: The level count.
getLevelCount()174 	inline int getLevelCount(){return levels.size();}
175 
176 	//Method that will return the requested level.
177 	//level: The index of the level, default is the current level.
178 	//Returns: Pointer to the requested level structure.
179 	struct Level* getLevel(int level=-1);
180 
181 	//Method that will reset any progress/statistics for a given level.
182 	//level: The index of the level to reset, default is currentLevel.
183 	void resetLevel(int level=-1);
184 
185 	//Check if a certain level is locked.
186 	//level: The index of the level to check.
187 	//Returns: True if the level is locked.
188 	bool getLocked(unsigned int level);
189 	//Set a level locked or not.
190 	//level: The level to (un)lock.
191 	//locked: The new status of the level, default is unlocked (false).
192 	void setLocked(unsigned int level,bool locked=false);
193 
194 	//Empties the levels.
195 	void clear();
196 
197 
198 	bool loadLevels(const std::string& levelListFile);
199 	void loadProgress();
200 	void saveLevels(const std::string& levelListFile);
201 	void saveLevelProgress();
202 
203 	void nextLevel();
204 
205 };
206 #endif
207