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