1 /* This file is part of the Marble Marcher (https://github.com/HackerPoet/MarbleMarcher).
2 * Copyright(C) 2018 CodeParade
3 *
4 * This program 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 * This program 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 this program.If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "Level.h"
18 
19 using namespace std;
20 
ConvertSpaces2_(string text)21 string ConvertSpaces2_(string text)
22 {
23 	while (true)
24 	{
25 		std::size_t pos = text.find(" ");
26 
27 		if (pos == std::string::npos)
28 			break;
29 
30 		text = text.replace(pos, 1, "_");
31 	}
32 	return text;
33 }
34 
35 //get path vector of all files of given type
GetFilesInFolder(string folder,string filetype)36 vector<fs::path> GetFilesInFolder(string folder, string filetype)
37 {
38 	vector<fs::path> paths;
39 
40 	for (const auto & entry : fs::directory_iterator(folder))
41 	{
42 		//check if the file has the correct filetype
43 		if (entry.path().extension().string() == filetype)
44 		{
45 			paths.push_back(entry.path());
46 		}
47 	}
48 
49 	//sort the files in alphabetical order
50 	sort(paths.begin(), paths.end());
51 
52 	return paths;
53 }
54 
55 
56 Level all_levels[num_levels] = {
57   //Level 1
58   Level(
59     1.8f, -0.12f, 0.5f,                              //Scale, Angle1, Angle2
60     Eigen::Vector3f(-2.12f, -2.75f, 0.49f),          //Offset
61     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
62     0.035f,                                          //Marble Radius
63     -2.0f,                                           //Start Look Direction
64     3.3f,                                            //Orbit Distance
65     Eigen::Vector3f(-2.95862f, 2.68825f, -1.11868f), //Marble Position
66     Eigen::Vector3f(2.95227f, 2.65057f, 1.11848f),   //Flag Position
67     -4.0f,                                           //Death Barrier
68     false,                                           //Is Planet
69     "Jump The Crater"),                              //Description
70 
71   //Level 2
72   Level(
73     1.9073f, -9.83f, -1.16f,                         //Scale, Angle1, Angle2
74     Eigen::Vector3f(-3.508f, -3.593f, 3.295f),       //Offset
75     Eigen::Vector3f(-0.34f, 0.12f, -0.08f),          //Color
76     0.04f,                                           //Marble Radius
77     -2.365f,                                         //Start Look Direction
78     5.8f,                                            //Orbit Distance
79     Eigen::Vector3f(-3.40191f, 4.14347f, -3.48312f), //Marble Position
80     Eigen::Vector3f(3.40191f, 4.065f, 3.48312f),     //Flag Position
81     -4.5f,                                           //Death Barrier
82     false,                                           //Is Planet
83     "Too Many Trees"),                               //Description
84 
85   //Level 3
86   Level(
87     2.02f, -1.57f, 1.62f,                            //Scale, Angle1, Angle2
88     Eigen::Vector3f(-3.31f, 6.19f, 1.53f),           //Offset
89     Eigen::Vector3f(0.12f, -0.09f, -0.09f),          //Color
90     0.009f,                                          //Marble Radius
91     1.570796f,                                       //Start Look Direction
92     7.0f,                                            //Orbit Distance
93     Eigen::Vector3f(3.18387f, 5.99466f, 0.0f),       //Marble Position
94     Eigen::Vector3f(0.0f, -6.25f, 0.0f),             //Flag Position
95     -7.0f,                                           //Death Barrier
96     false,                                           //Is Planet
97     "Hole In One"),                                  //Description
98 
99   //Level 4
100   Level(
101     1.65f, 0.37f, 5.26f,                             //Scale, Angle1, Angle2
102     Eigen::Vector3f(-1.41f, -0.22f, -0.77f),         //Offset
103     Eigen::Vector3f(0.14f, -1.71f, 0.31f),           //Color
104     0.01f,                                           //Marble Radius
105     3.14159f,                                        //Start Look Direction
106     3.1f,                                            //Orbit Distance
107     Eigen::Vector3f(0.0f, 2.26418f, 0.0f),           //Marble Position
108     Eigen::Vector3f(0.0f, -2.25f, 0.0f),             //Flag Position
109     -999.0f,                                         //Death Barrier
110     true,                                            //Is Planet
111     "Around The World"),                             //Description
112 
113   //Level 5
114   Level(
115     1.77f, -0.22f, 5.62f,                            //Scale, Angle1, Angle2
116     Eigen::Vector3f(-2.08f, -1.42f, -1.93f),         //Offset
117     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
118     0.02f,                                           //Marble Radius
119     0.545116f,                                       //Start Look Direction
120     3.3f,                                            //Orbit Distance
121     Eigen::Vector3f(1.98046f, 2.56955f, 2.08186f),   //Marble Position
122     Eigen::Vector3f(-0.514117f, 3.14f, -2.01516f),   //Flag Position
123     -3.8f,                                           //Death Barrier
124     false,                                           //Is Planet
125     "The Hills Are Alive",                           //Description
126     0.0f, 0.06f, 0.0f),                              //Animation
127 
128   //Level 6
129   Level(
130     1.66f, 1.52f, 0.19f,                             //Scale, Angle1, Angle2
131     Eigen::Vector3f(-3.83f, -1.94f, -1.09f),         //Offset
132     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
133     0.02f,                                           //Marble Radius
134     0.0f,                                            //Start Look Direction
135     3.1f,                                            //Orbit Distance
136     Eigen::Vector3f(0.68147f, 2.80038f, 2.52778f),   //Marble Position
137     Eigen::Vector3f(0.0f, 2.84448f, -2.71705f),      //Flag Position
138     -4.0f,                                           //Death Barrier
139     false,                                           //Is Planet
140     "Beware Of Bumps"),                              //Description
141 
142   //Level 7
143   Level(
144     1.58f, -1.45f, 3.95f,                            //Scale, Angle1, Angle2
145     Eigen::Vector3f(-1.55f, -0.13f, -2.52f),         //Offset
146     Eigen::Vector3f(-1.17f, -0.4f, -1.0f),           //Color
147     0.02f,                                           //Marble Radius
148     0.0f,                                            //Start Look Direction
149     4.3f,                                            //Orbit Distance
150     Eigen::Vector3f(0.0f, 3.36453f, 2.28284f),       //Marble Position
151     Eigen::Vector3f(0.0f, 3.68893f, -0.604513f),     //Flag Position
152     -5.5f,                                           //Death Barrier
153     false,                                           //Is Planet
154     "Mountain Climbing"),                            //Description
155 
156   //Level 8
157   Level(
158     1.87f, -3.12f, 0.02f,                            //Scale, Angle1, Angle2
159     Eigen::Vector3f(-3.57f, 0.129f, 2.95f),          //Offset
160     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
161     0.02f,                                           //Marble Radius
162     3.14159f,                                        //Start Look Direction
163     4.2f,                                            //Orbit Distance
164     Eigen::Vector3f(0.0f, 3.66236f, -3.30036f),      //Marble Position
165     Eigen::Vector3f(0.0f, 3.64236f, 3.80f),          //Flag Position
166     -3.6f,                                           //Death Barrier
167     false,                                           //Is Planet
168     "The Catwalk",                                   //Description
169     0.0f, 0.0f, 0.05f),                              //Animation
170 
171   //Level 9
172   Level(
173     1.81f, -4.84f, -2.99f,                           //Scale, Angle1, Angle2
174     Eigen::Vector3f(-2.905f, 0.765f, -4.165f),       //Offset
175     Eigen::Vector3f(0.16f, 0.38f, 0.15f),            //Color
176     0.022f,                                          //Marble Radius
177     -1.570796f,                                      //Start Look Direction
178     4.5f,                                            //Orbit Distance
179     Eigen::Vector3f(-4.63064f, 3.6365f, 0.0f),       //Marble Position
180     Eigen::Vector3f(4.63f, 3.61f, 0.0f),             //Flag Position
181     -5.5f,                                           //Death Barrier
182     false,                                           //Is Planet
183     "Mind The Gap"),                                 //Description
184 
185   //Level 10
186   Level(
187     1.93f, 1.34637f, 1.58f,                          //Scale, Angle1, Angle2
188     Eigen::Vector3f(-2.31f, 1.123f, 1.56f),          //Offset
189     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
190     0.02f,                                           //Marble Radius
191     -2.39681f,                                       //Start Look Direction
192     2.7f,                                            //Orbit Distance
193     Eigen::Vector3f(-1.71412f, 1.84836f, -1.70884f), //Marble Position
194     Eigen::Vector3f(0.0f, 2.13651f, 1.74782f),       //Flag Position
195     -3.6f,                                           //Death Barrier
196     false,                                           //Is Planet
197     "Don't Get Crushed",                             //Description
198     0.1f, 0.0f, 0.0f),                               //Animation
199 
200   //Level 11
201   Level(
202     1.88f, 1.52f, 4.91f,                             //Scale, Angle1, Angle2
203     Eigen::Vector3f(-4.54f, -1.26f, 0.1f),           //Offset
204     Eigen::Vector3f(-1.0f, 0.3f, -0.43f),            //Color
205     0.03f,                                           //Marble Radius
206     -1.570796f,                                      //Start Look Direction
207     5.7f,                                            //Orbit Distance
208     Eigen::Vector3f(-2.8896f, 3.76526f, 0.0f),       //Marble Position
209     Eigen::Vector3f(2.88924f, 3.73f, 0.0f),          //Flag Position
210     -4.5f,                                           //Death Barrier
211     false,                                           //Is Planet
212     "The Sponge"),                                   //Description
213 
214   //Level 12
215   Level(
216     1.6f, 3.77f, 3.93f,                              //Scale, Angle1, Angle2
217     Eigen::Vector3f(-2.0f, -0.41f, -1.43f),          //Offset
218     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
219     0.02f,                                           //Marble Radius
220     -1.570796f,                                      //Start Look Direction
221     3.5f,                                            //Orbit Distance
222     Eigen::Vector3f(-2.30432f, 0.0444069f, 2.31072f),//Marble Position
223     Eigen::Vector3f(2.30432f, 0.0244069f, -2.31072f),//Flag Position
224     -1.0f,                                           //Death Barrier
225     false,                                           //Is Planet
226     "Ride The Gecko",                                //Description
227     0.02f, 0.0f, 0.0f),                              //Animation
228 
229   //Level 13
230   Level(
231     2.08f, -4.79f, 3.16f,                            //Scale, Angle1, Angle2
232     Eigen::Vector3f(-7.43f, 5.96f, -6.23f),          //Offset
233     Eigen::Vector3f(0.16f, 0.38f, 0.15f),            //Color
234     0.023f,                                          //Marble Radius
235     1.570796f,                                       //Start Look Direction
236     7.6f,                                            //Orbit Distance
237     Eigen::Vector3f(6.06325f, 6.32712f, 0.0f),       //Marble Position
238     Eigen::Vector3f(0.0f, 6.72f, 0.0f),              //Flag Position
239     -7.0f,                                           //Death Barrier
240     false,                                           //Is Planet
241     "Build Up Speed"),                               //Description
242 
243   //Level 14
244   Level(
245     2.0773f, -9.66f, -1.34f,                         //Scale, Angle1, Angle2
246     Eigen::Vector3f(-1.238f, -1.533f, 1.085f),       //Offset
247     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
248     0.01f,                                           //Marble Radius
249     1.4f,                                            //Start Look Direction
250     3.0f,                                            //Orbit Distance
251     Eigen::Vector3f(1.03543f, 1.06432f, 1.22698f),   //Marble Position
252     Eigen::Vector3f(-1.39536f, 0.641835f, 0.0f),     //Flag Position
253     -2.0f,                                           //Death Barrier
254     false,                                           //Is Planet
255     "Around The Citadel"),                           //Description
256 
257   //Level 15
258   Level(
259     1.78f, -0.1f, 3.28f,                             //Scale, Angle1, Angle2
260     Eigen::Vector3f(-1.47f, 1.7f, -0.4f),            //Offset
261     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
262     0.02f,                                           //Marble Radius
263     3.14159f,                                        //Start Look Direction
264     2.9f,                                            //Orbit Distance
265     Eigen::Vector3f(0.0f, 2.1431f, 0.0f),            //Marble Position
266     Eigen::Vector3f(0.0, -2.12f, 0.0),               //Flag Position
267     -999.0f,                                         //Death Barrier
268     true,                                            //Is Planet
269     "Planet Crusher",                                //Description
270     0.0f, 0.08f, 0.0f),                              //Animation
271 
272   Level(
273     2.0773f, -9.66f, -1.34f,                         //Scale, Angle1, Angle2
274     Eigen::Vector3f(-1.238f, -1.533f, 1.085f),       //Offset
275     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
276     0.005f,                                          //Marble Radius
277     0.78539816339f,                                  //Start Look Direction
278     2.0f,                                            //Orbit Distance
279     Eigen::Vector3f(1.04172f, 1.41944f, 1.09742f),   //Marble Position
280     Eigen::Vector3f(-1.04172f, 1.414f, -1.09742f),   //Flag Position
281     -2.0f,                                           //Death Barrier
282     false,                                           //Is Planet
283     "Top Of The Citadel"),                           //Description
284 
285   Level(
286     1.8093f, -3.165f, -3.2094777f,                   //Scale, Angle1, Angle2
287     Eigen::Vector3f(-1.0939f, -0.43495f, -3.1113f),  //Offset
288     Eigen::Vector3f(-0.61f, -0.92f, 0.33f),          //Color
289     0.005f,                                          //Marble Radius
290     0.0f,                                            //Start Look Direction
291     5.0f,                                            //Orbit Distance
292     Eigen::Vector3f(0.0f, -0.483245f, 2.16278f),     //Marble Position
293     Eigen::Vector3f(0.0f, -0.489f, -2.16278f),       //Flag Position
294     -5.0f,                                           //Death Barrier
295     false,                                           //Is Planet
296     "Building Bridges",                              //Description
297     0.0f, 0.0f, 0.06f),                              //Animation
298 
299   Level(
300     1.95f, 1.570796f, 0.0f,                          //Scale, Angle1, Angle2
301     Eigen::Vector3f(-6.75f, -3.0f, 0.0f),            //Offset
302     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
303     0.022f,                                          //Marble Radius
304     0.0f,                                            //Start Look Direction
305     6.3f,                                            //Orbit Distance
306     Eigen::Vector3f(0.0f, 3.96637f, 4.54647f),       //Marble Position
307     Eigen::Vector3f(0.0f, 0.396f, -2.38815f),        //Flag Position
308     -5.0f,                                           //Death Barrier
309     false,                                           //Is Planet
310     "Pylon Palace"),                                 //Description
311 
312   Level(
313     1.91f, 0.06f, -0.76f,                            //Scale, Angle1, Angle2
314     Eigen::Vector3f(-3.44f, -0.69f, -1.14f),         //Offset
315     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
316     0.012f,                                          //Marble Radius
317     3.14159f,                                        //Start Look Direction
318     5.0f,                                            //Orbit Distance
319     Eigen::Vector3f(0.0f, 3.78299f, 0.0f),           //Marble Position
320     Eigen::Vector3f(0.0f, -3.77f, 0.0f),             //Flag Position
321     -999.0f,                                         //Death Barrier
322     true,                                            //Is Planet
323     "The Crown Jewels",                              //Description
324     0.0f, 0.05f, 0.0f),                              //Animation
325 
326   Level(
327     1.8986f, -0.4166f, 0.00683f,                     //Scale, Angle1, Angle2
328     Eigen::Vector3f(-2.5130f, -5.4067f, -2.51f),     //Offset
329     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
330     0.01f,                                           //Marble Radius
331     -1.570796f,                                      //Start Look Direction
332     5.0f,                                            //Orbit Distance
333     Eigen::Vector3f(1.19695f, 3.19773f, 2.8491f),    //Marble Position
334     Eigen::Vector3f(1.168f, 3.195f, -2.8491f),       //Flag Position
335     -5.0f,                                           //Death Barrier
336     false,                                           //Is Planet
337     "Expressways"),                                  //Description
338 
339   Level(
340     2.03413f, 1.688f, -1.57798f,                     //Scale, Angle1, Angle2
341     Eigen::Vector3f(-4.803822f, -4.1f, -1.39063f),   //Offset
342     Eigen::Vector3f(-0.95f, -0.16f, 0.14f),          //Color
343     0.005f,                                          //Marble Radius
344     1.570796f,                                       //Start Look Direction
345     7.0f,                                            //Orbit Distance
346     Eigen::Vector3f(3.77655f, 4.7211f, 0.0f),        //Marble Position
347     Eigen::Vector3f(-3.77655f, 4.716f, 0.0f),        //Flag Position
348     -5.0f,                                           //Death Barrier
349     false,                                           //Is Planet
350     "Bunny Hops"),                                   //Description
351 
352   Level(
353     1.6516888f, 0.026083898f, -0.7996324f,           //Scale, Angle1, Angle2
354     Eigen::Vector3f(-3.85863f, -5.13741f, -0.918303f),//Offset
355     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
356     0.016f,                                          //Marble Radius
357     0.0f,                                            //Start Look Direction
358     7.0f,                                            //Orbit Distance
359     Eigen::Vector3f(0.0f, 5.91936f, 4.3357f),        //Marble Position
360     Eigen::Vector3f(0.0f, -1.01f, -3.94f),           //Flag Position
361     -6.5f,                                           //Death Barrier
362     false,                                           //Is Planet
363     "Asteroid Field"),                               //Description
364 
365   Level(
366     1.77746f, 4.62318f, 0.0707307f,                  //Scale, Angle1, Angle2
367     Eigen::Vector3f(-4.6867f, -0.84376f, 1.98158f),  //Offset
368     Eigen::Vector3f(-0.35f, 1.5f, 0.48f),            //Color
369     0.016f,                                          //Marble Radius
370     1.570796f,                                       //Start Look Direction
371     7.0f,                                            //Orbit Distance
372     Eigen::Vector3f(3.03669f, 4.3497f, 0.0f),        //Marble Position
373     Eigen::Vector3f(-3.03669f, 4.331f, 0.0f),        //Flag Position
374     -5.0f,                                           //Death Barrier
375     false,                                           //Is Planet
376     "Lily Pads"),                                    //Description
377 
378   Level(
379     2.13f, -1.77f, -1.62f,                           //Scale, Angle1, Angle2
380     Eigen::Vector3f(-4.99f, -3.05f, -4.48f),         //Offset
381     Eigen::Vector3f(0.42f, 0.38f, 0.19f),            //Color
382     0.01f,                                           //Marble Radius
383     3.14159f,                                        //Start Look Direction
384     6.2f,                                            //Orbit Distance
385     Eigen::Vector3f(0.479104f,  2.18768f, -4.29408f),//Marble Position
386     Eigen::Vector3f(0.479104f,  2.177f, 4.29408f),   //Flag Position
387     -4.0f,                                           //Death Barrier
388     false,                                           //Is Planet
389     "Fatal Fissures"),                               //Description
390 };
391 
392 Level default_level(1.5f, 0.0f, 0.0f,                 //Scale, Angle1, Angle2
393 	Eigen::Vector3f(-1.f, -2.f, 0.f),				 //Offset
394 	Eigen::Vector3f(1.f, 1.f, 1.f),				     //Color
395 	0.035f,                                          //Marble Radius
396 	-2.0f,                                           //Start Look Direction
397 	3.3f,                                            //Orbit Distance
398 	Eigen::Vector3f(-2.95862f, 2.68825f, -1.11868f), //Marble Position
399 	Eigen::Vector3f(2.95227f, 2.65057f, 1.11848f),   //Flag Position
400 	-4.0f,                                           //Death Barrier
401 	false,                                           //Is Planet
402 	"Untitled level");
403 
Level(float s,float a1,float a2,const Eigen::Vector3f & v,const Eigen::Vector3f & c,float rad,float look_x,float orbit_d,const Eigen::Vector3f & start,const Eigen::Vector3f & end,float kill,bool pg,const char * name,float an1,float an2,float an3)404 Level::Level(float s, float a1, float a2,
405   const Eigen::Vector3f& v,
406   const Eigen::Vector3f& c,
407   float rad,
408   float look_x,
409   float orbit_d,
410   const Eigen::Vector3f& start,
411   const Eigen::Vector3f& end,
412   float kill,
413   bool pg,
414   const char* name,
415   float an1, float an2, float an3)
416 {
417   params[0] = s;
418   params[1] = a1;
419   params[2] = a2;
420   params.segment<3>(3) = v;
421   params.segment<3>(6) = c;
422   marble_rad = rad;
423   start_look_x = look_x;
424   orbit_dist = orbit_d;
425   start_pos = start;
426   end_pos = end;
427   kill_y = kill;
428   planet = pg;
429   txt = name;
430   anim_1 = an1;
431   anim_2 = an2;
432   anim_3 = an3;
433 
434   FractalIter = 16;
435 
436   PBR_roughness = 0.5;
437   PBR_metal = 0.4;
438 
439   desc = " ";
440 
441   light_dir = Eigen::Vector3f(-0.36, 0.8, 0.48);
442   light_col = Eigen::Vector3f(1.0, 0.95, 0.8);
443 
444   level_id = 0;
445   link_level = -1;
446   use_music = "level1.ogg";
447 
448   ground_force = 0.008f;
449   air_force = 0.004f;
450   ground_friction = 0.99f;
451   air_friction = 0.995f;
452   gravity = 0.005f;
453   ground_ratio = 1.15f;
454   FractalParamsAmp = FractalParams();
455   FractalParamsFrq = FractalParams();
456 
457   background_col = Eigen::Vector3f(0.6, 0.8, 1.0);
458   gravity_dir = Eigen::Vector3f(0, 0, -1.0);
459 }
460 
LoadFromFile(fs::path path)461 void Level::LoadFromFile(fs::path path)
462 {
463 	int lvl_size = fs::file_size(path);
464 	int LevelF_size = sizeof(LevelF);
465 
466 	if (lvl_size != LevelF_size)
467 	{
468 		ERROR_MSG("Invalid .LVL file");
469 	}
470 
471 	LevelF loaded_lvl;
472 
473 	std::ifstream level_file(path, ios_base::in | ios_base::binary);
474 
475 	level_file.seekg(0);
476 	level_file.read(reinterpret_cast<char *>(&loaded_lvl), sizeof(LevelF));
477 
478 	level_file.close();
479 
480 	LoadLevelF(loaded_lvl);
481 
482 }
483 
SaveToFile(std::string file,int ID,int Link)484 void Level::SaveToFile(std::string file, int ID, int Link)
485 {
486 	std::ofstream level_file(file, ios_base::out | ios_base::trunc | ios_base::binary);
487 
488 	LevelF lvl_to_save = GetLevelF();
489 
490 	lvl_to_save.level_id = ID;
491 	lvl_to_save.link_level = Link;
492 
493 	level_file.write(reinterpret_cast<char *>(&lvl_to_save), sizeof(lvl_to_save));
494 
495 	level_file.close();
496 }
497 
LoadLevelF(LevelF lvl)498 void Level::LoadLevelF(LevelF lvl)
499 {
500 	FractalIter = lvl.FractalIterations;			 //Fractal iterations
501 	params = FractalParams(lvl.FractalParams);      //Fractal parameters
502 
503 	PBR_roughness = lvl.PBR_roughness;		 //Fractal roughness
504 	PBR_metal = lvl.PBR_metal;           //Fractal metalicity
505 
506 	marble_rad = lvl.marble_rad;          //Radius of the marble
507 	start_look_x = lvl.start_look_x;        //Camera direction on start
508 	orbit_dist = lvl.orbit_dist;          //Distance to orbit
509 	start_pos = Eigen::Vector3f(lvl.start_pos); //Starting position of the marble
510 	end_pos = Eigen::Vector3f(lvl.end_pos);   //Ending goal flag position
511 	kill_y = lvl.kill_y;              //Below this height player is killed
512 	planet = lvl.planet;               //True if gravity should be like a planet
513 	txt = std::string(lvl.txt);           //Title
514 	desc = std::string(lvl.desc); 		 //Description
515 	anim_1 = lvl.anim_1;              //Animation amount for angle1 parameter
516 	anim_2 = lvl.anim_2;              //Animation amount for angle2 parameter
517 	anim_3 = lvl.anim_3;              //Animation amount for offset_y parameter
518 	light_dir = Eigen::Vector3f(lvl.light_dir); //Sun light direction
519 	light_col = Eigen::Vector3f(lvl.light_col); //Sun light color
520 
521 	level_id = lvl.level_id;				 //level identifier
522 	link_level = lvl.link_level;			 //Play what level after finish
523 	use_music = std::string(lvl.use_music);      //what track to use
524 
525 	ground_force = lvl.ground_force;
526 	air_force = lvl.air_force;
527 	ground_friction = lvl.ground_friction;
528 	air_friction = lvl.air_friction;
529 	gravity = lvl.gravity;
530 	ground_ratio = lvl.ground_ratio;
531 	background_col = Eigen::Vector3f(lvl.background_col);
532 	gravity_dir = Eigen::Vector3f(lvl.gravity_dir);
533 
534 	FractalParamsAmp = FractalParams(lvl.FractalParamsAmp);
535 	FractalParamsFrq = FractalParams(lvl.FractalParamsFrq);
536 }
537 
GetLevelF()538 LevelF Level::GetLevelF()
539 {
540 	LevelF lvlF;
541 
542 	strcpy(lvlF.txt, txt.c_str());
543 	strcpy(lvlF.desc, desc.c_str());
544 	strcpy(lvlF.use_music, use_music.c_str());
545 
546 	lvlF.FractalIterations = FractalIter;
547 	std::copy(params.data(), params.data() + 9, lvlF.FractalParams);
548 
549 	lvlF.PBR_roughness = PBR_roughness;
550 	lvlF.PBR_metal = PBR_metal;
551 
552 	lvlF.marble_rad = marble_rad;
553 	lvlF.start_look_x = start_look_x;
554 	lvlF.orbit_dist = orbit_dist;
555 	std::copy(start_pos.data(), start_pos.data() + 3, lvlF.start_pos);
556 	std::copy(end_pos.data(), end_pos.data() + 3, lvlF.end_pos);
557 
558 	lvlF.kill_y = kill_y;
559 	lvlF.planet = planet;
560 	lvlF.anim_1 = anim_1;
561 	lvlF.anim_2 = anim_2;
562 	lvlF.anim_3 = anim_3;
563 	std::copy(light_dir.data(), light_dir.data() + 3, lvlF.light_dir);
564 	std::copy(light_col.data(), light_col.data() + 3, lvlF.light_col);
565 
566 	lvlF.level_id = level_id;
567 	lvlF.link_level = link_level;
568 
569 	lvlF.ground_force = ground_force;
570 	lvlF.air_force = air_force;
571 	lvlF.ground_friction = ground_friction;
572 	lvlF.air_friction = air_friction;
573 	lvlF.gravity = gravity;
574 	lvlF.ground_ratio = ground_ratio;
575 
576 	std::copy(background_col.data(), background_col.data() + 3, lvlF.background_col);
577 	std::copy(gravity_dir.data(), gravity_dir.data() + 3, lvlF.gravity_dir);
578 
579 	std::copy(FractalParamsAmp.data(), FractalParamsAmp.data() + 9, lvlF.FractalParamsAmp);
580 	std::copy(FractalParamsFrq.data(), FractalParamsFrq.data() + 9, lvlF.FractalParamsFrq);
581 
582 	return lvlF;
583 }
584 
LoadLevelsFromFolder(std::string folder)585 void All_Levels::LoadLevelsFromFolder(std::string folder)
586 {
587 	lvl_folder = folder;
588 	level_num = 0;
589 	vector<fs::path> files = GetFilesInFolder(folder, ".lvl");
590 	for (int i = 0; i < files.size(); i++)
591 	{
592 		LoadLevelFromFile(files[i]);
593 	}
594 }
595 
LoadMusicFromFolder(std::string folder)596 void All_Levels::LoadMusicFromFolder(std::string folder)
597 {
598 	vector<fs::path> files = GetFilesInFolder(folder, ".ogg");
599 	for (int i = 0; i < files.size(); i++)
600 	{
601 		music_map.insert(std::make_pair(files[i].filename().string(), new sf::Music()));
602 		music_map[files[i].filename().string()]->openFromFile(files[i].string());
603 		music_map[files[i].filename().string()]->setLoop(true);
604 		music_names.push_back(files[i].filename().string());
605 	}
606 }
607 
LevelExists(int ID)608 bool All_Levels::LevelExists(int ID)
609 {
610 	if (level_map.count(ID) > 0)
611 	{
612 		return true;
613 	}
614 	return false;
615 }
616 
GetLevel(int ID)617 Level All_Levels::GetLevel(int ID)
618 {
619 	return level_map[ID];
620 }
621 
GetLevelNum()622 int All_Levels::GetLevelNum()
623 {
624 	return level_num;
625 }
626 
getLevelNames()627 std::map<int, std::string> All_Levels::getLevelNames()
628 {
629 	return level_names;
630 }
631 
getLevelDesc()632 std::map<int, std::string> All_Levels::getLevelDesc()
633 {
634 	return level_descriptions;
635 }
636 
getLevelIds()637 std::vector<int> All_Levels::getLevelIds()
638 {
639 	return level_ids;
640 }
641 
getLevelScores()642 std::map<int, Score> All_Levels::getLevelScores()
643 {
644 	return score_map;
645 }
646 
GetLevelMusic(int ID)647 sf::Music* All_Levels::GetLevelMusic(int ID)
648 {
649 	if (music_map.count(level_map[ID].use_music) > 0)
650 	{
651 		return music_map[level_map[ID].use_music];
652 	}
653 	return nullptr;
654 }
655 
GetMusic(std::string music)656 sf::Music* All_Levels::GetMusic(std::string music)
657 {
658 	if (music_map.count(music) > 0)
659 	{
660 		return music_map[music];
661 	}
662 	return nullptr;
663 }
664 
RecreateMissing()665 void All_Levels::RecreateMissing()
666 {
667 	for (int i = 0; i < 24; i++)
668 	{
669 		if (!LevelExists(i)) //if original level doesn't exist
670 		{
671 			all_levels[i].desc = "Official Level by Codeparade";
672 			all_levels[i].SaveToFile(std::string(level_folder) + "/" + ConvertSpaces2_(all_levels[i].txt) + ".lvl", i, (i < 24) ? (i + 1) : -1);
673 		}
674 	}
675 }
676 
ReloadLevels()677 void All_Levels::ReloadLevels()
678 {
679 	RecreateMissing();
680 	level_map.clear();
681 	level_id_map.clear();
682 	level_names.clear();
683 	level_descriptions.clear();
684 	level_ids.clear();
685 	LoadLevelsFromFolder(lvl_folder);
686 }
687 
LoadLevelFromFile(fs::path file)688 void All_Levels::LoadLevelFromFile(fs::path file)
689 {
690 	Level cur_lvl;
691 	cur_lvl.LoadFromFile(file);
692 	level_map.insert(std::make_pair(cur_lvl.level_id, cur_lvl));
693 	level_id_map.insert(std::make_pair(level_num, cur_lvl.level_id));
694 	level_names[cur_lvl.level_id] = cur_lvl.txt;
695 	level_descriptions[cur_lvl.level_id] = cur_lvl.desc;
696 	level_ids.push_back(cur_lvl.level_id);
697 	level_num++;
698 }
699 
LoadScoresFromFile(std::string file)700 void All_Levels::LoadScoresFromFile(std::string file)
701 {
702 	if (!fs::exists(file))
703 	{
704 		return;
705 	}
706 
707 	int scores_size = fs::file_size(file);
708 	int score_size = sizeof(Score);
709 
710 	if (scores_size % score_size != 0)
711 	{
712 		return;
713 	}
714 
715 	int lvl_num = scores_size / score_size;
716 
717 	std::ifstream score_file(file, ios_base::in | ios_base::binary);
718 	//score_file.seekg(0);
719 	for (int i = 0; i < lvl_num; i++)
720 	{
721 		Score sc;
722 		score_file.read(reinterpret_cast<char *>(&sc), sizeof(Score));
723 		if(sc.best_time != 0)
724 			score_map[sc.level_id] = sc;
725 	}
726 	score_file.close();
727 }
728 
GetBest(int lvl)729 float All_Levels::GetBest(int lvl)
730 {
731 	return score_map[lvl].best_time;
732 }
733 
734 
SaveScoresToFile(const std::string & file)735 void All_Levels::SaveScoresToFile(const std::string& file)
736 {
737 	std::ofstream score_file(file, ios_base::trunc | ios_base::binary);
738 
739 	for (auto &score : score_map)
740 	{
741 		score_file.write(reinterpret_cast<char *>(&score.second), sizeof(Score));
742 	}
743 
744 	score_file.close();
745 }
746 
UpdateScore(int lvl,float time)747 bool All_Levels::UpdateScore(int lvl, float time)
748 {
749 	float last = 1e10;
750 	if (score_map.count(lvl) > 0 && score_map[lvl].best_time!=0)
751 	{
752 		last = score_map[lvl].best_time;
753 	}
754 	else
755 	{
756 		score_map[lvl] = Score();
757 	}
758 	bool is_best = time<last;
759 	if (is_best)
760 	{
761 		score_map[lvl].best_time = time;
762 	}
763 	score_map[lvl].level_id = lvl;
764 	score_map[lvl].all_time += time;
765 	score_map[lvl].played_num++;
766 	score_map[lvl].last_time = time;
767 	return is_best;
768 }
769 
DeleteLevel(int lvl)770 void All_Levels::DeleteLevel(int lvl)
771 {
772 	std::string filename = lvl_folder + "/" + ConvertSpaces2_(level_names[lvl]) + ".lvl";
773 	fs::remove(filename);
774 	level_map.erase(lvl);
775 	ReloadLevels();
776 }
777 
GetMusicByID(int ID)778 sf::Music * All_Levels::GetMusicByID(int ID)
779 {
780 	return music_map[music_names[ID]];
781 }
782 
StopAllMusic()783 void All_Levels::StopAllMusic()
784 {
785 	for (int i = 0; i < music_names.size(); i++)
786 	{
787 		music_map[music_names[i]]->stop();
788 	}
789 }
790 
GetMusicNames()791 std::vector<std::string> All_Levels::GetMusicNames()
792 {
793 	return music_names;
794 }
795 
796