R-Type  2
Doom but in better
Loading...
Searching...
No Matches
MainClass.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2024
3** rtype (Workspace)
4** File description:
5** MainClass.cpp
6*/
7
14#include <cstdint>
15#include <sstream>
16#include <fstream>
17#include "RealMain.hpp"
18
44 const std::string &ip,
45 unsigned int port,
46 unsigned int windowWidth,
47 unsigned int windowHeight,
48 bool windowCursor,
49 bool windowFullscreen,
50 const std::string &windowTitle,
51 unsigned int windowX,
52 unsigned int windowY,
53 const std::string &windowCursorIcon,
54 bool imageIsSprite,
55 bool spriteStartTop,
56 bool spriteStartLeft,
57 unsigned int spriteWidth,
58 unsigned int spriteHeight,
59 unsigned int frameLimit,
60 const std::string &configFilePath,
61 const bool log,
62 const bool debug,
63 const std::string &player
64) :
65_windowWidth(windowWidth),
66_windowHeight(windowHeight),
67_windowCursor(windowCursor),
68_windowFullscreen(windowFullscreen),
69_windowTitle(windowTitle),
70_windowX(windowX),
71_windowY(windowY),
72_imageIsSprite(imageIsSprite),
73_spriteStartTop(spriteStartTop),
74_spriteStartLeft(spriteStartLeft),
75_spriteWidth(spriteWidth),
76_configFilePath(configFilePath),
77_spriteHeight(spriteHeight),
78_networkManager(),
79_player(player)
80{
81 _log = log;
83 PRETTY_INFO << "Logging is enabled" << std::endl;
84 _debug = debug;
86 PRETTY_DEBUG << "The debug section of the log is enabled" << std::endl;
87 PRETTY_INFO << "Processing ip" << std::endl;
88 if (_isIpInRange(ip) == true) {
89 _ip = ip;
90 } else {
92 }
93 PRETTY_INFO << "Processing port" << std::endl;
94 if (_isPortCorrect(port) == true) {
95 _port = port;
96 } else {
97 throw CustomExceptions::InvalidPort(std::to_string(port));
98 }
99 PRETTY_INFO << "Processing cursor icon" << std::endl;
100 std::string windowText = _lowerText(windowCursorIcon);
101 if (windowText.empty() || windowText == "null" || windowText == "none") {
102 _windowCursorIcon = "";
103 } else if (_isFilePresent(windowCursorIcon) == true) {
104 _windowCursorIcon = windowCursorIcon;
105 } else {
106 throw CustomExceptions::FileNotFound(windowCursorIcon);
107 }
108 PRETTY_INFO << "Processing frame limit" << std::endl;
109 if (_isFrameLimitCorrect(frameLimit)) {
110 _windowFrameLimit = frameLimit;
111 } else {
112 throw CustomExceptions::InvalidFrameLimit(frameLimit);
113 }
114 PRETTY_INFO << "Initialising the network manager" << std::endl;
115 _networkManager = std::make_shared<GUI::Network::ThreadCapsule>(_baseId);
116 _baseId += 1;
117 PRETTY_INFO << "Setting the player name" << std::endl;
118 _networkManager->setPlayerName(_player);
119 PRETTY_INFO << "End of processing" << std::endl;
120 // PRETTY_INFO << "Initialising the connection with the server" << std::endl;
121 // _networkManager->setAddress(_ip, _port);
122 // PRETTY_SUCCESS << "Connection with ther server initialised" << std::endl;
123}
124
130
139std::string Main::_lowerText(const std::string &text)
140{
141 std::string lowerText = text;
142 if (lowerText.empty()) {
143 return lowerText;
144 }
145 std::transform(
146 lowerText.begin(),
147 lowerText.end(),
148 lowerText.begin(),
149 [](unsigned char c) {
150 return std::tolower(c);
151 }
152 );
153 return lowerText;
154}
155
164const bool Main::_isIpInRange(const std::string &ip) const
165{
166 std::istringstream iss(ip);
167 std::string segment;
168 int count = 0;
169
170 while (std::getline(iss, segment, '.')) {
171 if (count >= 4) {
172 return false;
173 }
174 try {
175 int octet = std::stoi(segment);
176 if (octet < 0 || octet > 255) {
177 return false;
178 }
179 }
180 catch (...) {
181 return false;
182 }
183 count++;
184 }
185
186 return count == 4;
187}
188
197const bool Main::_isPortCorrect(const unsigned int port) const
198{
199 return port >= 0 && port <= 65535;
200}
201
210const bool Main::_isFilePresent(const std::string &filepath) const
211{
212 return std::ifstream(filepath).good();
213}
214
223const bool Main::_isFrameLimitCorrect(const unsigned int frameLimit) const
224{
225 if (frameLimit < 10 || frameLimit > 1000) {
226 return false;
227 }
228 return true;
229}
230
239const bool Main::_isFontConfigurationCorrect(const TOMLLoader &node) const
240{
241 if (
242 !_isKeyPresentAndOfCorrectType(node, "name", toml::node_type::string) ||
243 !_isKeyPresentAndOfCorrectType(node, "path", toml::node_type::string)
244 ) {
245 return false;
246 }
247
248 return true;
249}
250
259const bool Main::_isIconConfigurationCorrect(const TOMLLoader &node) const
260{
261 if (
262 !_isKeyPresentAndOfCorrectType(node, "name", toml::node_type::string) ||
263 !_isKeyPresentAndOfCorrectType(node, "path", toml::node_type::string)
264 ) {
265 return false;
266 }
267 return true;
268}
269
278const bool Main::_isMusicConfigurationCorrect(const TOMLLoader &node) const
279{
280 if (
281 !_isKeyPresentAndOfCorrectType(node, "name", toml::node_type::string) ||
282 !_isKeyPresentAndOfCorrectType(node, "path", toml::node_type::string) ||
283 !_isKeyPresentAndOfCorrectType(node, "loop", toml::node_type::boolean) ||
284 !_isKeyPresentAndOfCorrectType(node, "volume", toml::node_type::integer)
285 ) {
286 return false;
287 }
288 return true;
289}
290
299const bool Main::_isSpriteConfigurationCorrect(const TOMLLoader &node) const
300{
301 if (
302 !_isKeyPresentAndOfCorrectType(node, "name", toml::node_type::string) ||
303 !_isKeyPresentAndOfCorrectType(node, "path", toml::node_type::string) ||
304 !_isKeyPresentAndOfCorrectType(node, "sprite_width", toml::node_type::integer) ||
305 !_isKeyPresentAndOfCorrectType(node, "sprite_height", toml::node_type::integer) ||
306 !_isKeyPresentAndOfCorrectType(node, "start_left", toml::node_type::boolean) ||
307 !_isKeyPresentAndOfCorrectType(node, "start_top", toml::node_type::boolean)
308 ) {
309 return false;
310 }
311 return true;
312}
313
322const bool Main::_isBackgroundConfigurationCorrect(const TOMLLoader &node) const
323{
324 if (
325 !_isKeyPresentAndOfCorrectType(node, "name", toml::node_type::string) ||
326 !_isKeyPresentAndOfCorrectType(node, "path", toml::node_type::string)
327 ) {
328 return false;
329 }
330 return true;
331}
332
343const bool Main::_isKeyPresentAndOfCorrectType(const TOMLLoader &node, const std::string &key, const toml::node_type &valueType) const
344{
345 if (!node.hasKey(key)) {
346 return false;
347 }
348 if (node.getValueType(key) != valueType) {
349 return false;
350 }
351 return true;
352}
353
359void Main::_initialiseConnection()
360{
361 std::string address = _ip + ":" + std::to_string(_port);
362 PRETTY_DEBUG << "Connecting to the server at " << address << std::endl;
363 _networkManager->initialize();
364 _networkManager->setAddress(_ip, _port);
365 _networkManager->startGame();
366 _connectionInitialised = _networkManager->isConnected();
367 if (_connectionInitialised) {
368 PRETTY_SUCCESS << "We are connected to the server" << std::endl;
369 } else {
370 PRETTY_WARNING << "We are not connected to the server" << std::endl;
371 }
372}
373
378void Main::_closeConnection()
379{
380 _networkManager->stopThread();
381 _connectionInitialised = _networkManager->isConnected();
382}
383
389std::uint32_t Main::_initialiseAudio()
390{
391 const std::string tomlPath = _tomlContent.getTOMLPath();
392 const std::string musicKey = "music";
393 const std::string musicKeyAlt = "musics";
394 std::vector<std::string> audios;
395 std::unordered_map<std::string, TOMLLoader> loadedAudios;
396
397 const TOMLLoader audio = _getTOMLNodeContent<CustomExceptions::InvalidConfigurationMusicType, CustomExceptions::NoMusicInConfigFile>(_tomlContent, musicKey, musicKeyAlt);
398
399 TOMLLoader tempNode(audio);
400
401 audios.push_back("mainMenu");
402 audios.push_back("bossFight");
403 audios.push_back("gameLoop");
404 audios.push_back("shooting");
405 audios.push_back("damage");
406 audios.push_back("dead");
407 audios.push_back("button");
408 audios.push_back("gameOver");
409 audios.push_back("success");
410
411 const std::string &expectedStringType = _tomlContent.getTypeAsString(toml::node_type::table);
412
413 PRETTY_INFO << "Getting the music configuration chunks" << std::endl;
414
415 for (std::string &iterator : audios) {
416 _updateLoadingText("Processing music '" + iterator + "'...");
417 if (!audio.hasKey(iterator)) {
418 throw CustomExceptions::NoTOMLKey(tomlPath, iterator);
419 }
420 loadedAudios[iterator] = tempNode;
421 if (audio.getValueType(iterator) != toml::node_type::table) {
422 throw CustomExceptions::InvalidTOMLKeyType(tomlPath, iterator, audio.getTypeAsString(iterator), expectedStringType);
423 }
424 loadedAudios[iterator].update(audio.getTable(iterator));
425 if (!_isMusicConfigurationCorrect(loadedAudios[iterator])) {
426 std::string userConfig = loadedAudios[iterator].getTOMLString();
427 throw CustomExceptions::InvalidMusicConfiguration(userConfig, iterator);
428 }
429 _updateLoadingText("Processing music '" + iterator + "'...[OK]");
430 }
431
432 PRETTY_INFO << "Initialising the musics" << std::endl;
433
434 for (std::unordered_map<std::string, TOMLLoader>::iterator it = loadedAudios.begin(); it != loadedAudios.end(); ++it) {
435 std::string application = it->first;
436 std::string name = it->second.getValue<std::string>("name");
437 std::string path = it->second.getValue<std::string>("path");
438 int volume = 100;
439 bool loop = false;
440
441 _updateLoadingText("Loading music '" + name + "'...");
442
443 if (_isKeyPresentAndOfCorrectType(it->second, "volume", toml::node_type::integer)) {
444 volume = it->second.getValue<int>("volume");
445 }
446 if (_isKeyPresentAndOfCorrectType(it->second, "loop", toml::node_type::boolean)) {
447 loop = it->second.getValue<bool>("loop");
448 }
449 std::shared_ptr<GUI::ECS::Components::MusicComponent> node = std::make_shared<GUI::ECS::Components::MusicComponent>(_baseId, path, name, application, volume, loop);
450 _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)].push_back(node);
451 _baseId++;
452 _updateLoadingText("Loading music '" + name + "'...[OK]");
453 }
454
455 PRETTY_SUCCESS << "The musics are loaded." << std::endl;
456 PRETTY_INFO << "Value of the base id: " << std::to_string(_baseId) << std::endl;
457 return _baseId;
458}
459
465std::uint32_t Main::_initialiseFonts()
466{
467 const std::string tomlPath = _tomlContent.getTOMLPath();
468 const std::string fontKey = "font";
469 const std::string fontKeyAlt = "fonts";
470 const TOMLLoader font = _getTOMLNodeContent<CustomExceptions::InvalidConfigurationFontType, CustomExceptions::NoFontInConfigFile>(_tomlContent, fontKey, fontKeyAlt);
471 std::unordered_map<std::string, TOMLLoader> loadedFonts;
472
473 const std::string titleFontNode = "title";
474 const std::string bodyFontNode = "body";
475 const std::string defaultFontNode = "default";
476 const std::string buttonFontNode = "button";
477
478 if (!font.hasKey(titleFontNode)) {
480 }
481 if (!font.hasKey(bodyFontNode)) {
483 }
484 if (!font.hasKey(defaultFontNode)) {
486 }
487 if (!font.hasKey(buttonFontNode)) {
489 }
490
491 TOMLLoader tempNode(font);
492
493 loadedFonts["title"] = tempNode;
494 loadedFonts["body"] = tempNode;
495 loadedFonts["default"] = tempNode;
496 loadedFonts["button"] = tempNode;
497
498
499 loadedFonts["body"].update(font.getTable(titleFontNode));
500 loadedFonts["title"].update(font.getTable(bodyFontNode));
501 loadedFonts["default"].update(font.getTable(defaultFontNode));
502 loadedFonts["button"].update(font.getTable(buttonFontNode));
503
504 if (!_isFontConfigurationCorrect(loadedFonts["title"])) {
505 const std::string userConfig = loadedFonts["title"].getTOMLString();
506 const std::string fontName = titleFontNode;
507 throw CustomExceptions::InvalidFontConfiguration(userConfig, fontName);
508 }
509 if (!_isFontConfigurationCorrect(loadedFonts["body"])) {
510 const std::string userConfig = loadedFonts["body"].getTOMLString();
511 const std::string fontName = bodyFontNode;
512 throw CustomExceptions::InvalidFontConfiguration(userConfig, fontName);
513 }
514 if (!_isFontConfigurationCorrect(loadedFonts["default"])) {
515 const std::string userConfig = loadedFonts["default"].getTOMLString();
516 const std::string fontName = defaultFontNode;
517 throw CustomExceptions::InvalidFontConfiguration(userConfig, fontName);
518 }
519 if (!_isFontConfigurationCorrect(loadedFonts["button"])) {
520 const std::string userConfig = loadedFonts["button"].getTOMLString();
521 const std::string fontName = buttonFontNode;
522 throw CustomExceptions::InvalidFontConfiguration(userConfig, fontName);
523 }
524
525
526 for (std::unordered_map<std::string, TOMLLoader>::iterator it = loadedFonts.begin(); it != loadedFonts.end(); ++it) {
527 std::string application = it->first;
528 PRETTY_INFO << "Font application = '" + application + "'" << std::endl;
529 std::string name = it->second.getValue<std::string>("name");
530 std::string path = it->second.getValue<std::string>("path");
531 int defaultSize = 50;
532 bool bold = false;
533 bool italic = false;
534
535 if (_isKeyPresentAndOfCorrectType(it->second, "default_size", toml::node_type::integer)) {
536 defaultSize = it->second.getValue<int>("default_size");
537 }
538 if (_isKeyPresentAndOfCorrectType(it->second, "bold", toml::node_type::boolean)) {
539 bold = it->second.getValue<bool>("bold");
540 }
541 if (_isKeyPresentAndOfCorrectType(it->second, "italic", toml::node_type::boolean)) {
542 italic = it->second.getValue<bool>("italic");
543 }
544 PRETTY_DEBUG << "Loading font '" << application << "' ... [LOADING]" << std::endl;
545 std::shared_ptr<GUI::ECS::Systems::Font> node = std::make_shared<GUI::ECS::Systems::Font>(_baseId, name, path, defaultSize, application, bold, italic);
546 PRETTY_DEBUG << "Font '" << application << "' [LOADED]" << std::endl;
547 PRETTY_DEBUG << "Storing in ecs entity" << std::endl;
548 _ecsEntities[typeid(GUI::ECS::Systems::Font)].push_back(node);
549 if (application == titleFontNode) {
550 _titleFontIndex = _ecsEntities[typeid(GUI::ECS::Systems::Font)].size() - 1;
551 }
552 if (application == bodyFontNode) {
553 _bodyFontIndex = _ecsEntities[typeid(GUI::ECS::Systems::Font)].size() - 1;
554 }
555 if (application == defaultFontNode) {
556 _defaultFontIndex = _ecsEntities[typeid(GUI::ECS::Systems::Font)].size() - 1;
557 }
558 if (application == buttonFontNode) {
559 _buttonFontIndex = _ecsEntities[typeid(GUI::ECS::Systems::Font)].size() - 1;
560 }
561 PRETTY_DEBUG << "Stored in ecs entity" << std::endl;
562 _baseId++;
563 }
564 PRETTY_INFO << "Value of the base id: " << std::to_string(_baseId) << std::endl;
565 return _baseId;
566}
567
568
569std::uint32_t Main::_initialiseIcon()
570{
571 const std::string iconKey = "icon";
572 const std::string iconKeyAlt = "icons";
573 const TOMLLoader sprites = _getTOMLNodeContent<CustomExceptions::InvalidIconConfiguration, CustomExceptions::NoIconInConfigFile>(_tomlContent, iconKey, iconKeyAlt);
574 std::unordered_map<std::string, TOMLLoader> loadedSprites;
575
576 PRETTY_INFO << "Getting the icon configuration chunks" << std::endl;
577
578 if (!_isIconConfigurationCorrect(sprites)) {
579 std::string iconName = "";
580 if (_isKeyPresentAndOfCorrectType(sprites, "name", toml::node_type::string)) {
581 iconName = sprites.getValue<std::string>("name");
582 }
583 throw CustomExceptions::InvalidIconConfiguration(sprites.getTOMLPath(), "", iconName, "");
584 }
585
586 _updateLoadingText("Getting icon information...");
587 const std::string name = sprites.getValue<std::string>("name");
588 const std::string path = sprites.getValue<std::string>("path");
589 int width = 256;
590 int height = 256;
591 int x = 0;
592 int y = 0;
593
594 if (_isKeyPresentAndOfCorrectType(sprites, "width", toml::node_type::integer)) {
595 const int tmpWidth = sprites.getValue<int>("width");
596 if (tmpWidth > 0) {
597 width = tmpWidth;
598 }
599 }
600 if (_isKeyPresentAndOfCorrectType(sprites, "height", toml::node_type::integer)) {
601 const int tmpHeight = sprites.getValue<int>("height");
602 if (tmpHeight > 0) {
603 height = tmpHeight;
604 }
605 }
606 if (_isKeyPresentAndOfCorrectType(sprites, "x", toml::node_type::integer)) {
607 const int tmpX = sprites.getValue<int>("x");
608 if (tmpX > 0) {
609 x = tmpX;
610 }
611 }
612 if (_isKeyPresentAndOfCorrectType(sprites, "y", toml::node_type::integer)) {
613 const int tmpY = sprites.getValue<int>("y");
614 if (tmpY > 0) {
615 y = tmpY;
616 }
617 }
618 _updateLoadingText("Getting icon information...[OK]");
619 _updateLoadingText("Loading icon...");
620 std::shared_ptr<GUI::ECS::Components::ImageComponent> icon = std::make_shared<GUI::ECS::Components::ImageComponent>(_baseId, path, name);
621 icon->setDimension({ width, height });
622 icon->setPosition({ x,y });
623 _baseId++;
624 _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)].push_back(icon);
625 _iconIndex = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)].size() - 1;
626 _updateLoadingText("Loading icon...[OK]");
627
628 return _baseId;
629}
630
636std::uint32_t Main::_initialiseSprites()
637{
638 const std::string spriteSheetKey = "spritesheets";
639 const std::string spriteSheetKeyAlt = "spritesheet";
640 const TOMLLoader sprites = _getTOMLNodeContent<CustomExceptions::InvalidConfigurationSpritesheetType, CustomExceptions::NoSpritesInConfigFile>(_tomlContent, spriteSheetKey, spriteSheetKeyAlt);
641 const std::string tomlPath = _tomlContent.getTOMLPath();
642 std::unordered_map<std::string, TOMLLoader> loadedSprites;
643
644 TOMLLoader tempNode(sprites);
645
646 PRETTY_INFO << "Getting the sprite configuration chunks" << std::endl;
647
648 unsigned int counter = 1;
649 std::string data = "Processed Sprites: \n";
650 const std::string &expectedStringType = _tomlContent.getTypeAsString(toml::node_type::table);
651
652 for (std::string &it : sprites.getKeys()) {
653 _updateLoadingText("Processing '" + it + "'...");
654 data += "\t" + std::to_string(counter) + " : " + "'" + it + "'\n";
655 PRETTY_INFO << "Processing sprite: '" << it << "'" << std::endl;
656 if (!sprites.hasKey(it)) {
657 throw CustomExceptions::NoTOMLKey(tomlPath, it);
658 }
659 loadedSprites[it] = tempNode;
660 if (sprites.getValueType(it) != toml::node_type::table) {
661 throw CustomExceptions::InvalidTOMLKeyType(tomlPath, it, sprites.getTypeAsString(it), expectedStringType);
662 }
663 loadedSprites[it].update(sprites.getTable(it));
664 if (!_isSpriteConfigurationCorrect(loadedSprites[it])) {
665 std::string userConfig = loadedSprites[it].getTOMLString();
667 }
668 counter++;
669 _updateLoadingText("Processing '" + it + "'...[OK]");
670 };
671 PRETTY_SUCCESS << data << std::endl;
672
673 PRETTY_INFO << "Initialising the sprites" << std::endl;
674
675 for (std::unordered_map<std::string, TOMLLoader>::iterator it = loadedSprites.begin(); it != loadedSprites.end(); ++it) {
676 std::string application = it->first;
677 std::string name = it->second.getValue<std::string>("name");
678 std::string path = it->second.getValue<std::string>("path");
679 int spriteWidth = it->second.getValue<int>("sprite_width");
680 int spriteHeight = it->second.getValue<int>("sprite_height");
681 bool startLeft = it->second.getValue<bool>("start_left");
682 bool startTop = it->second.getValue<bool>("start_top");
683 int initialFrame = 0;
684 int endFrame = (-1);
685 int frameDelay = 100;
686
687 if (it->second.hasKey("initial_frame")) {
688 initialFrame = it->second.getValue<int>("initial_frame");
689 }
690 if (it->second.hasKey("end_frame")) {
691 endFrame = it->second.getValue<int>("end_frame");
692 }
693 if (it->second.hasKey("frame_delay")) {
694 frameDelay = it->second.getValue<int>("frame_delay");
695 if (frameDelay < 0) {
696 std::string errMsg = "<A number between 0 and 2147483647 was expected, however, you entered: '";
697 errMsg += Recoded::myToString(frameDelay);
698 errMsg += "'>";
699 throw CustomExceptions::InvalidSpriteConfiguration(it->second.getTOMLString(), name, errMsg);
700 }
701 }
702
703 _updateLoadingText("Loading sprite '" + name + "'...");
704 PRETTY_INFO << "Loading sprite '" << name << "' [LOADING]" << std::endl;
705
706
707 PRETTY_INFO << "Processing Animation component, id: '" << Recoded::myToString(_baseId) << "'" << std::endl;
708 PRETTY_INFO << "Passed parameters are: " <<
709 "name='" << name << "', " <<
710 "path='" << path << "', " <<
711 "sprite_width=" << Recoded::myToString(spriteWidth) << ", " <<
712 "sprite_height=" << Recoded::myToString(spriteHeight) << ", " <<
713 "start_left=" << Recoded::myToString(startLeft) << ", " <<
714 "start_top=" << Recoded::myToString(startTop) << ", " <<
715 "initial_frame=" << Recoded::myToString(initialFrame) << ", " <<
716 "end_frame=" << Recoded::myToString(endFrame) <<
717 "frame_delay=" << Recoded::myToString(frameDelay) << std::endl;
718
719 std::shared_ptr<GUI::ECS::Components::AnimationComponent> animationPointer = std::make_shared<GUI::ECS::Components::AnimationComponent>(_baseId, path, spriteWidth, spriteHeight, startLeft, startTop, initialFrame, endFrame);
720 _ecsEntities[typeid(GUI::ECS::Components::AnimationComponent)].push_back(animationPointer);
721 _baseId++;
722 PRETTY_DEBUG << "Setting animation delay to : '" << Recoded::myToString(frameDelay) << "'" << std::endl;
723 animationPointer->setDelay(frameDelay);
724 PRETTY_INFO << "Animation component info: " << *animationPointer << std::endl;
725 PRETTY_SUCCESS << "Animation component processed" << std::endl;
726 PRETTY_INFO << "Creating sprite id '" << name << "', id: '" << Recoded::myToString(_baseId) << "'" << std::endl;
727 PRETTY_DEBUG << "Setting animation, animation id: '" << Recoded::myToString(animationPointer->getEntityNodeId()) << "', sprite entity id: '" << _baseId << "'" << std::endl;
728 std::shared_ptr<GUI::ECS::Components::SpriteComponent> spriteEntity = std::make_shared<GUI::ECS::Components::SpriteComponent>(_baseId, name, *animationPointer);
729 PRETTY_SUCCESS << "Sprite entity added to sprite '" << name << "'" << std::endl;
730 PRETTY_SUCCESS << "Sprite '" << name << "' loaded" << std::endl;
731 spriteEntity->setApplication(application);
732 PRETTY_INFO << "Storing " << name << " into the ecs" << std::endl;
733 _ecsEntities[typeid(GUI::ECS::Components::SpriteComponent)].push_back(spriteEntity);
734 PRETTY_SUCCESS << name << " stored into the ecs entity" << std::endl;
735 _baseId++;
736
737 PRETTY_SUCCESS << "Sprite '" << name << "' [LOADED]" << std::endl;
738 _updateLoadingText("Loading sprite '" + name + "'...[OK]");
739
740 PRETTY_INFO << "buffer line1 between two sprite loads" << std::endl;
741 PRETTY_INFO << "buffer line2 between two sprite loads" << std::endl;
742 PRETTY_INFO << "buffer line3 between two sprite loads" << std::endl;
743 PRETTY_INFO << "buffer line4 between two sprite loads" << std::endl;
744 }
745
746 PRETTY_SUCCESS << "The sprites are loaded." << std::endl;
747 PRETTY_INFO << "Value of the base id: " << std::to_string(_baseId) << std::endl;
748 return _baseId;
749}
750
756std::uint32_t Main::_initialiseBackgrounds()
757{
758 const std::string iconKey = "backgrounds";
759 const std::string iconKeyAlt = "background";
760 const std::string path = _tomlContent.getTOMLPath();
761 const TOMLLoader backgrounds = _getTOMLNodeContent<CustomExceptions::InvalidBackgroundConfiguration, CustomExceptions::NoBackgroundInConfigFile>(_tomlContent, iconKey, iconKeyAlt);
762 std::unordered_map<std::string, TOMLLoader> loadedBackgrounds;
763 std::vector<std::string> systemBackgrounds;
764
765 systemBackgrounds.push_back("mainMenu");
766 systemBackgrounds.push_back("settings");
767 systemBackgrounds.push_back("gameOver");
768 systemBackgrounds.push_back("connectionFailed");
769
770 PRETTY_INFO << "Getting the background configuration chunks" << std::endl;
771
772 for (std::string &item : backgrounds.getKeys()) {
773 std::string checkMsg = "Checking for the presence of '" + item + "' in the config file...";
774 _updateLoadingText(checkMsg);
775 if (std::find(systemBackgrounds.begin(), systemBackgrounds.end(), item) != systemBackgrounds.end() && !backgrounds.hasKey(item)) {
776 PRETTY_CRITICAL << "No TOML key '" << item << "' in the file path '" << path << "'." << std::endl;
778 }
779 if (!_isKeyPresentAndOfCorrectType(backgrounds, item, toml::node_type::table)) {
780 PRETTY_CRITICAL << "The key '" << item << "' is not a table in the file." << std::endl;
782 }
783 loadedBackgrounds[item] = backgrounds.getTable(item);
784 _updateLoadingText(checkMsg + "[OK]");
785 }
786
787 std::unordered_map<std::string, TOMLLoader>::iterator it;
788
789 for (it = loadedBackgrounds.begin(); it != loadedBackgrounds.end(); it++) {
790 PRETTY_INFO << "Loading background: " << it->first << std::endl;
791 _updateLoadingText("Loading background '" + it->first + "'...");
792 std::string name = it->second.getValue<std::string>("name");
793 std::string path = it->second.getValue<std::string>("path");
794 int x = 0;
795 int y = 0;
796 bool allowAsLevelBackground = false;
797 if (_isKeyPresentAndOfCorrectType(it->second, "x", toml::node_type::integer)) {
798 int tmpX = it->second.getValue<int>("x");
799 if (tmpX < 0) {
800 PRETTY_CRITICAL << "The value of 'x' for the background '" << name << "'." << std::endl;
801 throw CustomExceptions::InvalidBackgroundConfiguration(path, name, "x", "<The x value must be a number greater or equal to 0>");
802 }
803 x = tmpX;
804 }
805 if (_isKeyPresentAndOfCorrectType(it->second, "y", toml::node_type::integer)) {
806 int tmpY = it->second.getValue<int>("y");
807 if (tmpY < 0) {
808 PRETTY_CRITICAL << "The value of 'y' for the background '" << name << "'." << std::endl;
809 throw CustomExceptions::InvalidBackgroundConfiguration(path, name, "y", "<The y value must be a number greater or equal to 0>");
810 }
811 y = tmpY;
812 }
813 if (_isKeyPresentAndOfCorrectType(it->second, "allow_as_level_background", toml::node_type::boolean)) {
814 bool allowAsLevelBackground = it->second.getValue<bool>("allow_as_level_background");
815 }
816 std::shared_ptr<GUI::ECS::Components::ImageComponent> node = std::make_shared<GUI::ECS::Components::ImageComponent>(_baseId, path, name, it->first);
817 _baseId++;
818 node->setPosition({ x, y });
819 node->setLevelBackgroundCompatible(allowAsLevelBackground);
820 _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)].push_back(node);
821 _updateLoadingText("Loading background '" + it->first + "'...[OK]");
822 PRETTY_INFO << "buffer line1 between two background loads" << std::endl;
823 PRETTY_INFO << "buffer line2 between two background loads" << std::endl;
824 PRETTY_INFO << "buffer line3 between two background loads" << std::endl;
825 PRETTY_INFO << "buffer line4 between two background loads" << std::endl;
826 }
827
828 return _baseId;
829}
830
835void Main::_initialiseRessources()
836{
837 std::uint32_t _baseId = 0;
838 _ecsEntities.clear();
839
840 PRETTY_INFO << "========================== Displaying loaded toml data. ==========================" << std::endl;
841 _tomlContent.printTOML();
842 PRETTY_SUCCESS << "========================== Displayed loaded toml data. ==========================" << std::endl;
843
844 std::shared_ptr<GUI::ECS::Systems::Window> window = std::make_shared<GUI::ECS::Systems::Window>(_baseId, _windowWidth, _windowHeight, _windowTitle);
845 PRETTY_DEBUG << "Setting the window position to : " << std::pair<int, int>({ _windowX, _windowY }) << std::endl;
846 window->setPosition({ _windowX, _windowY });
847 _baseId++;
848 std::shared_ptr<GUI::ECS::Systems::EventManager> event = std::make_shared<GUI::ECS::Systems::EventManager>(_baseId);
849 _baseId++;
850
851 window->setFullScreen(_windowFullscreen);
852 window->setFramerateLimit(_windowFrameLimit);
853
854 _ecsEntities[typeid(GUI::ECS::Systems::Window)].push_back(window);
855 _ecsEntities[typeid(GUI::ECS::Systems::EventManager)].push_back(event);
856
857 _mainWindowIndex = _ecsEntities[typeid(GUI::ECS::Systems::Window)].size() - 1;
858
859 _mainEventIndex = _ecsEntities[typeid(GUI::ECS::Systems::EventManager)].size() - 1;
860
861 _baseId = _initialiseFonts();
862
863 if (_baseId == 0 || _ecsEntities[typeid(GUI::ECS::Systems::Font)].size() == 0) {
864 PRETTY_CRITICAL << "There are no fonts that were loaded in the program, aborting." << std::endl;
865 throw CustomExceptions::NoFont("<No fonts are loaded into the program>");
866 }
867
868 PRETTY_INFO << "Fetching loaded font for displaying a loading text on screen." << std::endl;
869 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> firstFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>, CustomExceptions::NoFont>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_defaultFontIndex], true);
870 if (!firstFontCapsule.has_value()) {
872 }
873
874 GUI::ECS::Systems::Font firstFont = *firstFontCapsule.value();
875 std::shared_ptr<GUI::ECS::Components::TextComponent> loading = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, firstFont, "Loading...", 20, GUI::ECS::Systems::Colour::Aqua, GUI::ECS::Systems::Colour::Aquamarine, GUI::ECS::Systems::Colour::Chartreuse1);
876 _baseId++;
877 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(loading);
878 window->draw(*loading);
879 window->display();
880 _loadingIndex = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].size() - 1;
881
882
883 std::shared_ptr<SoundLib> soundLib = std::make_shared<SoundLib>(_baseId, _ecsEntities);
884 _ecsEntities[typeid(SoundLib)].push_back(soundLib);
885 _baseId += 1;
886 PRETTY_SUCCESS << "Sound library initialised" << std::endl;
887
888 _baseId = _initialiseIcon();
889 _baseId = _initialiseBackgrounds();
890 _baseId = _initialiseSprites();
891 _baseId = _initialiseAudio();
892 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
893 std::cout << "Sound is empty" << std::endl;
894 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
895 return;
896 }
897 std::optional<std::shared_ptr<SoundLib>> internalSoundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
898 if (!(internalSoundLib.has_value())) {
899 std::cout << "Sound lib not found" << std::endl;
900 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
901 return;
902 }
903 internalSoundLib.value()->updateSoundLib(_ecsEntities);
904 PRETTY_INFO << "Final value of the base Id: " << std::to_string(_baseId) << std::endl;
905}
906
907void Main::_updateLoadingText(const std::string &detail)
908{
909 PRETTY_DEBUG << "Updating loading display" << std::endl;
910 std::vector<std::any> windows = _ecsEntities[typeid(GUI::ECS::Systems::Window)];
911 std::vector<std::any> eventManagers = _ecsEntities[typeid(GUI::ECS::Systems::EventManager)];
912 std::vector<std::any> textComponents = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
913
914 if (_mainWindowIndex > windows.size()) {
915 PRETTY_ERROR << "Index out of bounds." << std::endl;
916 throw CustomExceptions::NoWindow("The window index you tried to access does not exist, the index was: " + Recoded::myToString(_mainWindowIndex));
917 }
918 std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> windowCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(windows[_mainWindowIndex], true, "The type of the window is unknown, system error: ");
919 if (!windowCapsule.has_value()) {
920 PRETTY_CRITICAL << "There is no window to access" << std::endl;
921 throw CustomExceptions::NoWindow("The window index you tried to access does not exist, the index was: " + Recoded::myToString(_mainWindowIndex));
922 }
923 std::shared_ptr<GUI::ECS::Systems::Window> window = windowCapsule.value();
924
925 if (_mainEventIndex > eventManagers.size()) {
926 PRETTY_ERROR << "Index out of bounds." << std::endl;
927 throw CustomExceptions::NoEventManager("The event manager index you tried to access does not exist, the index was: " + Recoded::myToString(_mainEventIndex));
928 }
929 std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> eventManagerCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>, CustomExceptions::NoEventManager>(eventManagers[_mainEventIndex], true, "The type of the event manager is unknown, system error: ");
930 if (!eventManagerCapsule.has_value()) {
931 PRETTY_CRITICAL << "There is no event manager to access" << std::endl;
932 throw CustomExceptions::NoEventManager("The event manager index you tried to access does not exist, the index was: " + Recoded::myToString(_mainEventIndex));
933 }
934 std::shared_ptr<GUI::ECS::Systems::EventManager> event = eventManagerCapsule.value();
935
936 if (_loadingIndex > textComponents.size()) {
937 PRETTY_ERROR << "Index out of bounds." << std::endl;
938 throw CustomExceptions::NoText("The text component index you tried to access does not exist, the index was: " + Recoded::myToString(_loadingIndex));
939 }
940 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>, CustomExceptions::NoText>(textComponents[_loadingIndex], true, "The type of the text component is unknown, system error: ");
941 if (!textCapsule.has_value()) {
942 PRETTY_CRITICAL << "There is no text to access" << std::endl;
943 throw CustomExceptions::NoText("The text index you tried to access does not exist, the index was: " + Recoded::myToString(_loadingIndex));
944 }
945 std::shared_ptr<GUI::ECS::Components::TextComponent> text = textCapsule.value();
946
947 if (!window->isOpen()) {
948 throw CustomExceptions::NoWindow("There is no window to draw on!");
949 }
950 event->processEvents(*window);
951 if (!window->isOpen()) {
952 throw CustomExceptions::NoWindow("There is no window to draw on!");
953 }
954
955 text->update(event->getMouseInfo());
956 text->setText(detail);
957 window->clear();
958 window->draw(*text);
959 window->display();
960 PRETTY_SUCCESS << "Loading text updated" << std::endl;
961}
962
963void Main::_updateMouseForAllRendererables(const GUI::ECS::Systems::MouseInfo &mouse)
964{
965 PRETTY_INFO << "Updating mouse information for renderable components." << std::endl;
966 std::vector<std::any> sprites = _ecsEntities[typeid(GUI::ECS::Components::SpriteComponent)];
967 std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
968 std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
969 std::vector<std::any> shapes = _ecsEntities[typeid(GUI::ECS::Components::ShapeComponent)];
970 std::vector<std::any> images = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
971
972 for (unsigned int index = 0; index < sprites.size(); index++) {
973 PRETTY_INFO << "Processing index for sprite : " << std::to_string(index) << std::endl;
974 try {
975 std::shared_ptr<GUI::ECS::Components::SpriteComponent> sprite = std::any_cast<std::shared_ptr<GUI::ECS::Components::SpriteComponent>>(sprites[index]);
976 sprite->update(mouse);
977 }
978 catch (std::bad_any_cast &e) {
979 PRETTY_ERROR << "Error casting sprite component, system error: " + std::string(e.what()) << std::endl;
980 }
981 }
982 for (unsigned int index = 0; index < texts.size(); index++) {
983 PRETTY_INFO << "Processing index for text : " << std::to_string(index) << std::endl;
984 try {
985 std::shared_ptr<GUI::ECS::Components::TextComponent> text = std::any_cast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(texts[index]);
986 text->update(mouse);
987 }
988 catch (std::bad_any_cast &e) {
989 PRETTY_ERROR << "Error casting text component, system error: " + std::string(e.what()) << std::endl;
990 }
991 }
992 for (unsigned int index = 0; index < buttons.size(); index++) {
993 PRETTY_INFO << "Processing index for button : " << std::to_string(index) << std::endl;
994 try {
995 std::shared_ptr<GUI::ECS::Components::ButtonComponent> button = std::any_cast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttons[index]);
996 button->update(mouse);
997 }
998 catch (std::bad_any_cast &e) {
999 PRETTY_ERROR << "Error casting button component, system error: " + std::string(e.what()) << std::endl;
1000 }
1001 }
1002 for (unsigned int index = 0; index < shapes.size(); index++) {
1003 PRETTY_INFO << "Processing index for shape : " << std::to_string(index) << std::endl;
1004 try {
1005 std::shared_ptr<GUI::ECS::Components::ShapeComponent> shape = std::any_cast<std::shared_ptr<GUI::ECS::Components::ShapeComponent>>(shapes[index]);
1006 shape->update(mouse);
1007 }
1008 catch (std::bad_any_cast &e) {
1009 PRETTY_ERROR << "Error casting shape component, system error: " + std::string(e.what()) << std::endl;
1010 }
1011 }
1012 for (unsigned int index = 0; index < images.size(); index++) {
1013 PRETTY_INFO << "Processing index for image : " << std::to_string(index) << std::endl;
1014 try {
1015 std::shared_ptr<GUI::ECS::Components::ImageComponent> image = std::any_cast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(images[index]);
1016 image->update(mouse);
1017 }
1018 catch (std::bad_any_cast &e) {
1019 PRETTY_ERROR << "Error casting shape component, system error: " + std::string(e.what()) << std::endl;
1020 }
1021 }
1022 PRETTY_SUCCESS << "Updated mouse information for renderable components." << std::endl;
1023}
1024
1030void Main::_sendAllPackets()
1031{
1032 PRETTY_DEBUG << "Sending any packets that have been buffered and not sent" << std::endl;
1033 // GUI::Network::MessageNode item;
1034 // item.id = 0;
1035 // item.info.assetId = 0;
1036 // item.info.coords = { 0,0 };
1037 // item.info.status = 0;
1038 // item.info.username = "user";
1039 // item.type = GUI::Network::MessageType::ERROR;
1040 // if (_networkManager->isConnected()){
1041 // _networkManager->sendMessage(item);
1042 // }
1043};
1044
1050void Main::_processIncommingPackets()
1051{
1052 PRETTY_DEBUG << "Getting the buffer from the incoming packets" << std::endl;
1053 _bufferPackets.clear();
1054 const bool connected = _networkManager->isConnected();
1055 PRETTY_DEBUG << "Connection status: " << Recoded::myToString(connected) << std::endl;
1056 if (connected) {
1057 _bufferPackets = _networkManager->getReceivedMessages();
1058 PRETTY_DEBUG << "Buffer packet size: " << Recoded::myToString(_bufferPackets.size()) << std::endl;
1059 }
1060 PRETTY_DEBUG << "Out of _processIncommingPackets" << std::endl;
1061}
1062
1090const std::string Main::_getIpChunk(const unsigned int index, const std::string &defaultValue) const
1091{
1092 PRETTY_DEBUG << "In _getIpChunk" << std::endl;
1093
1094 PRETTY_DEBUG << "Handling edge case when the _ip is empty" << std::endl;
1095 if (_ip.empty()) {
1096 PRETTY_DEBUG << "_ip is empty, returning defaultValue" << std::endl;
1097 return defaultValue;
1098 }
1099
1100 std::string resp;
1101 size_t startPos = 0;
1102 size_t dotPos = 0;
1103 unsigned int currentIndex = 0;
1104
1105 PRETTY_DEBUG << "Looping through the dots in the IP address." << std::endl;
1106 while (true) {
1107 PRETTY_DEBUG << "Finding the next dot" << std::endl;
1108 dotPos = _ip.find('.', startPos);
1109 if (dotPos == std::string::npos) {
1110 PRETTY_DEBUG << "No more dots found, returning the rest of the string" << std::endl;
1111 break;
1112 }
1113
1114 if (currentIndex == index) {
1115 resp = _ip.substr(startPos, dotPos - startPos);
1116 PRETTY_DEBUG << "Found node at index " << index << ": " << resp << std::endl;
1117 return resp;
1118 }
1119
1120 PRETTY_DEBUG << "Moving to the next segment after the current dot" << std::endl;
1121 startPos = dotPos + 1;
1122 ++currentIndex;
1123 }
1124
1125 if (currentIndex == index) {
1126 PRETTY_DEBUG << "Returning the content after the last dot if any" << std::endl;
1127 PRETTY_DEBUG << "Getting the part after the last dot" << std::endl;
1128 resp = _ip.substr(startPos);
1129 PRETTY_DEBUG << "Found node at last index: " << resp << std::endl;
1130 if (resp.empty()) {
1131 PRETTY_DEBUG << "Returning the defaultValue because resp is empty" << std::endl;
1132 return defaultValue;
1133 }
1134 return resp;
1135 }
1136
1137 PRETTY_DEBUG << "No dot was found or index was too large, returning the default value.\n"
1138 << "Content of defaultValue: " << defaultValue << std::endl;
1139 return defaultValue;
1140}
1141
1158const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> Main::_getTextComponent(const std::string &textComponentKey)
1159{
1160 const std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
1161
1162 PRETTY_DEBUG << "texts.size() = " << Recoded::myToString(texts.size()) << std::endl;
1163
1164 for (std::any node : texts) {
1165 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> chunk = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(node, false);
1166 if (node.has_value()) {
1167 PRETTY_DEBUG << "node type: '" << node.type().name() << "'" << std::endl;
1168 }
1169 if (!chunk.has_value()) {
1170 PRETTY_DEBUG << "Text component is empty" << std::endl;
1171 continue;
1172 }
1173 if (chunk.value()->getApplication() == textComponentKey || chunk.value()->getName() == textComponentKey) {
1174 PRETTY_DEBUG << "Found node with key: " << chunk.value()->getApplication() << std::endl;
1175 return chunk;
1176 }
1177 }
1178 PRETTY_DEBUG << "No matching text component found" << std::endl;
1179 return std::nullopt;
1180}
1181
1199const std::string Main::_incrementIpV4Node(const std::string &v4Node)
1200{
1201 if (v4Node == "0" || v4Node == "000") {
1202 return "1";
1203 }
1204 try {
1205 const unsigned int v4int = std::max({ std::stoi(v4Node), 0 });
1206 if (v4int < 255) {
1207 return std::to_string(v4int + 1);
1208 } else {
1209 return "0";
1210 }
1211 }
1212 catch (std::invalid_argument &e) {
1213 PRETTY_WARNING << "The argument passed is not a number, you entered: '"
1214 << v4Node << "', stoi error: '" << std::string(e.what()) << "'"
1215 << ", defaulting to: '0'"
1216 << std::endl;
1217 return "0";
1218 }
1219}
1220
1238const std::string Main::_decrementIpV4Node(const std::string &v4Node)
1239{
1240 try {
1241 const unsigned int v4int = std::max({ std::stoi(v4Node), 0 });
1242 if (v4int > 0) {
1243 return std::to_string(v4int - 1);
1244 } else {
1245 return "255";
1246 }
1247 }
1248 catch (std::invalid_argument &e) {
1249 PRETTY_WARNING << "The argument passed is not a number, you entered: '"
1250 << v4Node << "', stoi error: '" << std::string(e.what()) << "'"
1251 << ", defaulting to: '0'"
1252 << std::endl;
1253 return "0";
1254 }
1255}
1256
1272const std::string Main::_incrementPortCounter(const std::string &portSection)
1273{
1274 if (portSection == "0" || portSection == "000") {
1275 return "1";
1276 }
1277 try {
1278 const unsigned int port = std::max({ std::stoi(portSection), 0 });
1279 if (port < _maximumPortRange) {
1280 return std::to_string(port + 1);
1281 } else {
1282 return "0";
1283 }
1284 }
1285 catch (std::invalid_argument &e) {
1286 PRETTY_WARNING << "The argument passed is not a number, you entered: '"
1287 << portSection << "', stoi error: '" << std::string(e.what()) << "'"
1288 << ", defaulting to: '0'"
1289 << std::endl;
1290 return "0";
1291 }
1292}
1293
1309const std::string Main::_decrementPortCounter(const std::string &portSection)
1310{
1311 try {
1312 const unsigned int port = std::max({ std::stoi(portSection), 0 });
1313 if (port > 0) {
1314 return std::to_string(port - 1);
1315 } else {
1316 return std::to_string(_maximumPortRange);
1317 }
1318 }
1319 catch (std::invalid_argument &e) {
1320 PRETTY_WARNING << "The argument passed is not a number, you entered: '"
1321 << portSection << "', stoi error: '" << std::string(e.what()) << "'"
1322 << ", defaulting to: '0'"
1323 << std::endl;
1324 return "0";
1325 }
1326}
1327
1334void Main::_incrementIpChunkOne()
1335{
1336 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1337 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1338 events->flushEvents();
1339 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4FirstChunkKey);
1340 if (!text.has_value()) {
1341 PRETTY_ERROR << "Could not find the text component for the first IP chunk." << std::endl;
1342 return;
1343 }
1344 const std::string currentChunk = text.value()->getText();
1345 const std::string newChunk = _incrementIpV4Node(currentChunk);
1346 text.value()->setText(newChunk);
1347 PRETTY_DEBUG << "The first chunk has it's value that has been set to: '"
1348 << newChunk << "', the previous value was: '" << currentChunk << "'"
1349 << std::endl;
1350}
1351
1358void Main::_incrementIpChunkTwo()
1359{
1360 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1361 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1362 events->flushEvents();
1363 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4SecondChunkKey);
1364 if (!text.has_value()) {
1365 PRETTY_ERROR << "Could not find the text component for the second IP chunk." << std::endl;
1366 return;
1367 }
1368 const std::string currentChunk = text.value()->getText();
1369 const std::string newChunk = _incrementIpV4Node(currentChunk);
1370 text.value()->setText(newChunk);
1371 PRETTY_DEBUG << "The second chunk has it's value that has been set to: '"
1372 << newChunk << "', the previous value was: '" << currentChunk << "'"
1373 << std::endl;
1374}
1375
1382void Main::_incrementIpChunkThree()
1383{
1384 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1385 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1386 events->flushEvents();
1387 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4ThirdChunkKey);
1388 if (!text.has_value()) {
1389 PRETTY_ERROR << "Could not find the text component for the third IP chunk." << std::endl;
1390 return;
1391 }
1392 const std::string currentChunk = text.value()->getText();
1393 const std::string newChunk = _incrementIpV4Node(currentChunk);
1394 text.value()->setText(newChunk);
1395 PRETTY_DEBUG << "The third chunk has it's value that has been set to: '"
1396 << newChunk << "', the previous value was: '" << currentChunk << "'"
1397 << std::endl;
1398}
1399
1406void Main::_incrementIpChunkFour()
1407{
1408 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1409 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1410 events->flushEvents();
1411 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4FourthChunkKey);
1412 if (!text.has_value()) {
1413 PRETTY_ERROR << "Could not find the text component for the fourth IP chunk." << std::endl;
1414 return;
1415 }
1416 const std::string currentChunk = text.value()->getText();
1417 const std::string newChunk = _incrementIpV4Node(currentChunk);
1418 text.value()->setText(newChunk);
1419 PRETTY_DEBUG << "The fourth chunk has it's value that has been set to: '"
1420 << newChunk << "', the previous value was: '" << currentChunk << "'"
1421 << std::endl;
1422}
1423
1424
1431void Main::_incrementPortChunk()
1432{
1433 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1434 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1435 events->flushEvents();
1436 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_portV4ChunkKey);
1437 if (!text.has_value()) {
1438 PRETTY_ERROR << "Could not find the text component for the port chunk." << std::endl;
1439 return;
1440 }
1441 const std::string currentChunk = text.value()->getText();
1442 const std::string newChunk = _incrementPortCounter(currentChunk);
1443 text.value()->setText(newChunk);
1444 PRETTY_DEBUG << "The port chunk has it's value that has been set to: '"
1445 << newChunk << "', the previous value was: '" << currentChunk << "'"
1446 << std::endl;
1447}
1448
1449
1456void Main::_decrementIpChunkOne()
1457{
1458 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1459 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1460 events->flushEvents();
1461 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4FirstChunkKey);
1462 if (!text.has_value()) {
1463 PRETTY_ERROR << "Could not find the text component for the first IP chunk." << std::endl;
1464 return;
1465 }
1466 const std::string currentChunk = text.value()->getText();
1467 const std::string newChunk = _decrementIpV4Node(currentChunk);
1468 text.value()->setText(newChunk);
1469 PRETTY_DEBUG << "The first chunk has it's value that has been set to: '"
1470 << newChunk << "', the previous value was: '" << currentChunk << "'"
1471 << std::endl;
1472}
1473
1480void Main::_decrementIpChunkTwo()
1481{
1482 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1483 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1484 events->flushEvents();
1485 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4SecondChunkKey);
1486 if (!text.has_value()) {
1487 PRETTY_ERROR << "Could not find the text component for the second IP chunk." << std::endl;
1488 return;
1489 }
1490 const std::string currentChunk = text.value()->getText();
1491 const std::string newChunk = _decrementIpV4Node(currentChunk);
1492 text.value()->setText(newChunk);
1493 PRETTY_DEBUG << "The second chunk has it's value that has been set to: '"
1494 << newChunk << "', the previous value was: '" << currentChunk << "'"
1495 << std::endl;
1496}
1497
1504void Main::_decrementIpChunkThree()
1505{
1506 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1507 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1508 events->flushEvents();
1509 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4ThirdChunkKey);
1510 if (!text.has_value()) {
1511 PRETTY_ERROR << "Could not find the text component for the third IP chunk." << std::endl;
1512 return;
1513 }
1514 const std::string currentChunk = text.value()->getText();
1515 const std::string newChunk = _decrementIpV4Node(currentChunk);
1516 text.value()->setText(newChunk);
1517 PRETTY_DEBUG << "The third chunk has it's value that has been set to: '"
1518 << newChunk << "', the previous value was: '" << currentChunk << "'"
1519 << std::endl;
1520}
1521
1528void Main::_decrementIpChunkFour()
1529{
1530 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1531 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1532 events->flushEvents();
1533 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_ipV4FourthChunkKey);
1534 if (!text.has_value()) {
1535 PRETTY_ERROR << "Could not find the text component for the fourth IP chunk." << std::endl;
1536 return;
1537 }
1538 const std::string currentChunk = text.value()->getText();
1539 const std::string newChunk = _decrementIpV4Node(currentChunk);
1540 text.value()->setText(newChunk);
1541 PRETTY_DEBUG << "The fourth chunk has it's value that has been set to: '"
1542 << newChunk << "', the previous value was: '" << currentChunk << "'"
1543 << std::endl;
1544}
1545
1546
1553void Main::_decrementPortChunk()
1554{
1555 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1556 PRETTY_DEBUG << "Flushing cached events" << std::endl;
1557 events->flushEvents();
1558 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> text = _getTextComponent(_portV4ChunkKey);
1559 if (!text.has_value()) {
1560 PRETTY_ERROR << "Could not find the text component for the port chunk." << std::endl;
1561 return;
1562 }
1563 const std::string currentChunk = text.value()->getText();
1564 const std::string newChunk = _decrementPortCounter(currentChunk);
1565 text.value()->setText(newChunk);
1566 PRETTY_DEBUG << "The port chunk has it's value that has been set to: '"
1567 << newChunk << "', the previous value was: '" << currentChunk << "'"
1568 << std::endl;
1569}
1570
1583const std::shared_ptr<GUI::ECS::Systems::EventManager> Main::_getEventManager()
1584{
1585 PRETTY_DEBUG << "Getting the event manager component" << std::endl;
1586 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(_ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0], false);
1587 if (!event_ptr.has_value()) {
1588 throw CustomExceptions::NoEventManager("<std::any un-casting failed>");
1589 }
1590 PRETTY_SUCCESS << "Event manager component found" << std::endl;
1591 return event_ptr.value();
1592}
1593
1611const std::shared_ptr<GUI::ECS::Components::TextComponent> Main::_createText(const std::string &application, const std::string &name, const std::string &text, const GUI::ECS::Systems::Font &font, const unsigned int size, const GUI::ECS::Systems::Colour &normal, const GUI::ECS::Systems::Colour &hover, const GUI::ECS::Systems::Colour &clicked)
1612{
1613 std::shared_ptr<GUI::ECS::Components::TextComponent> textNode = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, font, text, size);
1614 textNode->setApplication(application);
1615 textNode->setName(name);
1616 textNode->setNormalColor(normal);
1617 textNode->setHoverColor(hover);
1618 textNode->setClickedColor(clicked);
1619 PRETTY_DEBUG << "Ecs before push_backs:\n" << "- TextComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::TextComponent)].size()) << std::endl;
1620 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(textNode);
1621 PRETTY_DEBUG << "Ecs after push_backs:\n" << "- TextComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::TextComponent)].size()) << std::endl;
1622 _baseId += 1;
1623 return textNode;
1624}
1625
1643const std::shared_ptr<GUI::ECS::Components::ButtonComponent> Main::_createButton(const std::string &application, const std::string &title, std::function<void()> callback, const std::string &callbackName, const int width, const int height, const int textSize, const GUI::ECS::Systems::Colour &bg, const GUI::ECS::Systems::Colour &normal, const GUI::ECS::Systems::Colour &hover, const GUI::ECS::Systems::Colour &clicked, const std::shared_ptr<GUI::ECS::Systems::Font> &textFont)
1644{
1645 const std::string errMsgFont = "<Required font not found for the text of the button>, system error: ";
1646 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> fontInstance;
1647 if (textFont == nullptr) {
1648 fontInstance = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>, CustomExceptions::NoFont>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_bodyFontIndex], true, errMsgFont);
1649 if (!fontInstance.has_value()) {
1650 PRETTY_CRITICAL << "There is no font to be extracted for creating the body text of the unknown screen screen." << std::endl;
1651 throw CustomExceptions::NoFont(errMsgFont);
1652 }
1653 } else {
1654 fontInstance.emplace(textFont);
1655 }
1656 std::shared_ptr<GUI::ECS::Components::ShapeComponent> shapeItem = std::make_shared<GUI::ECS::Components::ShapeComponent>(_baseId);
1657 _baseId += 1;
1658 shapeItem->setShape(std::pair<float, float>(width, height));
1659 shapeItem->setNormalColor(bg);
1660 shapeItem->setHoverColor(bg);
1661 shapeItem->setClickedColor(bg);
1662 shapeItem->setApplication(std::string(application + "Shape"));
1663
1664 std::shared_ptr<GUI::ECS::Components::TextComponent> textItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(fontInstance.value()), title, textSize, normal, hover, clicked);
1665 textItem->setApplication(std::string(application + "Text"));
1666 _baseId += 1;
1667 std::shared_ptr<GUI::ECS::Components::ButtonComponent> buttonItem = std::make_shared<GUI::ECS::Components::ButtonComponent>(_baseId, *shapeItem, *textItem);
1668 buttonItem->setCallback(callback, callbackName);
1669 buttonItem->setApplication(application);
1670 _baseId += 1;
1671 PRETTY_DEBUG << "Ecs before push_backs:\n" <<
1672 "- TextComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::TextComponent)].size()) << "\n"
1673 "- ShapeComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::ShapeComponent)].size()) << "\n"
1674 "- ButtonComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)].size()) << "\n"
1675 << std::endl;
1676 PRETTY_DEBUG << "Inserting a TextComponent with key: " << title << std::endl;
1677 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(textItem);
1678 PRETTY_DEBUG << "Inserting a ShapeComponent with key: " << application << std::endl;
1679 _ecsEntities[typeid(GUI::ECS::Components::ShapeComponent)].push_back(shapeItem);
1680 PRETTY_DEBUG << "Inserting a Button Component with key: " << Recoded::myToString(_baseId) << std::endl;
1681 _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)].push_back(buttonItem);
1682 PRETTY_DEBUG << "Ecs after push_backs:\n" <<
1683 "- TextComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::TextComponent)].size()) << "\n"
1684 "- ShapeComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::ShapeComponent)].size()) << "\n"
1685 "- ButtonComponent: " << Recoded::myToString(_ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)].size()) << "\n"
1686 << std::endl;
1687 return buttonItem;
1688}
1689
1697const unsigned int Main::_getScreenCenterX()
1698{
1699 std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
1700 if (!win.has_value()) {
1701 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
1702 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
1703 }
1704 PRETTY_DEBUG << "Setting the icon at the top center of the main menu." << std::endl;
1705 const std::pair<int, int> windowDimensions = win.value()->getDimensions();
1706 if (windowDimensions.first <= 0.0) {
1707 PRETTY_CRITICAL << "Skipping calculations and rendering because the window is smaller or equal to 0." << std::endl;
1708 throw CustomExceptions::NoWindow("<There is no window or it's size is smaller than 1>");
1709 }
1710 PRETTY_DEBUG << "Calculating the y-coordinate (center of the window)." << std::endl;
1711 return static_cast<unsigned int>(windowDimensions.first / 2);
1712}
1713
1714
1722const unsigned int Main::_getScreenCenterY()
1723{
1724 std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
1725 if (!win.has_value()) {
1726 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
1727 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
1728 }
1729 PRETTY_DEBUG << "Setting the icon at the top center of the main menu." << std::endl;
1730 const std::pair<int, int> windowDimensions = win.value()->getDimensions();
1731 if (windowDimensions.second <= 0.0) {
1732 PRETTY_CRITICAL << "Skipping calculations and rendering because the window is smaller or equal to 0." << std::endl;
1733 throw CustomExceptions::NoWindow("<There is no window or it's size is smaller than 1>");
1734 }
1735 PRETTY_DEBUG << "Calculating the y-coordinate (center of the window)." << std::endl;
1736 return static_cast<unsigned int>(windowDimensions.second / 2);
1737}
1738
1739void Main::_gameScreen()
1740{
1741 PRETTY_DEBUG << "In _onlineScreen" << std::endl;
1742 PRETTY_DEBUG << "_onlineInitialised = " << Recoded::myToString(_onlineInitialised) << ", _onlineStarted = " << Recoded::myToString(_onlineStarted) << std::endl;
1743
1744 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
1745 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
1746 if (!win.has_value()) {
1747 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
1748 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
1749 }
1750 PRETTY_SUCCESS << "Window manager component found" << std::endl;
1751
1752 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1753 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
1754
1755 if (!_networkClassSet) {
1756 PRETTY_DEBUG << "The online brain does not have the network class, providing" << std::endl;
1757 _onlineBrain.setNetworkClass(_networkManager);
1758 PRETTY_DEBUG << "The brain now has the network class" << std::endl;
1759 }
1760
1761 if (!_onlineInitialised) {
1762 PRETTY_DEBUG << "The online brain is not initialised, initialising" << std::endl;
1763 _onlineBrain.initialiseClass(_ecsEntities);
1764 _onlineInitialised = true;
1765 _onlineStarted = false;
1766 PRETTY_DEBUG << "The brain has been initialised" << std::endl;
1767 }
1768
1769 if (!_onlineStarted) {
1770 PRETTY_DEBUG << "The online has not started, starting" << std::endl;
1771 _onlineBrain.reset();
1772 _onlineBrain.start();
1773 _onlineStarted = true;
1774 PRETTY_DEBUG << "The online has started" << std::endl;
1775 }
1776
1777 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
1778 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
1779 _onlineBrain.reset();
1780 _onlineBrain.stop();
1781 _onlineStarted = false;
1782 _closeConnection();
1783 _goHome();
1784 return;
1785 }
1786
1787 if (_onlineBrain.isGameOver()) {
1788 PRETTY_DEBUG << "The online is over, resetting" << std::endl;
1789 _onlineBrain.reset();
1790 _onlineBrain.stop();
1791 _onlineStarted = false;
1792 _closeConnection();
1793 PRETTY_DEBUG << "The online has been reset" << std::endl;
1794 PRETTY_DEBUG << "The user has lost, going to the game over screen" << std::endl;
1795 _goGameOver();
1796 PRETTY_DEBUG << "The game over screen has been set to play next" << std::endl;
1797 return;
1798 }
1799
1800 if (_onlineBrain.isGameWon()) {
1801 PRETTY_DEBUG << "The online has been won, resetting" << std::endl;
1802 _onlineBrain.reset();
1803 _onlineBrain.stop();
1804 _onlineStarted = false;
1805 _closeConnection();
1806 PRETTY_DEBUG << "The online has been reset" << std::endl;
1807 PRETTY_DEBUG << "The user has won, going to the game won screen" << std::endl;
1808 _goGameWon();
1809 PRETTY_DEBUG << "The game won screen has been set to play next" << std::endl;
1810 return;
1811 }
1812
1813 if (!_connectionInitialised) {
1814 PRETTY_INFO << "Initialising the connection with the server" << std::endl;
1815 _initialiseConnection();
1816 PRETTY_SUCCESS << "Connection with ther server initialised" << std::endl;
1817 _connectionInitialised = _networkManager->isConnected();
1818 }
1819
1820 PRETTY_DEBUG << "Ticking the online brain" << std::endl;
1821 _onlineBrain.tick(_bufferPackets);
1822 PRETTY_DEBUG << "Rendering content" << std::endl;
1823 _onlineBrain.render();
1824 PRETTY_DEBUG << "Ticked and rendered content" << std::endl;
1825}
1826
1827void Main::_demoScreen()
1828{
1829 PRETTY_DEBUG << "In _demoScreen" << std::endl;
1830 PRETTY_DEBUG << "_demoInitialised = " << Recoded::myToString(_demoInitialised) << ", _demoStarted = " << Recoded::myToString(_demoStarted) << std::endl;
1831
1832 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
1833 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
1834 if (!win.has_value()) {
1835 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
1836 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
1837 }
1838 PRETTY_SUCCESS << "Window manager component found" << std::endl;
1839
1840 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1841 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
1842
1843 if (!_demoInitialised) {
1844 PRETTY_DEBUG << "The demo brain is not initialised, initialising" << std::endl;
1845 _demoBrain.initialiseClass(_ecsEntities);
1846 _demoInitialised = true;
1847 _demoStarted = false;
1848 PRETTY_DEBUG << "The brain has been initialised" << std::endl;
1849 }
1850
1851 if (!_demoStarted) {
1852 PRETTY_DEBUG << "The demo has not started, starting" << std::endl;
1853 _demoBrain.reset();
1854 _demoBrain.start();
1855 _demoStarted = true;
1856 PRETTY_DEBUG << "The demo has started" << std::endl;
1857 }
1858
1859 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
1860 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
1861 _demoBrain.reset();
1862 _demoBrain.stop();
1863 _demoStarted = false;
1864 _goHome();
1865 return;
1866 }
1867
1868 if (_demoBrain.isGameOver()) {
1869 PRETTY_DEBUG << "The demo is over, resetting" << std::endl;
1870 _demoBrain.reset();
1871 _demoBrain.stop();
1872 _demoStarted = false;
1873 PRETTY_DEBUG << "The demo has been reset" << std::endl;
1874 PRETTY_DEBUG << "The user has lost, going to the game over screen" << std::endl;
1875 _goGameOver();
1876 PRETTY_DEBUG << "The game over screen has been set to play next" << std::endl;
1877 return;
1878 }
1879
1880 if (_demoBrain.isGameWon()) {
1881 PRETTY_DEBUG << "The demo has been won, resetting" << std::endl;
1882 _demoBrain.reset();
1883 _demoBrain.stop();
1884 _demoStarted = false;
1885 PRETTY_DEBUG << "The demo has been reset" << std::endl;
1886 PRETTY_DEBUG << "The user has won, going to the game won screen" << std::endl;
1887 _goGameWon();
1888 PRETTY_DEBUG << "The game won screen has been set to play next" << std::endl;
1889 return;
1890 }
1891
1892 PRETTY_DEBUG << "Ticking the demo brain" << std::endl;
1893 _demoBrain.tick();
1894 PRETTY_DEBUG << "Rendering content" << std::endl;
1895 _demoBrain.render();
1896 PRETTY_DEBUG << "Ticked and rendered content" << std::endl;
1897}
1898
1899void Main::_settingsMenu()
1900{
1901
1902 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
1903 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
1904 if (!win.has_value()) {
1905 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
1906 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
1907 }
1908 PRETTY_SUCCESS << "Window manager component found" << std::endl;
1909
1910 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
1911 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
1912 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
1913 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
1914 _goHome();
1915 }
1916
1917 PRETTY_DEBUG << "Getting the sound library if present" << std::endl;
1918 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
1919 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
1920 return;
1921 }
1922 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
1923 if (!soundLib.has_value()) {
1924 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
1925 return;
1926 }
1927 PRETTY_DEBUG << "Fetched the sound library" << std::endl;
1928
1929 PRETTY_DEBUG << "Declaring size customisation options" << std::endl;
1930 const unsigned int titleTextSize = 40;
1931 const unsigned int bodyTextSize = 20;
1932 const unsigned int soundTextSize = 20;
1933 const unsigned int musicTextSize = 20;
1934 const unsigned int soundButtonTextSize = 20;
1935 const unsigned int soundButtonWidth = 50;
1936 const unsigned int soundButtonHeight = 20;
1937 const unsigned int musicButtonTextSize = 20;
1938 const unsigned int musicButtonWidth = 50;
1939 const unsigned int musicButtonHeight = 20;
1940 PRETTY_DEBUG << "Declared size customisation options" << std::endl;
1941
1942 PRETTY_DEBUG << "Declaring colour customisation options" << std::endl;
1947 const GUI::ECS::Systems::Colour stoppedSoundButtonBackgroundColour = GUI::ECS::Systems::Colour::Red;
1948 const GUI::ECS::Systems::Colour stoppedSoundButtonNormalColour = GUI::ECS::Systems::Colour::White;
1949 const GUI::ECS::Systems::Colour stoppedSoundButtonHoverColour = GUI::ECS::Systems::Colour::Grey50;
1950 const GUI::ECS::Systems::Colour stoppedSoundButtonClickedColour = GUI::ECS::Systems::Colour::Green;
1951 const GUI::ECS::Systems::Colour playingSoundButtonBackgroundColour = GUI::ECS::Systems::Colour::Green;
1952 const GUI::ECS::Systems::Colour playingSoundButtonNormalColour = GUI::ECS::Systems::Colour::Black;
1953 const GUI::ECS::Systems::Colour playingSoundButtonHoverColour = GUI::ECS::Systems::Colour::Grey50;
1954 const GUI::ECS::Systems::Colour playingSoundButtonClickedColour = GUI::ECS::Systems::Colour::Red;
1955 const GUI::ECS::Systems::Colour stoppedMusicButtonBackgroundColour = GUI::ECS::Systems::Colour::Red;
1956 const GUI::ECS::Systems::Colour stoppedMusicButtonNormalColour = GUI::ECS::Systems::Colour::White;
1957 const GUI::ECS::Systems::Colour stoppedMusicButtonHoverColour = GUI::ECS::Systems::Colour::Grey50;
1958 const GUI::ECS::Systems::Colour stoppedMusicButtonClickedColour = GUI::ECS::Systems::Colour::Green;
1959 const GUI::ECS::Systems::Colour playingMusicButtonBackgroundColour = GUI::ECS::Systems::Colour::Green;
1960 const GUI::ECS::Systems::Colour playingMusicButtonNormalColour = GUI::ECS::Systems::Colour::Black;
1961 const GUI::ECS::Systems::Colour playingMusicButtonHoverColour = GUI::ECS::Systems::Colour::Grey50;
1962 const GUI::ECS::Systems::Colour playingMusicButtonClickedColour = GUI::ECS::Systems::Colour::Red;
1963 PRETTY_DEBUG << "Declared colour customisation options" << std::endl;
1964
1965 PRETTY_DEBUG << "Declaring required item keys" << std::endl;
1966 const std::string titleTextKey = "settingsMenuTitleTextKey";
1967 const std::string bodyTextKey = "settingsMenuBodyTextKey";
1968 const std::string soundTextKey = "settingsMenuSoundTextKey";
1969 const std::string musicTextKey = "settingsMenuMusicTextKey";
1970 const std::string soundButtonKey = "settingsMenuSoundButtonKey";
1971 const std::string musicButtonKey = "settingsMenuMusicButtonKey";
1972 PRETTY_DEBUG << "Declared required item keys" << std::endl;
1973
1974 PRETTY_DEBUG << "Getting the lists of ressources we want" << std::endl;
1975 // The list of font components to allow the screen to find the ressources it needs if present
1976 const std::vector<std::any> fonts = _ecsEntities[typeid(GUI::ECS::Systems::Font)];
1977
1978 // The list of text components to allow the screen to find the ressources it needs if present
1979 std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
1980
1981 // The list of button components to allow the screen to find the ressources it needs if present
1982 std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
1983
1984 // The list of the background components to allow the screen to find the ressources it needs (if present)
1985 std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
1986 PRETTY_DEBUG << "Got the list of ressources we want" << std::endl;
1987
1988 PRETTY_DEBUG << "Declaring the ressources required for the settings menu (for the texts)" << std::endl;
1989 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> bodyTextItem;
1990 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> titleTextItem;
1991 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> musicTextItem;
1992 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> soundTextItem;
1993 PRETTY_DEBUG << "Declared the ressources required for the settings menu (for the texts)" << std::endl;
1994
1995 PRETTY_DEBUG << "Declaring the ressources required for the settings menu (for the buttons)" << std::endl;
1996 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> musicButtonItem;
1997 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> soundButtonItem;
1998 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> mainMenuButtonItem;
1999 PRETTY_DEBUG << "Declared the ressources required for the settings menu (for the buttons)" << std::endl;
2000
2001 PRETTY_DEBUG << "Declaring font holder instances" << std::endl;
2002 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFont;
2003 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont;
2004 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont;
2005 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFont;
2006 PRETTY_DEBUG << "Declared font holder instances" << std::endl;
2007
2008 PRETTY_DEBUG << "Declaring the ressource required for the settings menu to have a background" << std::endl;
2009 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundItem;
2010 PRETTY_DEBUG << "Declared the ressource required for the settings menu to have a background" << std::endl;
2011
2012
2013 for (std::any textCast : texts) {
2014 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(textCast, false);
2015 if (textCapsule.has_value()) {
2016 continue;
2017 }
2018 std::string application = textCapsule.value()->getApplication();
2019 std::string name = textCapsule.value()->getName();
2020 if (application == titleTextKey || name == titleTextKey) {
2021 titleTextItem.emplace(textCapsule.value());
2022 } else if (application == bodyTextKey || name == bodyTextKey) {
2023 bodyTextItem.emplace(textCapsule.value());
2024 } else if (application == soundTextKey || name == soundTextKey) {
2025 soundTextItem.emplace(textCapsule.value());
2026 } else if (application == musicTextKey || name == musicTextKey) {
2027 musicTextItem.emplace(textCapsule.value());
2028 } else {
2029 continue;
2030 }
2031 }
2032
2033 for (std::any buttonCast : buttons) {
2034 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> buttonCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttonCast, false);
2035 if (buttonCapsule.has_value()) {
2036 continue;
2037 }
2038 std::string application = buttonCapsule.value()->getApplication();
2039 std::string name = buttonCapsule.value()->getName();
2040 if (application == soundButtonKey || name == soundButtonKey) {
2041 soundButtonItem.emplace(buttonCapsule.value());
2042 } else if (application == _mainMenuKey) {
2043 mainMenuButtonItem.emplace(buttonCapsule.value());
2044 } else if (application == musicButtonKey || name == musicButtonKey) {
2045 musicButtonItem.emplace(buttonCapsule.value());
2046 } else {
2047 continue;
2048 }
2049 }
2050
2051 for (std::any backgroundCast : backgrounds) {
2052 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
2053 if (!backgroundCapsule.has_value()) {
2054 continue;
2055 }
2056 if (
2057 backgroundCapsule.value()->getApplication() == "settings" || backgroundCapsule.value()->getName() == "settings" ||
2058 backgroundCapsule.value()->getApplication() == "Settings" || backgroundCapsule.value()->getName() == "Settings"
2059 ) {
2060 backgroundItem.emplace(backgroundCapsule.value());
2061 }
2062 }
2063
2064 if (!titleTextItem.has_value() || !bodyTextItem.has_value() || !soundTextItem.has_value() || !musicButtonItem.has_value() || !soundButtonItem.has_value() || !mainMenuButtonItem.has_value()) {
2065 PRETTY_DEBUG << "Fetching the fonts that will be used in the window" << std::endl;
2066 unsigned int index = 0;
2067 unsigned int titleFontIndex = 0;
2068 unsigned int bodyFontIndex = 0;
2069 unsigned int defaultFontIndex = 0;
2070 unsigned int buttonFontIndex = 0;
2071 for (std::any fontCast : fonts) {
2072 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> fontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fontCast, false);
2073 if (!fontCapsule.has_value()) {
2074 continue;
2075 }
2076 std::string applicationContext = fontCapsule.value()->getApplication();
2077 if (applicationContext == "title") {
2078 titleFontIndex = index;
2079 } else if (applicationContext == "body") {
2080 bodyFontIndex = index;
2081 } else if (applicationContext == "default") {
2082 defaultFontIndex = index;
2083 } else if (applicationContext == "button") {
2084 buttonFontIndex = index;
2085 } else {
2086 index++;
2087 continue;
2088 }
2089 index++;
2090 }
2091 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[titleFontIndex], false);
2092 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[bodyFontIndex], false);
2093 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[defaultFontIndex], false);
2094 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[buttonFontIndex], false);
2095 if (!defaultFontCapsule.has_value()) {
2096 PRETTY_DEBUG << "No default font found, aborting program" << std::endl;
2097 throw CustomExceptions::NoFont("<Default font not found>");
2098 }
2099 defaultFont.emplace(defaultFontCapsule.value());
2100 titleFont.emplace(defaultFontCapsule.value());
2101 bodyFont.emplace(defaultFontCapsule.value());
2102 buttonFont.emplace(defaultFontCapsule.value());
2103 if (titleFontCapsule.has_value()) {
2104 PRETTY_SUCCESS << "Title font found, not defaulting to the default font." << std::endl;
2105 titleFont.emplace(titleFontCapsule.value());
2106 }
2107 if (bodyFontCapsule.has_value()) {
2108 PRETTY_SUCCESS << "Body font found, not defaulting to the default font." << std::endl;
2109 bodyFont.emplace(bodyFontCapsule.value());
2110 }
2111 if (buttonFontCapsule.has_value()) {
2112 PRETTY_SUCCESS << "Button font found, not defaulting to the default font." << std::endl;
2113 buttonFont.emplace(buttonFontCapsule.value());
2114 }
2115 PRETTY_DEBUG << "Fetched the fonts that will be used in the window" << std::endl;
2116 }
2117
2118 PRETTY_DEBUG << "Checking is title text component exists" << std::endl;
2119 if (!titleTextItem.has_value()) {
2120 PRETTY_DEBUG << "Title text component does not exist, creating" << std::endl;
2121 if (!titleFont.has_value()) {
2122 PRETTY_ERROR << "No font found in title font." << std::endl;
2123 return;
2124 }
2125 PRETTY_DEBUG << "Creating title text component" << std::endl;
2126 titleTextItem = _createText(
2127 titleTextKey,
2128 titleTextKey,
2129 "Settings",
2130 *(titleFont.value()),
2131 titleTextSize,
2132 titleColour,
2133 titleColour,
2134 titleColour
2135 );
2136 PRETTY_DEBUG << "Created title text component" << std::endl;
2137 }
2138 PRETTY_DEBUG << "Checked if title text component existed" << std::endl;
2139
2140 PRETTY_DEBUG << "Checking is body text component exists" << std::endl;
2141 if (!bodyTextItem.has_value()) {
2142 PRETTY_DEBUG << "Body text component does not exist, creating" << std::endl;
2143 if (!bodyFont.has_value()) {
2144 PRETTY_ERROR << "No font found in body font." << std::endl;
2145 return;
2146 }
2147 PRETTY_DEBUG << "Creating body text component" << std::endl;
2148 bodyTextItem = _createText(
2149 bodyTextKey,
2150 bodyTextKey,
2151 "Comme and customise your user experience!",
2152 *(bodyFont.value()),
2153 bodyTextSize,
2154 bodyColour,
2155 bodyColour,
2156 bodyColour
2157 );
2158 PRETTY_DEBUG << "Created body text component" << std::endl;
2159 }
2160 PRETTY_DEBUG << "Checked if body text component existed" << std::endl;
2161
2162 PRETTY_DEBUG << "Checking is sound text component exists" << std::endl;
2163 if (!soundTextItem.has_value()) {
2164 PRETTY_DEBUG << "Sound text component does not exist, creating" << std::endl;
2165 if (!defaultFont.has_value()) {
2166 PRETTY_ERROR << "No font found in body font." << std::endl;
2167 return;
2168 }
2169 PRETTY_DEBUG << "Creating sound text component" << std::endl;
2170 soundTextItem = _createText(
2171 soundTextKey,
2172 soundTextKey,
2173 "Sound effects: ",
2174 *(defaultFont.value()),
2175 soundTextSize,
2176 soundColour,
2177 soundColour,
2178 soundColour
2179 );
2180 PRETTY_DEBUG << "Created sound text component" << std::endl;
2181 }
2182 PRETTY_DEBUG << "Checked if sound text component existed" << std::endl;
2183
2184 PRETTY_DEBUG << "Checking is music text component exists" << std::endl;
2185 if (!musicTextItem.has_value()) {
2186 PRETTY_DEBUG << "Music text component does not exist, creating" << std::endl;
2187 if (!defaultFont.has_value()) {
2188 PRETTY_ERROR << "No font found in body font." << std::endl;
2189 return;
2190 }
2191 PRETTY_DEBUG << "Creating music text component" << std::endl;
2192 musicTextItem = _createText(
2193 musicTextKey,
2194 musicTextKey,
2195 "Music: ",
2196 *(defaultFont.value()),
2197 musicTextSize,
2198 musicColour,
2199 musicColour,
2200 musicColour
2201 );
2202 PRETTY_DEBUG << "Created music text component" << std::endl;
2203 }
2204 PRETTY_DEBUG << "Checked if music text component existed" << std::endl;
2205
2206 PRETTY_DEBUG << "Checking if the sound button is created" << std::endl;
2207 if (!soundButtonItem.has_value()) {
2208 PRETTY_DEBUG << "Sound button component does not exist, creating" << std::endl;
2209 if (!defaultFont.has_value()) {
2210 PRETTY_ERROR << "No font found in default font." << std::endl;
2211 return;
2212 }
2213 std::string soundStatus = "OFF";
2214 GUI::ECS::Systems::Colour soundButtonBackgroundColour = stoppedSoundButtonBackgroundColour;
2215 GUI::ECS::Systems::Colour soundButtonNormalColour = stoppedSoundButtonNormalColour;
2216 GUI::ECS::Systems::Colour soundButtonHoverColour = stoppedSoundButtonHoverColour;
2217 GUI::ECS::Systems::Colour soundButtonClickedColour = stoppedSoundButtonClickedColour;
2218 if (soundLib.has_value() && soundLib.value()->isEnabled()) {
2219 soundStatus = "ON";
2220 soundButtonBackgroundColour = playingSoundButtonBackgroundColour;
2221 soundButtonNormalColour = playingSoundButtonNormalColour;
2222 soundButtonHoverColour = playingSoundButtonHoverColour;
2223 soundButtonClickedColour = playingSoundButtonClickedColour;
2224 }
2225 PRETTY_DEBUG << "Creating sound button component" << std::endl;
2226 soundButtonItem = _createButton(
2227 soundButtonKey,
2228 soundStatus,
2229 std::bind(&Main::_toggleSound, this),
2230 "_toggleSound",
2231 soundButtonWidth,
2232 soundButtonHeight,
2233 soundButtonTextSize,
2234 soundButtonBackgroundColour,
2235 soundButtonNormalColour,
2236 soundButtonHoverColour,
2237 soundButtonClickedColour,
2238 defaultFont.value()
2239 );
2240 PRETTY_DEBUG << "sound button component created" << std::endl;
2241 }
2242 PRETTY_DEBUG << "Checked if the sound button was created" << std::endl;
2243
2244 PRETTY_DEBUG << "Checking if the music button is created" << std::endl;
2245 if (!musicButtonItem.has_value()) {
2246 PRETTY_DEBUG << "Sound button component does not exist, creating" << std::endl;
2247 if (!defaultFont.has_value()) {
2248 PRETTY_ERROR << "No font found in default font." << std::endl;
2249 return;
2250 }
2251 std::string musicStatus = "OFF";
2252 GUI::ECS::Systems::Colour musicButtonBackgroundColour = playingMusicButtonBackgroundColour;
2253 GUI::ECS::Systems::Colour musicButtonNormalColour = playingMusicButtonNormalColour;
2254 GUI::ECS::Systems::Colour musicButtonHoverColour = playingMusicButtonHoverColour;
2255 GUI::ECS::Systems::Colour musicButtonClickedColour = playingMusicButtonClickedColour;
2256 if (_playMusic) {
2257 musicStatus = "ON";
2258 musicButtonBackgroundColour = stoppedMusicButtonBackgroundColour;
2259 musicButtonNormalColour = stoppedMusicButtonNormalColour;
2260 musicButtonHoverColour = stoppedMusicButtonHoverColour;
2261 musicButtonClickedColour = stoppedMusicButtonClickedColour;
2262 }
2263 PRETTY_DEBUG << "Creating music button component" << std::endl;
2264 musicButtonItem = _createButton(
2265 musicButtonKey,
2266 musicStatus,
2267 std::bind(&Main::_toggleMusic, this),
2268 "_toggleMusic",
2269 musicButtonWidth,
2270 musicButtonHeight,
2271 musicButtonTextSize,
2272 musicButtonBackgroundColour,
2273 musicButtonNormalColour,
2274 musicButtonHoverColour,
2275 musicButtonClickedColour,
2276 defaultFont.value()
2277 );
2278 PRETTY_DEBUG << "music button component created" << std::endl;
2279 }
2280 PRETTY_DEBUG << "Checked if the music button was created" << std::endl;
2281
2282 PRETTY_DEBUG << "Checking if the home button exists" << std::endl;
2283 if (!mainMenuButtonItem.has_value()) {
2284 PRETTY_WARNING << "Home button not found, creating" << std::endl;
2285 mainMenuButtonItem = _createButton(
2286 _mainMenuKey,
2287 "Home",
2288 std::bind(&Main::_goHome, this),
2289 "_goHome",
2290 200,
2291 30,
2292 20,
2297 );
2298 PRETTY_SUCCESS << "Home Button created" << std::endl;
2299 }
2300 PRETTY_DEBUG << "Checked if the home button existed" << std::endl;
2301
2302
2303 PRETTY_DEBUG << "Setting item positions" << std::endl;
2304 backgroundItem.value()->setDimension(win.value()->getDimensions());
2305 backgroundItem.value()->setPosition({ 0, 0 });
2306
2307 float posY = 0;
2308 float posX = 0;
2309 const float step = 10;
2310
2311 titleTextItem.value()->setPosition({ posX, posY });
2312 posY += step + titleTextSize;
2313 bodyTextItem.value()->setPosition({ posX, posY });
2314 posY += step + bodyTextSize;
2315 soundTextItem.value()->setPosition({ posX, posY });
2316 posX = _getScreenCenterX();
2317 soundButtonItem.value()->setPosition({ posX, posY });
2318 posX = 0;
2319 posY += step + soundTextSize;
2320 musicTextItem.value()->setPosition({ posX, posY });
2321 posX = _getScreenCenterX();
2322 musicButtonItem.value()->setPosition({ posX, posY });
2323 posX = 0;
2324 posY += step + musicTextSize;
2325 mainMenuButtonItem.value()->setPosition({ posX, posY });
2326 PRETTY_DEBUG << "Item positions set" << std::endl;
2327
2328 PRETTY_DEBUG << "Setting the text of the buttons" << std::endl;
2329 std::string soundStatus = "OFF";
2330 if (soundLib.has_value() && soundLib.value()->isEnabled()) {
2331 soundStatus = "ON";
2332 }
2333 soundButtonItem.value()->setTextString(soundStatus);
2334 std::string musicStatus = "OFF";
2335 if (_playMusic) {
2336 musicStatus = "ON";
2337 }
2338 musicButtonItem.value()->setTextString(musicStatus);
2339 PRETTY_DEBUG << "The text of the buttons has been set" << std::endl;
2340
2341 PRETTY_DEBUG << "Setting the colour of the buttons" << std::endl;
2342 PRETTY_DEBUG << "Colour for the sound" << std::endl;
2343 if (soundLib.has_value() && soundLib.value()->isEnabled()) {
2344 soundButtonItem.value()->setNormalColor(playingSoundButtonBackgroundColour);
2345 soundButtonItem.value()->setHoverColor(playingSoundButtonBackgroundColour);
2346 soundButtonItem.value()->setClickedColor(playingSoundButtonBackgroundColour);
2347 soundButtonItem.value()->setTextNormalColor(playingSoundButtonNormalColour);
2348 soundButtonItem.value()->setTextHoverColor(playingSoundButtonHoverColour);
2349 soundButtonItem.value()->setTextClickedColor(playingSoundButtonClickedColour);
2350 } else {
2351 soundButtonItem.value()->setNormalColor(stoppedSoundButtonBackgroundColour);
2352 soundButtonItem.value()->setHoverColor(stoppedSoundButtonBackgroundColour);
2353 soundButtonItem.value()->setClickedColor(stoppedSoundButtonBackgroundColour);
2354 soundButtonItem.value()->setTextNormalColor(stoppedSoundButtonNormalColour);
2355 soundButtonItem.value()->setTextHoverColor(stoppedSoundButtonHoverColour);
2356 soundButtonItem.value()->setTextClickedColor(stoppedSoundButtonClickedColour);
2357 }
2358 PRETTY_DEBUG << "Colour for the music" << std::endl;
2359 if (_playMusic) {
2360 musicButtonItem.value()->setNormalColor(playingMusicButtonBackgroundColour);
2361 musicButtonItem.value()->setHoverColor(playingMusicButtonBackgroundColour);
2362 musicButtonItem.value()->setClickedColor(playingMusicButtonBackgroundColour);
2363 musicButtonItem.value()->setTextNormalColor(playingMusicButtonNormalColour);
2364 musicButtonItem.value()->setTextHoverColor(playingMusicButtonHoverColour);
2365 musicButtonItem.value()->setTextClickedColor(playingMusicButtonClickedColour);
2366 } else {
2367 musicButtonItem.value()->setNormalColor(stoppedMusicButtonBackgroundColour);
2368 musicButtonItem.value()->setHoverColor(stoppedMusicButtonBackgroundColour);
2369 musicButtonItem.value()->setClickedColor(stoppedMusicButtonBackgroundColour);
2370 musicButtonItem.value()->setTextNormalColor(stoppedMusicButtonNormalColour);
2371 musicButtonItem.value()->setTextHoverColor(stoppedMusicButtonHoverColour);
2372 musicButtonItem.value()->setTextClickedColor(stoppedMusicButtonClickedColour);
2373 }
2374 PRETTY_DEBUG << "The colour of the buttons has been set" << std::endl;
2375
2376 PRETTY_DEBUG << "Displaying elements on the screen" << std::endl;
2377 win.value()->draw(*(backgroundItem.value()));
2378 PRETTY_DEBUG << "Background rendered" << std::endl;
2379 win.value()->draw(*(titleTextItem.value()));
2380 win.value()->draw(*(bodyTextItem.value()));
2381 PRETTY_DEBUG << "Title and body text rendered" << std::endl;
2382 win.value()->draw(*(soundTextItem.value()));
2383 win.value()->draw(*(soundButtonItem.value()));
2384 PRETTY_DEBUG << "Sound button and text rendered" << std::endl;
2385 win.value()->draw(*(musicTextItem.value()));
2386 win.value()->draw(*(musicButtonItem.value()));
2387 PRETTY_DEBUG << "Music button and text rendered" << std::endl;
2388 win.value()->draw(*(mainMenuButtonItem.value()));
2389 PRETTY_DEBUG << "Home button rendered" << std::endl;
2390 PRETTY_DEBUG << "Displayed elements on the screen" << std::endl;
2391}
2392
2393void Main::_unknownScreen()
2394{
2395 bool bodyTextFound = false;
2396 bool titleTextFound = false;
2397 bool homeButtonFound = false;
2398
2399 const std::string titleKey = "unknownScreenTitle";
2400 const std::string bodyKey = "unknownScreenBody";
2401
2402 const unsigned int titleTextSize = 40;
2403 const unsigned int bodyTextSize = 20;
2404
2406
2407 std::shared_ptr<GUI::ECS::Components::TextComponent> bodyItem;
2408 std::shared_ptr<GUI::ECS::Components::TextComponent> titleItem;
2409 std::shared_ptr<GUI::ECS::Components::ButtonComponent> homeItem;
2410
2411 std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
2412 std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
2413
2414 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
2415 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
2416 if (!win.has_value()) {
2417 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
2418 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
2419 }
2420 PRETTY_SUCCESS << "Window manager component found" << std::endl;
2421
2422 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
2423 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
2424 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
2425 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
2426 _goHome();
2427 }
2428
2429
2430 for (std::any textCast : texts) {
2431 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(textCast, false);
2432 if (textCapsule) {
2433 if (textCapsule.value()->getApplication() == titleKey) {
2434 titleTextFound = true;
2435 titleItem = textCapsule.value();
2436 titleItem->setSize(titleTextSize);
2437 } else if (textCapsule.value()->getApplication() == bodyKey) {
2438 bodyTextFound = true;
2439 bodyItem = textCapsule.value();
2440 bodyItem->setSize(bodyTextSize);
2441 } else {
2442 continue;
2443 }
2444 }
2445 }
2446
2447 for (std::any buttonCast : buttons) {
2448 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> buttonCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttonCast, false);
2449 if (buttonCapsule) {
2450 if (buttonCapsule.value()->getApplication() == _mainMenuKey) {
2451 homeButtonFound = true;
2452 homeItem = buttonCapsule.value();
2453 }
2454 }
2455 }
2456
2457 if (!titleTextFound) {
2458 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_titleFontIndex], false);
2459 if (!titleFont.has_value()) {
2460 PRETTY_CRITICAL << "There is no font to be extracted for creating the title text of the unknown screen screen." << std::endl;
2461 return;
2462 }
2463 titleItem = _createText(
2464 titleKey,
2465 titleKey,
2466 "Uh Oh!",
2467 *(titleFont.value()),
2468 titleTextSize,
2469 textColour,
2470 textColour,
2471 textColour
2472 );
2473 }
2474
2475 if (!bodyTextFound) {
2476 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_bodyFontIndex], false);
2477 if (!bodyFont.has_value()) {
2478 PRETTY_CRITICAL << "There is no font to be extracted for creating the body text of the unknown screen screen." << std::endl;
2479 return;
2480 }
2481 bodyItem = _createText(
2482 bodyKey,
2483 bodyKey,
2484 "It seems like you have landed on an unknown page.",
2485 *(bodyFont.value()),
2486 bodyTextSize,
2487 textColour,
2488 textColour,
2489 textColour
2490 );
2491 }
2492
2493 if (!homeButtonFound) {
2494 PRETTY_WARNING << "Home button not found, creating" << std::endl;
2495 homeItem = _createButton(
2496 _mainMenuKey,
2497 "Home",
2498 std::bind(&Main::_goHome, this),
2499 "_goHome",
2500 200,
2501 30,
2502 20,
2507 );
2508 PRETTY_SUCCESS << "Home Button created" << std::endl;
2509 }
2510
2511 unsigned int posx = _getScreenCenterX();
2512 unsigned int posy = _getScreenCenterY();
2513
2514 const unsigned int titleOffest = (2 * titleTextSize);
2515 const unsigned int titleLength = (titleItem->getSize() + 1) / 2 + titleOffest;
2516 const unsigned int bodyLength = ((bodyItem->getSize() + 1) / 2) + (17 * bodyTextSize);
2517 const unsigned int homeItemLength = (homeItem->getTextSize() + 1) / 2 + titleOffest;
2518
2519 PRETTY_DEBUG << "Lengths:\n- titleLength: '" << titleLength << "'\n- bodyLength: '" << bodyLength << "'\n- homeItemLength: '" << homeItemLength << "'" << std::endl;
2520 PRETTY_DEBUG << "Positions:\n- posx: '" << posx << "'\n- posy: '" << posy << "'" << std::endl;
2521
2522
2523 titleItem->setPosition({ posx - titleLength, posy });
2524 bodyItem->setPosition({ posx - bodyLength, posy + 60 });
2525 homeItem->setPosition({ posx - homeItemLength, posy + 100 });
2526 PRETTY_DEBUG << "Component's positions updated for the current screen." << std::endl;
2527 win.value()->draw(*titleItem);
2528 win.value()->draw(*bodyItem);
2529 win.value()->draw(*homeItem);
2530 PRETTY_SUCCESS << "Component's positions drawn successfully." << std::endl;
2531}
2532
2533void Main::_gameOverScreen()
2534{
2535
2536 PRETTY_DEBUG << "In the _gameOverScreen function." << std::endl;
2537
2538 bool bodyTextFound = false;
2539 bool titleTextFound = false;
2540 bool homeButtonFound = false;
2541 bool backgroundFound = false;
2542
2543 const std::string titleKey = "GameOverScreenTitle";
2544 const std::string bodyKey = "GameOverScreenBody";
2545 const std::string backgroundKey = "gameOver";
2546
2548
2549 std::shared_ptr<GUI::ECS::Components::TextComponent> bodyItem;
2550 std::shared_ptr<GUI::ECS::Components::TextComponent> titleItem;
2551 std::shared_ptr<GUI::ECS::Components::ButtonComponent> homeItem;
2552 std::shared_ptr<GUI::ECS::Components::ImageComponent> backgroundItem;
2553
2554 std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
2555 std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
2556 std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
2557
2558 PRETTY_DEBUG << "vector texts size: " << texts.size() << std::endl;
2559 PRETTY_DEBUG << "vector buttons size: " << buttons.size() << std::endl;
2560 PRETTY_DEBUG << "vector backgrounds size: " << backgrounds.size() << std::endl;
2561
2562 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
2563 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
2564 if (!win.has_value()) {
2565 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
2566 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
2567 }
2568 PRETTY_SUCCESS << "Window manager component found" << std::endl;
2569
2570 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
2571 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
2572 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
2573 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
2574 _goHome();
2575 }
2576
2577 PRETTY_DEBUG << "Fetching the text components if present." << std::endl;
2578 for (std::any textCast : texts) {
2579 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(textCast, false);
2580 if (textCapsule.has_value()) {
2581 if (textCapsule.value()->getApplication() == titleKey) {
2582 titleTextFound = true;
2583 titleItem = textCapsule.value();
2584 PRETTY_DEBUG << "Text title found" << std::endl;
2585 } else if (textCapsule.value()->getApplication() == bodyKey) {
2586 bodyTextFound = true;
2587 bodyItem = textCapsule.value();
2588 PRETTY_DEBUG << "Text body found" << std::endl;
2589 } else {
2590 continue;
2591 }
2592 }
2593 }
2594 PRETTY_DEBUG << "Fetched the text components that were present." << std::endl;
2595
2596 PRETTY_DEBUG << "Attempting to fetch content for the button." << std::endl;
2597 for (std::any buttonCast : buttons) {
2598 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> buttonCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttonCast, false);
2599 if (buttonCapsule.has_value() && buttonCapsule.value()->getApplication() == _mainMenuKey) {
2600 homeButtonFound = true;
2601 homeItem = buttonCapsule.value();
2602 PRETTY_DEBUG << "Button found" << std::endl;
2603 }
2604 }
2605 PRETTY_DEBUG << "Fetched the button content." << std::endl;
2606
2607 PRETTY_DEBUG << "Attempting to fetch content for the background." << std::endl;
2608 for (std::any backgroundCast : backgrounds) {
2609 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
2610 if (backgroundCapsule.has_value() && backgroundCapsule.value()->getApplication() == backgroundKey) {
2611 backgroundFound = true;
2612 backgroundItem = backgroundCapsule.value();
2613 PRETTY_DEBUG << "Background found" << std::endl;
2614 }
2615 }
2616 PRETTY_DEBUG << "Fetched the background content." << std::endl;
2617
2618 PRETTY_DEBUG << "Values of the checker variables: \n- bodyTextFound: '" << Recoded::myToString(bodyTextFound) << "'\n- titleTextFound: '" << Recoded::myToString(titleTextFound) << "'\n- homeButtonFound: '" << Recoded::myToString(homeButtonFound) << "'" << std::endl;
2619
2620 PRETTY_DEBUG << "Checking the text for the title." << std::endl;
2621 if (!titleTextFound) {
2622 PRETTY_WARNING << "No title text instance found, creating instance." << std::endl;
2623 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_titleFontIndex], false);
2624 if (!titleFont.has_value()) {
2625 PRETTY_CRITICAL << "There is no font to be extracted for creating the title text of the game over screen screen." << std::endl;
2626 return;
2627 }
2628 titleItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(titleFont.value()), "Game Over!");
2629 titleItem->setApplication(titleKey);
2630 titleItem->setNormalColor(textColour);
2631 titleItem->setHoverColor(textColour);
2632 titleItem->setClickedColor(textColour);
2633 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(titleItem);
2634 _baseId += 1;
2635 }
2636 PRETTY_DEBUG << "Checked the text for the title." << std::endl;
2637
2638 PRETTY_DEBUG << "Checking text content for the body." << std::endl;
2639 if (!bodyTextFound) {
2640 PRETTY_WARNING << "No body text instance found, creating instance." << std::endl;
2641 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_bodyFontIndex], false);
2642 if (!bodyFont.has_value()) {
2643 PRETTY_CRITICAL << "There is no font to be extracted for creating the body text of the game over screen screen." << std::endl;
2644 return;
2645 }
2646 bodyItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(bodyFont.value()), "You have died!", 20);
2647 bodyItem->setApplication(bodyKey);
2648 bodyItem->setNormalColor(textColour);
2649 bodyItem->setHoverColor(textColour);
2650 bodyItem->setClickedColor(textColour);
2651 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(bodyItem);
2652 _baseId += 1;
2653 }
2654 PRETTY_DEBUG << "Checked the text content for the body." << std::endl;
2655
2656 PRETTY_DEBUG << "Checking if the Home button exists." << std::endl;
2657 if (!homeButtonFound) {
2658 PRETTY_WARNING << "Home button not found, creating" << std::endl;
2659 homeItem = _createButton(
2660 _mainMenuKey,
2661 "Home",
2662 std::bind(&Main::_goHome, this),
2663 "_goHome",
2664 200,
2665 30,
2666 20,
2671 );
2672 PRETTY_SUCCESS << "Home Button created" << std::endl;
2673 }
2674 PRETTY_DEBUG << "Checked if the home button existed." << std::endl;
2675
2676 if (!backgroundFound) {
2677 PRETTY_WARNING << "Background not found, changing the text components" << std::endl;
2678 const GUI::ECS::Systems::Colour defaultColourForNoBackground = GUI::ECS::Systems::Colour::Red;
2679 titleItem->setNormalColor(defaultColourForNoBackground);
2680 titleItem->setHoverColor(defaultColourForNoBackground);
2681 titleItem->setClickedColor(defaultColourForNoBackground);
2682 bodyItem->setNormalColor(defaultColourForNoBackground);
2683 bodyItem->setHoverColor(defaultColourForNoBackground);
2684 bodyItem->setClickedColor(defaultColourForNoBackground);
2685 }
2686
2687 PRETTY_DEBUG << "Checking the coordinates for the center of the x and y axis." << std::endl;
2688 unsigned int posx = _getScreenCenterX();
2689 unsigned int posy = _getScreenCenterY();
2690 PRETTY_DEBUG << "Center of the screen is at (" << posx << ", " << posy << ")" << std::endl;
2691
2692 PRETTY_DEBUG << "The items that are currently loaded, are:\n- " << *titleItem << "\n- " << *bodyItem << "\n- " << *homeItem << std::endl;
2693
2694 PRETTY_DEBUG << "Setting the position of the components." << std::endl;
2695 titleItem->setPosition({ posx, posy });
2696 PRETTY_DEBUG << "Position for the title item is set." << std::endl;
2697 bodyItem->setPosition({ posx, posy + 40 });
2698 PRETTY_DEBUG << "Position for the body item is set." << std::endl;
2699 homeItem->setPosition({ posx, posy + 100 });
2700 PRETTY_DEBUG << "Position for the home item is set." << std::endl;
2701 if (backgroundFound) {
2702 backgroundItem->setDimension({ _windowWidth, _windowHeight });
2703 win.value()->draw(*backgroundItem);
2704 }
2705 PRETTY_DEBUG << "Component's positions updated for the current screen." << std::endl;
2706 win.value()->draw(*titleItem);
2707 PRETTY_DEBUG << "Title Item drawn." << std::endl;
2708 win.value()->draw(*bodyItem);
2709 PRETTY_DEBUG << "Body Item drawn." << std::endl;
2710 win.value()->draw(*homeItem);
2711 PRETTY_DEBUG << "Home Item drawn." << std::endl;
2712 PRETTY_SUCCESS << "Component's positions drawn successfully." << std::endl;
2713}
2714
2715void Main::_gameWonScreen()
2716{
2717
2718 PRETTY_DEBUG << "In the _gameWonScreen function." << std::endl;
2719
2720 bool bodyTextFound = false;
2721 bool titleTextFound = false;
2722 bool homeButtonFound = false;
2723 bool backgroundFound = false;
2724
2725 const std::string titleKey = "GameWonScreenTitle";
2726 const std::string bodyKey = "GameWonScreenBody";
2727 const std::string backgroundKey = "gameWon";
2728
2730
2731 std::shared_ptr<GUI::ECS::Components::TextComponent> bodyItem;
2732 std::shared_ptr<GUI::ECS::Components::TextComponent> titleItem;
2733 std::shared_ptr<GUI::ECS::Components::ButtonComponent> homeItem;
2734 std::shared_ptr<GUI::ECS::Components::ImageComponent> backgroundItem;
2735
2736 std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
2737 std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
2738 std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
2739
2740 PRETTY_DEBUG << "vector texts size: " << texts.size() << std::endl;
2741 PRETTY_DEBUG << "vector buttons size: " << buttons.size() << std::endl;
2742 PRETTY_DEBUG << "vector backgrounds size: " << backgrounds.size() << std::endl;
2743
2744 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
2745 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
2746 if (!win.has_value()) {
2747 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
2748 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
2749 }
2750 PRETTY_SUCCESS << "Window manager component found" << std::endl;
2751
2752 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
2753 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
2754 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
2755 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
2756 _goHome();
2757 }
2758
2759 PRETTY_DEBUG << "Fetching the text components if present." << std::endl;
2760 for (std::any textCast : texts) {
2761 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(textCast, false);
2762 if (textCapsule.has_value()) {
2763 if (textCapsule.value()->getApplication() == titleKey) {
2764 titleTextFound = true;
2765 titleItem = textCapsule.value();
2766 PRETTY_DEBUG << "Text title found" << std::endl;
2767 } else if (textCapsule.value()->getApplication() == bodyKey) {
2768 bodyTextFound = true;
2769 bodyItem = textCapsule.value();
2770 PRETTY_DEBUG << "Text body found" << std::endl;
2771 } else {
2772 continue;
2773 }
2774 }
2775 }
2776 PRETTY_DEBUG << "Fetched the text components that were present." << std::endl;
2777
2778 PRETTY_DEBUG << "Attempting to fetch content for the button." << std::endl;
2779 for (std::any buttonCast : buttons) {
2780 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> buttonCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttonCast, false);
2781 if (buttonCapsule.has_value() && buttonCapsule.value()->getApplication() == _mainMenuKey) {
2782 homeButtonFound = true;
2783 homeItem = buttonCapsule.value();
2784 PRETTY_DEBUG << "Button found" << std::endl;
2785 }
2786 }
2787 PRETTY_DEBUG << "Fetched the button content." << std::endl;
2788
2789 PRETTY_DEBUG << "Attempting to fetch content for the background." << std::endl;
2790 for (std::any backgroundCast : backgrounds) {
2791 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
2792 if (backgroundCapsule.has_value() && backgroundCapsule.value()->getApplication() == backgroundKey) {
2793 backgroundFound = true;
2794 backgroundItem = backgroundCapsule.value();
2795 PRETTY_DEBUG << "Background found" << std::endl;
2796 }
2797 }
2798 PRETTY_DEBUG << "Fetched the background content." << std::endl;
2799
2800 PRETTY_DEBUG << "Values of the checker variables: \n- bodyTextFound: '" << Recoded::myToString(bodyTextFound) << "'\n- titleTextFound: '" << Recoded::myToString(titleTextFound) << "'\n- homeButtonFound: '" << Recoded::myToString(homeButtonFound) << "'" << std::endl;
2801
2802 PRETTY_DEBUG << "Checking the text for the title." << std::endl;
2803 if (!titleTextFound) {
2804 PRETTY_WARNING << "No title text instance found, creating instance." << std::endl;
2805 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_titleFontIndex], false);
2806 if (!titleFont.has_value()) {
2807 PRETTY_CRITICAL << "There is no font to be extracted for creating the title text of the game won screen screen." << std::endl;
2808 return;
2809 }
2810 titleItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(titleFont.value()), "Game Won!");
2811 titleItem->setApplication(titleKey);
2812 titleItem->setNormalColor(textColour);
2813 titleItem->setHoverColor(textColour);
2814 titleItem->setClickedColor(textColour);
2815 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(titleItem);
2816 _baseId += 1;
2817 }
2818 PRETTY_DEBUG << "Checked the text for the title." << std::endl;
2819
2820 PRETTY_DEBUG << "Checking text content for the body." << std::endl;
2821 if (!bodyTextFound) {
2822 PRETTY_WARNING << "No body text instance found, creating instance." << std::endl;
2823 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_bodyFontIndex], false);
2824 if (!bodyFont.has_value()) {
2825 PRETTY_CRITICAL << "There is no font to be extracted for creating the body text of the game won screen screen." << std::endl;
2826 return;
2827 }
2828 bodyItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(bodyFont.value()), "You have won!", 20);
2829 bodyItem->setApplication(bodyKey);
2830 bodyItem->setNormalColor(textColour);
2831 bodyItem->setHoverColor(textColour);
2832 bodyItem->setClickedColor(textColour);
2833 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(bodyItem);
2834 _baseId += 1;
2835 }
2836 PRETTY_DEBUG << "Checked the text content for the body." << std::endl;
2837
2838 PRETTY_DEBUG << "Checking if the Home button exists." << std::endl;
2839 if (!homeButtonFound) {
2840 PRETTY_WARNING << "Home button not found, creating" << std::endl;
2841 homeItem = _createButton(
2842 _mainMenuKey,
2843 "Home",
2844 std::bind(&Main::_goHome, this),
2845 "_goHome",
2846 200,
2847 30,
2848 20,
2853 );
2854 PRETTY_SUCCESS << "Home Button created" << std::endl;
2855 }
2856 PRETTY_DEBUG << "Checked if the home button existed." << std::endl;
2857
2858 if (!backgroundFound) {
2859 PRETTY_WARNING << "Background not found, changing the text components" << std::endl;
2860 const GUI::ECS::Systems::Colour defaultColourForNoBackground = GUI::ECS::Systems::Colour::GreenYellow;
2861 titleItem->setNormalColor(defaultColourForNoBackground);
2862 titleItem->setHoverColor(defaultColourForNoBackground);
2863 titleItem->setClickedColor(defaultColourForNoBackground);
2864 titleItem->setNormalColor(defaultColourForNoBackground);
2865 titleItem->setHoverColor(defaultColourForNoBackground);
2866 titleItem->setClickedColor(defaultColourForNoBackground);
2867 }
2868
2869 PRETTY_DEBUG << "Checking the coordinates for the center of the x and y axis." << std::endl;
2870 unsigned int posx = _getScreenCenterX();
2871 unsigned int posy = _getScreenCenterY();
2872 PRETTY_DEBUG << "Center of the screen is at (" << posx << ", " << posy << ")" << std::endl;
2873
2874 PRETTY_DEBUG << "The items that are currently loaded, are:\n- " << *titleItem << "\n- " << *bodyItem << "\n- " << *homeItem << std::endl;
2875
2876 PRETTY_DEBUG << "Setting the position of the components." << std::endl;
2877 titleItem->setPosition({ posx, posy });
2878 PRETTY_DEBUG << "Position for the title item is set." << std::endl;
2879 bodyItem->setPosition({ posx, posy + 40 });
2880 PRETTY_DEBUG << "Position for the body item is set." << std::endl;
2881 homeItem->setPosition({ posx, posy + 100 });
2882 PRETTY_DEBUG << "Position for the home item is set." << std::endl;
2883 if (backgroundFound) {
2884 backgroundItem->setDimension({ _windowWidth, _windowHeight });
2885 win.value()->draw(*backgroundItem);
2886 }
2887 PRETTY_DEBUG << "Component's positions updated for the current screen." << std::endl;
2888 win.value()->draw(*titleItem);
2889 PRETTY_DEBUG << "Title Item drawn." << std::endl;
2890 win.value()->draw(*bodyItem);
2891 PRETTY_DEBUG << "Body Item drawn." << std::endl;
2892 win.value()->draw(*homeItem);
2893 PRETTY_DEBUG << "Home Item drawn." << std::endl;
2894 PRETTY_SUCCESS << "Component's positions drawn successfully." << std::endl;
2895}
2896
2897void Main::_mainMenuScreen()
2898{
2899 const std::string startGameKey = "MainMenuStartGame";
2900 const std::string onlineGameKey = "MainMenuOnlineGame";
2901 const std::string settingsKey = "MainMenuSettings";
2902 const std::string exitMenuKey = "MainMenuexitMenu";
2903
2904 const unsigned int textSize = 20;
2905 const unsigned int buttonWidth = 200;
2906 const unsigned int buttonHeight = 30;
2911
2912 const std::vector<std::any> images = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
2913
2914 const std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
2915
2916 std::shared_ptr<GUI::ECS::Components::ImageComponent> background;
2917 std::shared_ptr<GUI::ECS::Components::ImageComponent> icon;
2918
2919 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> startGame;
2920 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> onlineGame;
2921 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> settings;
2922 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> exitWindow;
2923
2924 unsigned int heightPos = 0;
2925 const unsigned int heightStep = 40;
2926
2927
2928 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
2929 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
2930 if (!win.has_value()) {
2931 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
2932 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
2933 }
2934 PRETTY_SUCCESS << "Window manager component found" << std::endl;
2935
2936 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
2937 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
2938 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
2939 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
2940 _goExit();
2941 }
2942
2943 for (const std::any node : images) {
2944 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> nodeCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(node, false);
2945 if (!nodeCapsule.has_value()) {
2946 PRETTY_WARNING << "The uncasting of an image component has failed." << std::endl;
2947 continue;
2948 }
2949 if (
2950 nodeCapsule.value()->getName() == "mainMenu" ||
2951 nodeCapsule.value()->getApplication() == "mainMenu" ||
2952 nodeCapsule.value()->getName() == "Main Menu" ||
2953 nodeCapsule.value()->getApplication() == "Main Menu"
2954 ) {
2955 PRETTY_INFO << "Background found, assinning to variable" << std::endl;
2956 background = nodeCapsule.value();
2957 } else if (
2958 nodeCapsule.value()->getName() == "icon" ||
2959 nodeCapsule.value()->getApplication() == "icon" ||
2960 nodeCapsule.value()->getName() == "Main Icon" ||
2961 nodeCapsule.value()->getApplication() == "Main Icon" ||
2962 nodeCapsule.value()->getName() == "R-type" ||
2963 nodeCapsule.value()->getApplication() == "R-type"
2964 ) {
2965 PRETTY_INFO << "Icon found, assinning to variable" << std::endl;
2966 icon = nodeCapsule.value();
2967 }
2968 }
2969
2970 for (const std::any node : buttons) {
2971 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> nodeCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(node, false);
2972 if (!nodeCapsule.has_value()) {
2973 PRETTY_WARNING << "The uncasting of a button component has failed." << std::endl;
2974 continue;
2975 }
2976 if (
2977 nodeCapsule.value()->getName() == startGameKey ||
2978 nodeCapsule.value()->getApplication() == startGameKey
2979 ) {
2980 PRETTY_INFO << "Start Game found, assinning to variable" << std::endl;
2981 startGame.emplace(nodeCapsule.value());
2982 } else if (
2983 nodeCapsule.value()->getName() == onlineGameKey ||
2984 nodeCapsule.value()->getApplication() == onlineGameKey
2985 ) {
2986 PRETTY_INFO << "Online Game found, assinning to variable" << std::endl;
2987 onlineGame.emplace(nodeCapsule.value());
2988 } else if (
2989 nodeCapsule.value()->getName() == settingsKey ||
2990 nodeCapsule.value()->getApplication() == settingsKey
2991 ) {
2992 PRETTY_INFO << "Settings found, assinning to variable" << std::endl;
2993 settings.emplace(nodeCapsule.value());
2994 } else if (
2995 nodeCapsule.value()->getName() == exitMenuKey ||
2996 nodeCapsule.value()->getApplication() == exitMenuKey
2997 ) {
2998 PRETTY_INFO << "Exit Menu found, assinning to variable" << std::endl;
2999 exitWindow.emplace(nodeCapsule.value());
3000 }
3001 }
3002
3003
3004 PRETTY_DEBUG << "Setting the icon at the top center of the main menu." << std::endl;
3005 const std::pair<int, int> windowDimensions = win.value()->getDimensions();
3006 PRETTY_DEBUG << "The window dimensions are: " << windowDimensions << std::endl;
3007 if (windowDimensions.first == 0.0 || windowDimensions.second == 0.0) {
3008 PRETTY_CRITICAL << "Skipping calculations and rendering because the window is smaller or equal to 0." << std::endl;
3009 throw CustomExceptions::NoWindow("<There is no window or it's size is smaller than 1>");
3010 }
3011
3012 PRETTY_DEBUG << "Getting the icon dimensions" << std::endl;
3013 const std::pair<float, float> iconDimensions = icon->getDimension();
3014 PRETTY_DEBUG << "The icon dimensions are : " << iconDimensions << std::endl;
3015 if (iconDimensions.first <= 0 || iconDimensions.second <= 0) {
3016 PRETTY_WARNING << "Icon dimensions are zero, skipping position adjustment." << std::endl;
3017 throw CustomExceptions::NoIcon("<Invalid icon dimensions>");
3018 }
3019
3020 PRETTY_DEBUG << "Calculating the center of the window based on the image and the window dimensions." << std::endl;
3021 const float xCenter = windowDimensions.first / 2.0f;
3022 const int x = xCenter - (iconDimensions.first / 2);
3023
3024 PRETTY_DEBUG << "Calculating the y-coordinate (for the top position)." << std::endl;
3025 const int y = (windowDimensions.second / 10);
3026 PRETTY_DEBUG << "The adjusted coordinates for the icon are: " << std::pair<int, int>(x, y) << std::endl;
3027 PRETTY_DEBUG << "The coordinates are: " << std::pair<int, int>(x, y) << std::endl;
3028 icon->setPosition({ x, y });
3029 PRETTY_DEBUG << "Icon position set" << std::endl;
3030 PRETTY_DEBUG << "Setting the size of the background to that of the window" << std::endl;
3031 background->setPosition({ 0, 0 });
3032 background->setDimension({ windowDimensions.first, windowDimensions.second });
3033 PRETTY_DEBUG << "Background position set" << std::endl;
3034
3035 int verticalIconHeight = 0;
3036 if (iconDimensions.second < 1) {
3037 verticalIconHeight = static_cast<int>(std::round(iconDimensions.second * 1000)) + 100;
3038 PRETTY_DEBUG << "Calculated converted icon height's value is: " << verticalIconHeight << std::endl;
3039 } else {
3040 verticalIconHeight = iconDimensions.second;
3041 }
3042 heightPos = y + verticalIconHeight;
3043
3044 PRETTY_DEBUG << "Checking if the Start game button exists." << std::endl;
3045 if (!startGame.has_value()) {
3046 PRETTY_WARNING << "Start Game button not found, creating" << std::endl;
3047 startGame.emplace(
3048 _createButton(
3049 startGameKey, "Start Game", std::bind(&Main::_goDemo, this), "_goDemo", buttonWidth, buttonHeight, textSize, bg, normal, hover, clicked
3050 )
3051 );
3052 PRETTY_SUCCESS << "Start Button created" << std::endl;
3053 }
3054 startGame.value()->setPosition({ x, heightPos });
3055 heightPos += heightStep;
3056
3057 PRETTY_DEBUG << "Checking if the Online game button exists." << std::endl;
3058 if (!onlineGame.has_value()) {
3059 PRETTY_WARNING << "Online Game button not found, creating" << std::endl;
3060 onlineGame.emplace(
3061 _createButton(
3062 onlineGameKey, "Online Game", std::bind(&Main::_goConnectionAddress, this), "_goConnectionAddress", buttonWidth, buttonHeight, textSize, bg, normal, hover, clicked
3063 )
3064 );
3065 PRETTY_SUCCESS << "Start Button created" << std::endl;
3066 }
3067 onlineGame.value()->setPosition({ x, heightPos });
3068 heightPos += heightStep;
3069
3070 PRETTY_DEBUG << "Checking if the settings button exists." << std::endl;
3071 if (!settings.has_value()) {
3072 PRETTY_WARNING << "Settings button not found, creating" << std::endl;
3073 settings.emplace(
3074 _createButton(
3075 settingsKey, "Settings", std::bind(&Main::_goSettings, this), "_goSettings", buttonWidth, buttonHeight, textSize, bg, normal, hover, clicked
3076 )
3077 );
3078 PRETTY_SUCCESS << "Settings Button created" << std::endl;
3079 }
3080 settings.value()->setPosition({ x, heightPos });
3081 heightPos += heightStep;
3082
3083 PRETTY_DEBUG << "Checking if the exit window game button exists." << std::endl;
3084 if (!exitWindow.has_value()) {
3085 PRETTY_WARNING << "Exit Window button not found, creating" << std::endl;
3086 exitWindow.emplace(
3087 _createButton(
3088 exitMenuKey, "Exit Window", std::bind(&Main::_goExit, this), "_goExit", buttonWidth, buttonHeight, textSize, bg, normal, hover, clicked
3089 )
3090 );
3091 PRETTY_SUCCESS << "exit window Button created" << std::endl;
3092 }
3093 exitWindow.value()->setPosition({ x, heightPos });
3094 heightPos += heightStep;
3095
3096 PRETTY_DEBUG << "Drawing the elements required for the main menu to be displayed." << std::endl;
3097 win.value()->draw(*background);
3098 PRETTY_SUCCESS << "Main menu background drawn" << std::endl;
3099 win.value()->draw(*icon);
3100 PRETTY_SUCCESS << "Icon drawn" << std::endl;
3101 win.value()->draw(*(startGame.value()));
3102 PRETTY_SUCCESS << "Start game button drawn" << std::endl;
3103 win.value()->draw(*(onlineGame.value()));
3104 PRETTY_SUCCESS << "Online game button drawn" << std::endl;
3105 win.value()->draw(*(settings.value()));
3106 PRETTY_SUCCESS << "Settings button drawn" << std::endl;
3107 win.value()->draw(*(exitWindow.value()));
3108 PRETTY_SUCCESS << "Exit window button drawn" << std::endl;
3109}
3110
3111void Main::_bossFightScreen()
3112{
3113
3114 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
3115 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
3116 if (!win.has_value()) {
3117 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
3118 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
3119 }
3120 PRETTY_SUCCESS << "Window manager component found" << std::endl;
3121
3122 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
3123 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
3124 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
3125 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
3126 _goHome();
3127 }
3128}
3129
3130void Main::_connectionFailedScreen()
3131{
3132
3133 PRETTY_DEBUG << "In the _connectionFailedScreen function." << std::endl;
3134
3135 bool bodyTextFound = false;
3136 bool titleTextFound = false;
3137 bool homeButtonFound = false;
3138 bool backgroundFound = false;
3139 bool connectButtonFound = false;
3140
3141 const std::string bodyKey = "ConnectionFailedScreenBody";
3142 const std::string titleKey = "ConnectionFailedScreenTitle";
3143 const std::string backgroundKey = "connectionFailed";
3144 const std::string connectionButtonKey = "ConnectionFailedScreenConnectButton";
3145
3147
3148 std::shared_ptr<GUI::ECS::Components::TextComponent> bodyItem;
3149 std::shared_ptr<GUI::ECS::Components::TextComponent> titleItem;
3150 std::shared_ptr<GUI::ECS::Components::ButtonComponent> homeItem;
3151 std::shared_ptr<GUI::ECS::Components::ButtonComponent> connectItem;
3152 std::shared_ptr<GUI::ECS::Components::ImageComponent> backgroundItem;
3153
3154 const std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
3155 const std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
3156 const std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
3157
3158 PRETTY_DEBUG << "vector texts size: " << texts.size() << std::endl;
3159 PRETTY_DEBUG << "vector buttons size: " << buttons.size() << std::endl;
3160 PRETTY_DEBUG << "vector backgrounds size: " << backgrounds.size() << std::endl;
3161
3162 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
3163 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
3164 if (!win.has_value()) {
3165 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
3166 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
3167 }
3168 PRETTY_SUCCESS << "Window manager component found" << std::endl;
3169
3170 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
3171 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
3172 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
3173 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
3174 _goHome();
3175 }
3176
3177 PRETTY_DEBUG << "Fetching the text components if present." << std::endl;
3178 for (std::any textCast : texts) {
3179 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>>(textCast, false);
3180 if (textCapsule.has_value()) {
3181 if (textCapsule.value()->getApplication() == titleKey) {
3182 titleTextFound = true;
3183 titleItem = textCapsule.value();
3184 PRETTY_DEBUG << "Text title found" << std::endl;
3185 } else if (textCapsule.value()->getApplication() == bodyKey) {
3186 bodyTextFound = true;
3187 bodyItem = textCapsule.value();
3188 PRETTY_DEBUG << "Text body found" << std::endl;
3189 } else {
3190 continue;
3191 }
3192 }
3193 }
3194 PRETTY_DEBUG << "Fetched the text components that were present." << std::endl;
3195
3196 PRETTY_DEBUG << "Attempting to fetch content for the button." << std::endl;
3197 for (std::any buttonCast : buttons) {
3198 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> buttonCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttonCast, false);
3199 if (buttonCapsule.has_value()) {
3200 if (buttonCapsule.value()->getApplication() == _mainMenuKey) {
3201 homeButtonFound = true;
3202 homeItem = buttonCapsule.value();
3203 PRETTY_DEBUG << "Home button found" << std::endl;
3204 } else if (buttonCapsule.value()->getApplication() == connectionButtonKey) {
3205 connectButtonFound = true;
3206 connectItem = buttonCapsule.value();
3207 PRETTY_DEBUG << "Connection button found" << std::endl;
3208 }
3209 }
3210 }
3211 PRETTY_DEBUG << "Fetched the button content." << std::endl;
3212
3213 PRETTY_DEBUG << "Attempting to fetch content for the background." << std::endl;
3214 for (std::any backgroundCast : backgrounds) {
3215 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
3216 if (backgroundCapsule.has_value() && backgroundCapsule.value()->getApplication() == backgroundKey) {
3217 backgroundFound = true;
3218 backgroundItem = backgroundCapsule.value();
3219 PRETTY_DEBUG << "Background found" << std::endl;
3220 }
3221 }
3222 PRETTY_DEBUG << "Fetched the background content." << std::endl;
3223
3224 PRETTY_DEBUG << "Values of the checker variables: \n- bodyTextFound: '" << Recoded::myToString(bodyTextFound) << "'\n- titleTextFound: '" << Recoded::myToString(titleTextFound) << "'\n- homeButtonFound: '" << Recoded::myToString(homeButtonFound) << "'\n- backgroundFound: '" << Recoded::myToString(backgroundFound) << "'\n- connectButtonFound: '" << Recoded::myToString(connectButtonFound) << "'" << std::endl;
3225
3226 PRETTY_DEBUG << "Checking the text for the title." << std::endl;
3227 if (!titleTextFound) {
3228 PRETTY_WARNING << "No title text instance found, creating instance." << std::endl;
3229 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_titleFontIndex], false);
3230 if (!titleFont.has_value()) {
3231 PRETTY_CRITICAL << "There is no font to be extracted for creating the title text of the game won screen screen." << std::endl;
3232 return;
3233 }
3234 titleItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(titleFont.value()), "Connection failed!");
3235 titleItem->setApplication(titleKey);
3236 titleItem->setNormalColor(textColour);
3237 titleItem->setHoverColor(textColour);
3238 titleItem->setClickedColor(textColour);
3239 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(titleItem);
3240 _baseId += 1;
3241 }
3242 PRETTY_DEBUG << "Checked the text for the title." << std::endl;
3243
3244 PRETTY_DEBUG << "Checking text content for the body." << std::endl;
3245 if (!bodyTextFound) {
3246 PRETTY_WARNING << "No body text instance found, creating instance." << std::endl;
3247 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][_bodyFontIndex], false);
3248 if (!bodyFont.has_value()) {
3249 PRETTY_CRITICAL << "There is no font to be extracted for creating the body text of the game won screen screen." << std::endl;
3250 return;
3251 }
3252 bodyItem = std::make_shared<GUI::ECS::Components::TextComponent>(_baseId, *(bodyFont.value()), "You are not connected to the server!", 20);
3253 bodyItem->setApplication(bodyKey);
3254 bodyItem->setNormalColor(textColour);
3255 bodyItem->setHoverColor(textColour);
3256 bodyItem->setClickedColor(textColour);
3257 _ecsEntities[typeid(GUI::ECS::Components::TextComponent)].push_back(bodyItem);
3258 _baseId += 1;
3259 }
3260 PRETTY_DEBUG << "Checked the text content for the body." << std::endl;
3261
3262 PRETTY_DEBUG << "Checking if the Home button exists." << std::endl;
3263 if (!homeButtonFound) {
3264 PRETTY_WARNING << "Home button not found, creating" << std::endl;
3265 homeItem = _createButton(
3266 _mainMenuKey,
3267 "Home",
3268 std::bind(&Main::_goHome, this),
3269 "_goHome",
3270 200,
3271 30,
3272 20,
3277 );
3278 PRETTY_SUCCESS << "Home Button created" << std::endl;
3279 }
3280 PRETTY_DEBUG << "Checked if the home button existed." << std::endl;
3281
3282 PRETTY_DEBUG << "Checking if the Connect button exists." << std::endl;
3283 if (!connectButtonFound) {
3284 PRETTY_WARNING << "Connect button not found, creating" << std::endl;
3285 connectItem = _createButton(
3286 connectionButtonKey,
3287 "Connection address",
3288 std::bind(&Main::_goConnectionAddress, this),
3289 "_goConnectionAddress",
3290 300,
3291 30,
3292 20,
3297 );
3298 PRETTY_SUCCESS << "connect Button created" << std::endl;
3299 }
3300 PRETTY_DEBUG << "Checked if the home button existed." << std::endl;
3301
3302 if (!backgroundFound) {
3303 PRETTY_WARNING << "Background not found, changing the text components" << std::endl;
3304 const GUI::ECS::Systems::Colour defaultColourForNoBackground = GUI::ECS::Systems::Colour::OrangeRed;
3305 titleItem->setNormalColor(defaultColourForNoBackground);
3306 titleItem->setHoverColor(defaultColourForNoBackground);
3307 titleItem->setClickedColor(defaultColourForNoBackground);
3308 bodyItem->setNormalColor(defaultColourForNoBackground);
3309 bodyItem->setHoverColor(defaultColourForNoBackground);
3310 bodyItem->setClickedColor(defaultColourForNoBackground);
3311 }
3312
3313 PRETTY_DEBUG << "Checking the coordinates for the center of the x and y axis." << std::endl;
3314 unsigned int posx = 40;
3315 unsigned int posy = 30;
3316 PRETTY_DEBUG << "Center of the screen is at (" << posx << ", " << posy << ")" << std::endl;
3317
3318 PRETTY_DEBUG << "The items that are currently loaded, are:\n- " << *titleItem << "\n- " << *bodyItem << "\n- " << *homeItem << std::endl;
3319
3320 PRETTY_DEBUG << "Setting the position of the components." << std::endl;
3321 titleItem->setPosition({ posx, posy });
3322 PRETTY_DEBUG << "Position for the title item is set." << std::endl;
3323 bodyItem->setPosition({ posx, posy + 40 });
3324 PRETTY_DEBUG << "Position for the body item is set." << std::endl;
3325 homeItem->setPosition({ posx, posy + 100 });
3326 PRETTY_DEBUG << "Position for the home item is set." << std::endl;
3327 connectItem->setPosition({ posx, posy + 160 });
3328 PRETTY_DEBUG << "Position for the connect item is set." << std::endl;
3329 if (backgroundFound) {
3330 backgroundItem->setDimension({ _windowWidth, _windowHeight });
3331 win.value()->draw(*backgroundItem);
3332 }
3333 PRETTY_DEBUG << "Component's positions updated for the current screen." << std::endl;
3334 win.value()->draw(*titleItem);
3335 PRETTY_DEBUG << "Title Item drawn." << std::endl;
3336 win.value()->draw(*bodyItem);
3337 PRETTY_DEBUG << "Body Item drawn." << std::endl;
3338 win.value()->draw(*homeItem);
3339 PRETTY_DEBUG << "Home Item drawn." << std::endl;
3340 win.value()->draw(*connectItem);
3341 PRETTY_DEBUG << "Connect Item drawn." << std::endl;
3342 PRETTY_SUCCESS << "Component's positions drawn successfully." << std::endl;
3343}
3344
3345void Main::_connectionAddressScreen()
3346{
3347
3348 PRETTY_DEBUG << "Base id: " << Recoded::myToString(_baseId) << std::endl;
3349
3350 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
3351 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
3352 if (!win.has_value()) {
3353 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
3354 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
3355 }
3356 PRETTY_SUCCESS << "Window manager component found" << std::endl;
3357
3358 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
3359 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
3360 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
3361 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
3362 _goHome();
3363 }
3364 PRETTY_SUCCESS << "Escape key wasn't pressed" << std::endl;
3365
3366 PRETTY_DEBUG << "In the _connectionAddressScreen" << std::endl;
3367 PRETTY_DEBUG << "Initialising keys" << std::endl;
3368 // navigation and info tokens
3369 const std::string homeKey = "connectionAddressScreenHome";
3370 const std::string bodyKey = "connectionAddressScreenBody";
3371 const std::string titleKey = "connectionAddressScreenTitle";
3372 const std::string connectKey = "connectionAddressScreenConnect";
3373 // decoration token
3374 const std::string backgroundKey = "connectionAddress";
3375 // ip tokens
3376 const std::string ipV4FirstDotKey = "connectionAddressScreenIpV4FirstDot";
3377 const std::string ipV4SecondDotKey = "connectionAddressScreenIpV4SecondDot";
3378 const std::string ipV4ThirdDotKey = "connectionAddressScreenIpV4ThirdDot";
3379 // port tokens
3380 const std::string portV4ColumnKey = "connectionAddressScreenPortV4ColumnKey";
3381 // ip toggler tokens
3382 const std::string ipChunkOneUpKey = "connectionAddressScreenIpChunkOneUp";
3383 const std::string ipChunkOneDownKey = "connectionAddressScreenIpChunkOneDown";
3384 const std::string ipChunkTwoUpKey = "connectionAddressScreenIpChunkTwoUp";
3385 const std::string ipChunkTwoDownKey = "connectionAddressScreenIpChunkTwoDown";
3386 const std::string ipChunkThreeUpKey = "connectionAddressScreenIpChunkThreeUp";
3387 const std::string ipChunkThreeDownKey = "connectionAddressScreenIpChunkThreeDown";
3388 const std::string ipChunkFourUpKey = "connectionAddressScreenIpChunkFourUp";
3389 const std::string ipChunkFourDownKey = "connectionAddressScreenIpChunkFourDown";
3390 // port toggler tokens
3391 const std::string portChunkUpKey = "connectionAddressScreenPortChunkUpKey";
3392 const std::string portChunkDownKey = "connectionAddressScreenPortChunkDownKey";
3393 PRETTY_DEBUG << "Keys initialised" << std::endl;
3394
3395 PRETTY_DEBUG << "Fetching component lists from the entity list" << std::endl;
3396 const std::vector<std::any> fonts = _ecsEntities[typeid(GUI::ECS::Systems::Font)];
3397 const std::vector<std::any> texts = _ecsEntities[typeid(GUI::ECS::Components::TextComponent)];
3398 const std::vector<std::any> buttons = _ecsEntities[typeid(GUI::ECS::Components::ButtonComponent)];
3399 const std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
3400 PRETTY_DEBUG << "Fetched component lists from the entity list" << std::endl;
3401
3402 PRETTY_DEBUG << "Setting the default colour for the text that will displayed" << std::endl;
3404 PRETTY_DEBUG << "Default colour set" << std::endl;
3405
3406 PRETTY_DEBUG << "Setting the ip colour for the text that will displayed" << std::endl;
3411 PRETTY_DEBUG << "Ip text colour set" << std::endl;
3412
3413 PRETTY_DEBUG << "Setting the size of the title" << std::endl;
3414 const unsigned int titleSize = 40;
3415 PRETTY_DEBUG << "Title size set" << std::endl;
3416
3417 PRETTY_DEBUG << "Setting the size of the body text" << std::endl;
3418 const unsigned int bodySize = 20;
3419 PRETTY_DEBUG << "Body text size set" << std::endl;
3420
3421 PRETTY_DEBUG << "Setting the size for the text that will manage the ip and port display" << std::endl;
3422 const unsigned int ipTextSize = 20;
3423 const unsigned int portTextSize = 20;
3424 const unsigned int ipTextDotSize = ipTextSize;
3425 const unsigned int portTextColumnSize = portTextSize;
3426 const unsigned int buttonUpSize = 40;
3427 const unsigned int buttonUpBoxWidth = 30;
3428 const unsigned int buttonUpBoxHeight = 30;
3429 const unsigned int buttonDownSize = 40;
3430 const unsigned int buttonDownBoxWidth = 30;
3431 const unsigned int buttonDownBoxHeight = 30;
3432 PRETTY_DEBUG << "Text size set for ip and port display" << std::endl;
3433
3434 PRETTY_DEBUG << "Setting the ip and port colour for the buttons that will displayed" << std::endl;
3438 const GUI::ECS::Systems::Colour buttonUpColourIpBackground = GUI::ECS::Systems::Colour::Transparent;
3439
3442 const GUI::ECS::Systems::Colour buttonUpColourPortClicked = GUI::ECS::Systems::Colour::YellowGreen;
3443 const GUI::ECS::Systems::Colour buttonUpColourPortBackground = GUI::ECS::Systems::Colour::Transparent;
3444
3447 const GUI::ECS::Systems::Colour buttonDownColourIpClicked = GUI::ECS::Systems::Colour::YellowGreen;
3448 const GUI::ECS::Systems::Colour buttonDownColourIpBackground = GUI::ECS::Systems::Colour::Transparent;
3449
3450 const GUI::ECS::Systems::Colour buttonDownColourPortNormal = GUI::ECS::Systems::Colour::BlueViolet;
3451 const GUI::ECS::Systems::Colour buttonDownColourPortHover = GUI::ECS::Systems::Colour::Chartreuse;
3452 const GUI::ECS::Systems::Colour buttonDownColourPortClicked = GUI::ECS::Systems::Colour::YellowGreen;
3453 const GUI::ECS::Systems::Colour buttonDownColourPortBackground = GUI::ECS::Systems::Colour::Transparent;
3454 PRETTY_DEBUG << "Ip and port button colour set" << std::endl;
3455
3456 PRETTY_DEBUG << "Setting the customisation information for the general buttons" << std::endl;
3457 const GUI::ECS::Systems::Colour buttonGeneralColourBackground = GUI::ECS::Systems::Colour::White;
3458 const GUI::ECS::Systems::Colour buttonGeneralColourNormal = GUI::ECS::Systems::Colour::Black;
3460 const GUI::ECS::Systems::Colour buttonGeneralColourClicked = GUI::ECS::Systems::Colour::DeepSkyBlue;
3461 PRETTY_DEBUG << "General button customisation set" << std::endl;
3462
3463 PRETTY_DEBUG << "Fetching the fonts that will be used in the window" << std::endl;
3464 unsigned int index = 0;
3465 unsigned int titleFontIndex = 0;
3466 unsigned int bodyFontIndex = 0;
3467 unsigned int defaultFontIndex = 0;
3468 unsigned int buttonFontIndex = 0;
3469 for (std::any fontCast : fonts) {
3470 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> fontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fontCast, false);
3471 if (!fontCapsule.has_value()) {
3472 continue;
3473 }
3474 std::string applicationContext = fontCapsule.value()->getApplication();
3475 if (applicationContext == "title") {
3476 titleFontIndex = index;
3477 } else if (applicationContext == "body") {
3478 bodyFontIndex = index;
3479 } else if (applicationContext == "default") {
3480 defaultFontIndex = index;
3481 } else if (applicationContext == "button") {
3482 buttonFontIndex = index;
3483 } else {
3484 index++;
3485 continue;
3486 }
3487 index++;
3488 }
3489 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[titleFontIndex], false);
3490 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[bodyFontIndex], false);
3491 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[defaultFontIndex], false);
3492 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[buttonFontIndex], false);
3493 if (!defaultFontCapsule.has_value()) {
3494 PRETTY_DEBUG << "No default font found, aborting program" << std::endl;
3495 throw CustomExceptions::NoFont("<Default font not found>");
3496 }
3497 const std::shared_ptr<GUI::ECS::Systems::Font> defaultFont = defaultFontCapsule.value();
3498 std::shared_ptr<GUI::ECS::Systems::Font> titleFont = defaultFontCapsule.value();
3499 std::shared_ptr<GUI::ECS::Systems::Font> bodyFont = defaultFontCapsule.value();
3500 std::shared_ptr<GUI::ECS::Systems::Font> buttonFont = defaultFontCapsule.value();
3501 if (titleFontCapsule.has_value()) {
3502 PRETTY_SUCCESS << "Title font found, not defaulting to the default font." << std::endl;
3503 titleFont = titleFontCapsule.value();
3504 }
3505 if (bodyFontCapsule.has_value()) {
3506 PRETTY_SUCCESS << "Body font found, not defaulting to the default font." << std::endl;
3507 bodyFont = bodyFontCapsule.value();
3508 }
3509 if (buttonFontCapsule.has_value()) {
3510 PRETTY_SUCCESS << "Button font found, not defaulting to the default font." << std::endl;
3511 buttonFont = buttonFontCapsule.value();
3512 }
3513 PRETTY_DEBUG << "Fetched the fonts that will be used in the window" << std::endl;
3514
3515 PRETTY_DEBUG << "Holder for the background initialising" << std::endl;
3516 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundItem;
3517 PRETTY_DEBUG << "Background holder initialised" << std::endl;
3518
3519 PRETTY_DEBUG << "Holders for the title and body initialising" << std::endl;
3520 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> titleItem;
3521 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> bodyItem;
3522 PRETTY_DEBUG << "Holders for the title and body initialised" << std::endl;
3523
3524 PRETTY_DEBUG << "Holders for the home and connect buttons initialising" << std::endl;
3525 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> homeItem;
3526 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> connectItem;
3527 PRETTY_DEBUG << "Holders for the home and connect buttons initialised" << std::endl;
3528
3529 PRETTY_DEBUG << "Holders for the ip text chunks initialising" << std::endl;
3530 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4FirstChunkItem;
3531 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4FirstDotItem;
3532 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4SecondChunkItem;
3533 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4SecondDotItem;
3534 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4ThirdChunkItem;
3535 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4ThirdDotItem;
3536 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> ipV4FourthChunkItem;
3537 PRETTY_DEBUG << "Holders for the ip text chunks initialised" << std::endl;
3538
3539 PRETTY_DEBUG << "Holders for the port text chunks initialising" << std::endl;
3540 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> portV4ColumnItem;
3541 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> portV4ChunkItem;
3542 PRETTY_DEBUG << "Holders for the port text chunks initialised" << std::endl;
3543
3544 PRETTY_DEBUG << "Holders for the ip button chunks initialising" << std::endl;
3545 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkOneUpItem;
3546 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkOneDownItem;
3547 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkTwoUpItem;
3548 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkTwoDownItem;
3549 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkThreeUpItem;
3550 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkThreeDownItem;
3551 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkFourUpItem;
3552 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> ipChunkFourDownItem;
3553 PRETTY_DEBUG << "Holders for the ip button chunks initialised" << std::endl;
3554
3555 PRETTY_DEBUG << "Holders for the port button chunks initialising" << std::endl;
3556 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> portChunkUpItem;
3557 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> portChunkDownItem;
3558 PRETTY_DEBUG << "Holders for the port button chunks initialised" << std::endl;
3559
3560 PRETTY_DEBUG << "Attempting to fetch content for the background." << std::endl;
3561 for (std::any backgroundCast : backgrounds) {
3562 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
3563 if (backgroundCapsule.has_value() && backgroundCapsule.value()->getApplication() == backgroundKey) {
3564 backgroundItem.emplace(backgroundCapsule.value());
3565 PRETTY_DEBUG << "Background found" << std::endl;
3566 }
3567 }
3568 PRETTY_DEBUG << "Fetched the background content." << std::endl;
3569
3570
3571 PRETTY_DEBUG << "Fetching the text components if present." << std::endl;
3572 unsigned int textIndex = 0;
3573 for (std::any textCast : texts) {
3574 textIndex += 1;
3575 PRETTY_DEBUG << "Text component index: " << Recoded::myToString(textIndex) << std::endl;
3576 std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> textCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::TextComponent>, CustomExceptions::NoText>(textCast, false, "<No text component found>");
3577 if (!textCapsule.has_value()) {
3578 PRETTY_WARNING << "No text component found, index: " << Recoded::myToString(textIndex) << std::endl;
3579 continue;
3580 }
3581 std::string applicationContext = textCapsule.value()->getApplication();
3582 if (applicationContext == titleKey) {
3583 PRETTY_DEBUG << "Text Node '"
3584 << titleKey << "' found and assigned to the correct item."
3585 << std::endl;
3586 titleItem.emplace(textCapsule.value());
3587 } else if (applicationContext == bodyKey) {
3588 PRETTY_DEBUG << "Text Node '"
3589 << bodyKey << "' found and assigned to the correct item."
3590 << std::endl;
3591 bodyItem.emplace(textCapsule.value());
3592 } else if (applicationContext == _ipV4FirstChunkKey) {
3593 PRETTY_DEBUG << "Text Node '"
3594 << _ipV4FirstChunkKey << "' found and assigned to the correct item."
3595 << std::endl;
3596 ipV4FirstChunkItem.emplace(textCapsule.value());
3597 } else if (applicationContext == _ipV4SecondChunkKey) {
3598 PRETTY_DEBUG << "Text Node '"
3599 << _ipV4SecondChunkKey << "' found and assigned to the correct item."
3600 << std::endl;
3601 ipV4SecondChunkItem.emplace(textCapsule.value());
3602 } else if (applicationContext == _ipV4ThirdChunkKey) {
3603 PRETTY_DEBUG << "Text Node '"
3604 << _ipV4ThirdChunkKey << "' found and assigned to the correct item."
3605 << std::endl;
3606 ipV4ThirdChunkItem.emplace(textCapsule.value());
3607 } else if (applicationContext == _ipV4FourthChunkKey) {
3608 PRETTY_DEBUG << "Text Node '"
3609 << _ipV4FirstChunkKey << "' found and assigned to the correct item."
3610 << std::endl;
3611 ipV4FourthChunkItem.emplace(textCapsule.value());
3612 } else if (applicationContext == _portV4ChunkKey) {
3613 PRETTY_DEBUG << "Text Node '"
3614 << _portV4ChunkKey << "' found and assigned to the correct item."
3615 << std::endl;
3616 portV4ChunkItem.emplace(textCapsule.value());
3617 } else if (applicationContext == ipV4FirstDotKey) {
3618 PRETTY_DEBUG << "Text Node '"
3619 << ipV4FirstDotKey << "' found and assigned to the correct item."
3620 << std::endl;
3621 ipV4FirstDotItem.emplace(textCapsule.value());
3622 } else if (applicationContext == ipV4SecondDotKey) {
3623 PRETTY_DEBUG << "Text Node '"
3624 << ipV4SecondDotKey << "' found and assigned to the correct item."
3625 << std::endl;
3626 ipV4SecondDotItem.emplace(textCapsule.value());
3627 } else if (applicationContext == ipV4ThirdDotKey) {
3628 PRETTY_DEBUG << "Text Node '"
3629 << ipV4ThirdDotKey << "' found and assigned to the correct item."
3630 << std::endl;
3631 ipV4ThirdDotItem.emplace(textCapsule.value());
3632 } else if (applicationContext == portV4ColumnKey) {
3633 PRETTY_DEBUG << "Text Node '"
3634 << portV4ColumnKey << "' found and assigned to the correct item."
3635 << std::endl;
3636 portV4ColumnItem.emplace(textCapsule.value());
3637 } else {
3638 PRETTY_DEBUG << "The current text node: " << Recoded::myToString(textIndex) << " does not correspond to the researched contexts" << std::endl;
3639 PRETTY_DEBUG << "Text application context: " << applicationContext << std::endl;
3640 continue;
3641 }
3642 }
3643 PRETTY_DEBUG << "Fetched the text components that were present." << std::endl;
3644
3645 PRETTY_DEBUG << "Attempting to fetch content for the button." << std::endl;
3646 unsigned int buttonIndex = 0;
3647 for (std::any buttonCast : buttons) {
3648 buttonIndex += 1;
3649 PRETTY_DEBUG << "Button index: " << Recoded::myToString(buttonIndex) << std::endl;
3650 std::optional<std::shared_ptr<GUI::ECS::Components::ButtonComponent>> buttonCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ButtonComponent>>(buttonCast, false);
3651 if (!buttonCapsule.has_value()) {
3652 PRETTY_DEBUG << "The current button (index: " << Recoded::myToString(buttonIndex) << ") does not correspond to a button" << std::endl;
3653 continue;
3654 }
3655 std::string applicationContext = buttonCapsule.value()->getApplication();
3656 if (applicationContext == _mainMenuKey) {
3657 homeItem.emplace(buttonCapsule.value());
3658 PRETTY_DEBUG << "Main menu button found" << std::endl;
3659 } else if (applicationContext == connectKey) {
3660 connectItem.emplace(buttonCapsule.value());
3661 PRETTY_DEBUG << "Connect button found" << std::endl;
3662 } else if (applicationContext == ipChunkOneUpKey) {
3663 ipChunkOneUpItem.emplace(buttonCapsule.value());
3664 PRETTY_DEBUG << "IP chunk one up button found" << std::endl;
3665 } else if (applicationContext == ipChunkTwoUpKey) {
3666 ipChunkTwoUpItem.emplace(buttonCapsule.value());
3667 PRETTY_DEBUG << "IP chunk two up button found" << std::endl;
3668 } else if (applicationContext == ipChunkThreeUpKey) {
3669 ipChunkThreeUpItem.emplace(buttonCapsule.value());
3670 PRETTY_DEBUG << "IP chunk three up button found" << std::endl;
3671 } else if (applicationContext == ipChunkFourUpKey) {
3672 ipChunkFourUpItem.emplace(buttonCapsule.value());
3673 PRETTY_DEBUG << "IP chunk four up button found" << std::endl;
3674 } else if (applicationContext == ipChunkOneDownKey) {
3675 ipChunkOneDownItem.emplace(buttonCapsule.value());
3676 PRETTY_DEBUG << "IP chunk one down button found" << std::endl;
3677 } else if (applicationContext == ipChunkTwoDownKey) {
3678 ipChunkTwoDownItem.emplace(buttonCapsule.value());
3679 PRETTY_DEBUG << "IP chunk two down button found" << std::endl;
3680 } else if (applicationContext == ipChunkThreeDownKey) {
3681 ipChunkThreeDownItem.emplace(buttonCapsule.value());
3682 PRETTY_DEBUG << "IP chunk three down button found" << std::endl;
3683 } else if (applicationContext == ipChunkFourDownKey) {
3684 ipChunkFourDownItem.emplace(buttonCapsule.value());
3685 PRETTY_DEBUG << "IP chunk four down button found" << std::endl;
3686 } else if (applicationContext == portChunkUpKey) {
3687 portChunkUpItem.emplace(buttonCapsule.value());
3688 PRETTY_DEBUG << "Port chunk up button found" << std::endl;
3689 } else if (applicationContext == portChunkDownKey) {
3690 portChunkDownItem.emplace(buttonCapsule.value());
3691 PRETTY_DEBUG << "Port chunk down button found" << std::endl;
3692 } else {
3693 PRETTY_DEBUG << "Button Index:" << Recoded::myToString(buttonIndex) << std::endl;
3694 PRETTY_DEBUG << "Unknown button found with context: " << applicationContext << std::endl;
3695 continue;
3696 }
3697 }
3698 PRETTY_DEBUG << "Fetched the button content." << std::endl;
3699
3700 PRETTY_DEBUG << "Checking if the Home button exists." << std::endl;
3701 if (!homeItem.has_value()) {
3702 PRETTY_WARNING << "Home button not found, creating" << std::endl;
3703 homeItem = _createButton(
3704 _mainMenuKey,
3705 "Home",
3706 std::bind(&Main::_goHome, this),
3707 "_goHome",
3708 200,
3709 30,
3710 20,
3711 buttonGeneralColourBackground,
3712 buttonGeneralColourNormal,
3713 buttonGeneralColourHover,
3714 buttonGeneralColourClicked
3715 );
3716 PRETTY_SUCCESS << "Home Button created" << std::endl;
3717 }
3718 PRETTY_DEBUG << "Checked if the home button existed." << std::endl;
3719
3720 PRETTY_DEBUG << "Checking text content for the body." << std::endl;
3721 if (!bodyItem.has_value()) {
3722 PRETTY_WARNING << "No body text instance found, creating instance." << std::endl;
3723 bodyItem = _createText(
3724 bodyKey,
3725 bodyKey,
3726 "Please set the ip for the server",
3727 *bodyFont,
3728 bodySize,
3729 textColour,
3730 textColour,
3731 textColour
3732 );
3733 }
3734 PRETTY_DEBUG << "Checked the text content for the body." << std::endl;
3735
3736 PRETTY_DEBUG << "Checking if the title item is set" << std::endl;
3737 if (!titleItem.has_value()) {
3738 PRETTY_DEBUG << "Title item is not set, setting the title component" << std::endl;
3739 titleItem = _createText(
3740 titleKey,
3741 titleKey,
3742 "Server address",
3743 *titleFont,
3744 titleSize,
3745 textColour,
3746 textColour,
3747 textColour
3748 );
3749 }
3750 PRETTY_DEBUG << "Checked if the title item is set" << std::endl;
3751
3752 PRETTY_DEBUG << "Checking if the Connect button exists." << std::endl;
3753 if (!connectItem.has_value()) {
3754 PRETTY_WARNING << "Connect button not found, creating" << std::endl;
3755 connectItem = _createButton(
3756 connectKey,
3757 "Connect",
3758 std::bind(&Main::_goConnect, this),
3759 "_goConnect",
3760 200,
3761 30,
3762 20,
3763 buttonGeneralColourBackground,
3764 buttonGeneralColourNormal,
3765 buttonGeneralColourHover,
3766 buttonGeneralColourClicked
3767 );
3768 PRETTY_SUCCESS << "Connect Button created" << std::endl;
3769 }
3770 PRETTY_DEBUG << "Checked if the Connect button existed." << std::endl;
3771
3772 PRETTY_DEBUG << "Checking if the ipV4FirstChunk item is set" << std::endl;
3773 if (!ipV4FirstChunkItem.has_value()) {
3774 PRETTY_DEBUG << "Title item is not set, setting the ipV4FirstChunk component" << std::endl;
3775 ipV4FirstChunkItem = _createText(
3776 _ipV4FirstChunkKey,
3777 _ipV4FirstChunkKey,
3778 _getIpChunk(0, "127"),
3779 *defaultFont,
3780 ipTextSize,
3781 textColourIp,
3782 textColourIp,
3783 textColourIp
3784 );
3785 }
3786 PRETTY_DEBUG << "Checked if the ipV4FirstChunk item is set" << std::endl;
3787
3788 PRETTY_DEBUG << "Checking if the ipV4FirstDot item is set" << std::endl;
3789 if (!ipV4FirstDotItem.has_value()) {
3790 PRETTY_DEBUG << "Title item is not set, setting the ipV4FirstDot component" << std::endl;
3791 ipV4FirstDotItem = _createText(
3792 ipV4FirstDotKey,
3793 ipV4FirstDotKey,
3794 ".",
3795 *defaultFont,
3796 ipTextSize,
3797 textColourIpDot,
3798 textColourIpDot,
3799 textColourIpDot
3800 );
3801 }
3802 PRETTY_DEBUG << "Checked if the ipV4FirstDot item is set" << std::endl;
3803
3804 PRETTY_DEBUG << "Checking if the ipV4SecondChunk item is set" << std::endl;
3805 if (!ipV4SecondChunkItem.has_value()) {
3806 PRETTY_DEBUG << "Title item is not set, setting the ipV4SecondChunk component" << std::endl;
3807 ipV4SecondChunkItem = _createText(
3808 _ipV4SecondChunkKey,
3809 _ipV4SecondChunkKey,
3810 _getIpChunk(1, "0"),
3811 *defaultFont,
3812 ipTextSize,
3813 textColourIp,
3814 textColourIp,
3815 textColourIp
3816 );
3817 }
3818 PRETTY_DEBUG << "Checked if the ipV4SecondChunk item is set" << std::endl;
3819
3820 PRETTY_DEBUG << "Checking if the ipV4SecondDot item is set" << std::endl;
3821 if (!ipV4SecondDotItem.has_value()) {
3822 PRETTY_DEBUG << "Title item is not set, setting the ipV4SecondDot component" << std::endl;
3823 ipV4SecondDotItem = _createText(
3824 ipV4SecondDotKey,
3825 ipV4SecondDotKey,
3826 ".",
3827 *defaultFont,
3828 ipTextDotSize,
3829 textColourIpDot,
3830 textColourIpDot,
3831 textColourIpDot
3832 );
3833 }
3834 PRETTY_DEBUG << "Checked if the ipV4SecondDot item is set" << std::endl;
3835
3836 PRETTY_DEBUG << "Checking if the ipV4ThirdChunk item is set" << std::endl;
3837 if (!ipV4ThirdChunkItem.has_value()) {
3838 PRETTY_DEBUG << "Title item is not set, setting the ipV4ThirdChunk component" << std::endl;
3839 ipV4ThirdChunkItem = _createText(
3840 _ipV4ThirdChunkKey,
3841 _ipV4ThirdChunkKey,
3842 _getIpChunk(2, "0"),
3843 *defaultFont,
3844 ipTextSize,
3845 textColourIp,
3846 textColourIp,
3847 textColourIp
3848 );
3849 }
3850 PRETTY_DEBUG << "Checked if the ipV4ThirdChunk item is set" << std::endl;
3851
3852 PRETTY_DEBUG << "Checking if the ipV4ThirdDot item is set" << std::endl;
3853 if (!ipV4ThirdDotItem.has_value()) {
3854 PRETTY_DEBUG << "Title item is not set, setting the ipV4ThirdDot component" << std::endl;
3855 ipV4ThirdDotItem = _createText(
3856 ipV4ThirdDotKey,
3857 ipV4ThirdDotKey,
3858 ".",
3859 *defaultFont,
3860 ipTextDotSize,
3861 textColourIpDot,
3862 textColourIpDot,
3863 textColourIpDot
3864 );
3865 }
3866 PRETTY_DEBUG << "Checked if the ipV4ThirdDot item is set" << std::endl;
3867
3868 PRETTY_DEBUG << "Checking if the ipV4FourthChunk item is set" << std::endl;
3869 if (!ipV4FourthChunkItem.has_value()) {
3870 PRETTY_DEBUG << "Title item is not set, setting the ipV4FourthChunk component" << std::endl;
3871 ipV4FourthChunkItem = _createText(
3872 _ipV4FourthChunkKey,
3873 _ipV4FourthChunkKey,
3874 _getIpChunk(3, "1"),
3875 *defaultFont,
3876 ipTextSize,
3877 textColourIp,
3878 textColourIp,
3879 textColourIp
3880 );
3881 }
3882 PRETTY_DEBUG << "Checked if the ipV4FourthChunk item is set" << std::endl;
3883
3884 PRETTY_DEBUG << "Checking if the portV4Column item is set" << std::endl;
3885 if (!portV4ColumnItem.has_value()) {
3886 PRETTY_DEBUG << "Title item is not set, setting the portV4Column component" << std::endl;
3887 portV4ColumnItem = _createText(
3888 portV4ColumnKey,
3889 portV4ColumnKey,
3890 ":",
3891 *defaultFont,
3892 portTextColumnSize,
3893 textColourPortColumn,
3894 textColourPortColumn,
3895 textColourPortColumn
3896 );
3897 }
3898 PRETTY_DEBUG << "Checked if the portV4Column item is set" << std::endl;
3899
3900 PRETTY_DEBUG << "Checking if the portV4Chunk item is set" << std::endl;
3901 if (!portV4ChunkItem.has_value()) {
3902 PRETTY_DEBUG << "Title item is not set, setting the portV4Chunk component" << std::endl;
3903 portV4ChunkItem = _createText(
3904 _portV4ChunkKey,
3905 _portV4ChunkKey,
3906 std::to_string(_port),
3907 *defaultFont,
3908 portTextSize,
3909 textColourPort,
3910 textColourPort,
3911 textColourPort
3912 );
3913 }
3914 PRETTY_DEBUG << "Checked if the portV4Chunk item is set" << std::endl;
3915
3916 PRETTY_DEBUG << "Checking if the ipChunkOneUp button exists." << std::endl;
3917 if (!ipChunkOneUpItem.has_value()) {
3918 PRETTY_WARNING << "ipChunkOneUp button not found, creating" << std::endl;
3919 ipChunkOneUpItem = _createButton(
3920 ipChunkOneUpKey,
3921 "x",
3922 std::bind(&Main::_incrementIpChunkOne, this),
3923 "_incrementIpChunkOne",
3924 buttonUpBoxWidth,
3925 buttonUpBoxHeight,
3926 buttonUpSize,
3927 buttonUpColourIpBackground,
3928 buttonUpColourIpNormal,
3929 buttonUpColourIpHover,
3930 buttonUpColourIpClicked,
3931 buttonFont
3932 );
3933 PRETTY_SUCCESS << "ipChunkOneUp Button created" << std::endl;
3934 }
3935 PRETTY_DEBUG << "Checked if the ipChunkOneUp button existed." << std::endl;
3936
3937 PRETTY_DEBUG << "Checking if the ipChunkOneDown button exists." << std::endl;
3938 if (!ipChunkOneDownItem.has_value()) {
3939 PRETTY_WARNING << "ipChunkOneDown button not found, creating" << std::endl;
3940 ipChunkOneDownItem = _createButton(
3941 ipChunkOneDownKey,
3942 "z",
3943 std::bind(&Main::_decrementIpChunkOne, this),
3944 "_decrementIpChunkOne",
3945 buttonDownBoxWidth,
3946 buttonDownBoxHeight,
3947 buttonDownSize,
3948 buttonDownColourIpBackground,
3949 buttonDownColourIpNormal,
3950 buttonDownColourIpHover,
3951 buttonDownColourIpClicked,
3952 buttonFont
3953 );
3954 PRETTY_SUCCESS << "ipChunkOneDown Button created" << std::endl;
3955 }
3956 PRETTY_DEBUG << "Checked if the ipChunkOneDown button existed." << std::endl;
3957
3958 PRETTY_DEBUG << "Checking if the ipChunkTwoUp button exists." << std::endl;
3959 if (!ipChunkTwoUpItem.has_value()) {
3960 PRETTY_WARNING << "ipChunkTwoUp button not found, creating" << std::endl;
3961 ipChunkTwoUpItem = _createButton(
3962 ipChunkTwoUpKey,
3963 "x",
3964 std::bind(&Main::_incrementIpChunkTwo, this),
3965 "_incrementIpChunkTwo",
3966 buttonUpBoxWidth,
3967 buttonUpBoxHeight,
3968 buttonUpSize,
3969 buttonUpColourIpBackground,
3970 buttonUpColourIpNormal,
3971 buttonUpColourIpHover,
3972 buttonUpColourIpClicked,
3973 buttonFont
3974 );
3975 PRETTY_SUCCESS << "ipChunkTwoUp Button created" << std::endl;
3976 }
3977 PRETTY_DEBUG << "Checked if the ipChunkTwoUp button existed." << std::endl;
3978
3979 PRETTY_DEBUG << "Checking if the ipChunkTwoDown button exists." << std::endl;
3980 if (!ipChunkTwoDownItem.has_value()) {
3981 PRETTY_WARNING << "ipChunkTwoDown button not found, creating" << std::endl;
3982 ipChunkTwoDownItem = _createButton(
3983 ipChunkTwoDownKey,
3984 "z",
3985 std::bind(&Main::_decrementIpChunkTwo, this),
3986 "_decrementIpChunkTwo",
3987 buttonDownBoxWidth,
3988 buttonDownBoxHeight,
3989 buttonDownSize,
3990 buttonDownColourIpBackground,
3991 buttonDownColourIpNormal,
3992 buttonDownColourIpHover,
3993 buttonDownColourIpClicked,
3994 buttonFont
3995 );
3996 PRETTY_SUCCESS << "ipChunkTwoDown Button created" << std::endl;
3997 }
3998 PRETTY_DEBUG << "Checked if the ipChunkTwoDown button existed." << std::endl;
3999
4000 PRETTY_DEBUG << "Checking if the ipChunkThreeUp button exists." << std::endl;
4001 if (!ipChunkThreeUpItem.has_value()) {
4002 PRETTY_WARNING << "ipChunkThreeUp button not found, creating" << std::endl;
4003 ipChunkThreeUpItem = _createButton(
4004 ipChunkThreeUpKey,
4005 "x",
4006 std::bind(&Main::_incrementIpChunkThree, this),
4007 "_incrementIpChunkThree",
4008 buttonUpBoxWidth,
4009 buttonUpBoxHeight,
4010 buttonUpSize,
4011 buttonUpColourIpBackground,
4012 buttonUpColourIpNormal,
4013 buttonUpColourIpHover,
4014 buttonUpColourIpClicked,
4015 buttonFont
4016 );
4017 PRETTY_SUCCESS << "ipChunkThreeUp Button created" << std::endl;
4018 }
4019 PRETTY_DEBUG << "Checked if the ipChunkThreeUp button existed." << std::endl;
4020
4021 PRETTY_DEBUG << "Checking if the ipChunkThreeDown button exists." << std::endl;
4022 if (!ipChunkThreeDownItem.has_value()) {
4023 PRETTY_WARNING << "ipChunkThreeDown button not found, creating" << std::endl;
4024 ipChunkThreeDownItem = _createButton(
4025 ipChunkThreeDownKey,
4026 "z",
4027 std::bind(&Main::_decrementIpChunkThree, this),
4028 "_decrementIpChunkThree",
4029 buttonDownBoxWidth,
4030 buttonDownBoxHeight,
4031 buttonDownSize,
4032 buttonDownColourIpBackground,
4033 buttonDownColourIpNormal,
4034 buttonDownColourIpHover,
4035 buttonDownColourIpClicked,
4036 buttonFont
4037 );
4038 PRETTY_SUCCESS << "ipChunkThreeDown Button created" << std::endl;
4039 }
4040 PRETTY_DEBUG << "Checked if the ipChunkThreeDown button existed." << std::endl;
4041
4042 PRETTY_DEBUG << "Checking if the ipChunkFourUp button exists." << std::endl;
4043 if (!ipChunkFourUpItem.has_value()) {
4044 PRETTY_WARNING << "ipChunkFourUp button not found, creating" << std::endl;
4045 ipChunkFourUpItem = _createButton(
4046 ipChunkFourUpKey,
4047 "x",
4048 std::bind(&Main::_incrementIpChunkFour, this),
4049 "_incrementIpChunkFour",
4050 buttonUpBoxWidth,
4051 buttonUpBoxHeight,
4052 buttonUpSize,
4053 buttonUpColourIpBackground,
4054 buttonUpColourIpNormal,
4055 buttonUpColourIpHover,
4056 buttonUpColourIpClicked,
4057 buttonFont
4058 );
4059 PRETTY_SUCCESS << "ipChunkFourUp Button created" << std::endl;
4060 }
4061 PRETTY_DEBUG << "Checked if the ipChunkFourUp button existed." << std::endl;
4062
4063 PRETTY_DEBUG << "Checking if the ipChunkFourDown button exists." << std::endl;
4064 if (!ipChunkFourDownItem.has_value()) {
4065 PRETTY_WARNING << "ipChunkFourDown button not found, creating" << std::endl;
4066 ipChunkFourDownItem = _createButton(
4067 ipChunkFourDownKey,
4068 "z",
4069 std::bind(&Main::_decrementIpChunkFour, this),
4070 "_decrementIpChunkFour",
4071 buttonDownBoxWidth,
4072 buttonDownBoxHeight,
4073 buttonDownSize,
4074 buttonDownColourIpBackground,
4075 buttonDownColourIpNormal,
4076 buttonDownColourIpHover,
4077 buttonDownColourIpClicked,
4078 buttonFont
4079 );
4080 PRETTY_SUCCESS << "ipChunkFourDown Button created" << std::endl;
4081 }
4082 PRETTY_DEBUG << "Checked if the ipChunkFourDown button existed." << std::endl;
4083
4084 PRETTY_DEBUG << "Checking if the portChunkUp button exists." << std::endl;
4085 if (!portChunkUpItem.has_value()) {
4086 PRETTY_WARNING << "portChunkUp button not found, creating" << std::endl;
4087 portChunkUpItem = _createButton(
4088 portChunkUpKey,
4089 "x",
4090 std::bind(&Main::_incrementPortChunk, this),
4091 "_incrementPortChunk",
4092 buttonUpBoxWidth,
4093 buttonUpBoxHeight,
4094 buttonUpSize,
4095 buttonUpColourPortBackground,
4096 buttonUpColourPortNormal,
4097 buttonUpColourPortHover,
4098 buttonUpColourPortClicked,
4099 buttonFont
4100 );
4101 PRETTY_SUCCESS << "portChunkUp Button created" << std::endl;
4102 }
4103 PRETTY_DEBUG << "Checked if the portChunkUp button existed." << std::endl;
4104
4105 PRETTY_DEBUG << "Checking if the portChunkDown button exists." << std::endl;
4106 if (!portChunkDownItem.has_value()) {
4107 PRETTY_WARNING << "portChunkDown button not found, creating" << std::endl;
4108 portChunkDownItem = _createButton(
4109 portChunkDownKey,
4110 "z",
4111 std::bind(&Main::_decrementPortChunk, this),
4112 "_decrementPortChunk",
4113 buttonDownBoxWidth,
4114 buttonDownBoxHeight,
4115 buttonDownSize,
4116 buttonDownColourPortBackground,
4117 buttonDownColourPortNormal,
4118 buttonDownColourPortHover,
4119 buttonDownColourPortClicked,
4120 buttonFont
4121 );
4122 PRETTY_SUCCESS << "portChunkDown Button created" << std::endl;
4123 }
4124 PRETTY_DEBUG << "Checked if the portChunkDown button existed." << std::endl;
4125
4126 PRETTY_DEBUG << "Checking if background exists" << std::endl;
4127 if (!backgroundItem.has_value()) {
4128 PRETTY_WARNING << "Background not found, changing the text components" << std::endl;
4129 const GUI::ECS::Systems::Colour defaultColourForNoBackground = GUI::ECS::Systems::Colour::White;
4130 titleItem.value()->setNormalColor(defaultColourForNoBackground);
4131 titleItem.value()->setHoverColor(defaultColourForNoBackground);
4132 titleItem.value()->setClickedColor(defaultColourForNoBackground);
4133 bodyItem.value()->setNormalColor(defaultColourForNoBackground);
4134 bodyItem.value()->setHoverColor(defaultColourForNoBackground);
4135 bodyItem.value()->setClickedColor(defaultColourForNoBackground);
4136 ipV4FirstChunkItem.value()->setNormalColor(defaultColourForNoBackground);
4137 ipV4FirstChunkItem.value()->setHoverColor(defaultColourForNoBackground);
4138 ipV4FirstChunkItem.value()->setClickedColor(defaultColourForNoBackground);
4139 ipV4SecondChunkItem.value()->setNormalColor(defaultColourForNoBackground);
4140 ipV4SecondChunkItem.value()->setHoverColor(defaultColourForNoBackground);
4141 ipV4SecondChunkItem.value()->setClickedColor(defaultColourForNoBackground);
4142 ipV4ThirdChunkItem.value()->setNormalColor(defaultColourForNoBackground);
4143 ipV4ThirdChunkItem.value()->setHoverColor(defaultColourForNoBackground);
4144 ipV4ThirdChunkItem.value()->setClickedColor(defaultColourForNoBackground);
4145 ipV4FourthChunkItem.value()->setNormalColor(defaultColourForNoBackground);
4146 ipV4FourthChunkItem.value()->setHoverColor(defaultColourForNoBackground);
4147 ipV4FourthChunkItem.value()->setClickedColor(defaultColourForNoBackground);
4148 portV4ColumnItem.value()->setNormalColor(defaultColourForNoBackground);
4149 portV4ColumnItem.value()->setHoverColor(defaultColourForNoBackground);
4150 portV4ColumnItem.value()->setClickedColor(defaultColourForNoBackground);
4151 }
4152 PRETTY_DEBUG << "Checked if the background existed." << std::endl;
4153
4154 PRETTY_DEBUG << "Getting the center y of the screen" << std::endl;
4155 const unsigned int centerY = _getScreenCenterY();
4156 const unsigned int centerX = _getScreenCenterX();
4157 PRETTY_DEBUG << "Center Y of the screen is " << centerY << std::endl;
4158
4159 PRETTY_DEBUG << "Setting the X padding" << std::endl;
4160 const unsigned int padX = 10;
4161 PRETTY_DEBUG << "Setting the Y padding" << std::endl;
4162 const unsigned int padY = 10;
4163 PRETTY_DEBUG << "Setting the X line tracker" << std::endl;
4164 unsigned int posX = padX;
4165 PRETTY_DEBUG << "Setting the x step" << std::endl;
4166 const unsigned int ipXStep = 20;
4167 PRETTY_DEBUG << "Setting the Y column tracker" << std::endl;
4168 unsigned int posY = padY;
4169 PRETTY_DEBUG << "Setting the y step" << std::endl;
4170 const unsigned int yStep = 40;
4171
4172 PRETTY_DEBUG << "Setting positions" << std::endl;
4173 titleItem.value()->setPosition({ posX, posY });
4174 PRETTY_DEBUG << "titleItem position: " << Recoded::myToString(titleItem.value()->getPosition()) << std::endl;
4175 posY += yStep + titleSize;
4176 bodyItem.value()->setPosition({ posX, posY });
4177 PRETTY_DEBUG << "bodyItem position: " << Recoded::myToString(bodyItem.value()->getPosition()) << std::endl;
4178 posY += yStep + bodySize;
4179 PRETTY_DEBUG << "Setting the positions for the increment arrows" << std::endl;
4180 ipChunkOneUpItem.value()->setPosition({ posX, posY });
4181 PRETTY_DEBUG << "ipChunkOneUpItem position: " << Recoded::myToString(ipChunkOneUpItem.value()->getPosition()) << std::endl;
4182 posX += ipXStep + ipTextSize;
4183 posX += ipTextDotSize;
4184 ipChunkTwoUpItem.value()->setPosition({ posX, posY });
4185 PRETTY_DEBUG << "ipChunkTwoUpItem position: " << Recoded::myToString(ipChunkTwoUpItem.value()->getPosition()) << std::endl;
4186 posX += ipXStep + ipTextSize;
4187 posX += ipTextDotSize;
4188 ipChunkThreeUpItem.value()->setPosition({ posX, posY });
4189 PRETTY_DEBUG << "ipChunkThreeUpItem position: " << Recoded::myToString(ipChunkThreeUpItem.value()->getPosition()) << std::endl;
4190 posX += ipXStep + ipTextSize;
4191 posX += ipTextDotSize;
4192 ipChunkFourUpItem.value()->setPosition({ posX, posY });
4193 PRETTY_DEBUG << "ipChunkFourUpItem position: " << Recoded::myToString(ipChunkFourUpItem.value()->getPosition()) << std::endl;
4194 posX += ipXStep + ipTextSize;
4195 posX += portTextColumnSize;
4196 portChunkUpItem.value()->setPosition({ posX, posY });
4197 PRETTY_DEBUG << "portChunkUpItem position: " << Recoded::myToString(portChunkUpItem.value()->getPosition()) << std::endl;
4198 PRETTY_DEBUG << "Setting the positions for the texts representing the address" << std::endl;
4199 posX = padX;
4200 posY += yStep + ipTextSize;
4201 PRETTY_DEBUG << "Current posX: " << Recoded::myToString(posX) << ", posY: " << Recoded::myToString(posY) << std::endl;
4202 ipV4FirstChunkItem.value()->setPosition({ posX, posY });
4203 PRETTY_DEBUG << "ipV4FirstChunkItem position: " << Recoded::myToString(ipV4FirstChunkItem.value()->getPosition()) << std::endl;
4204 posX += ipXStep + ipTextSize;
4205 ipV4FirstDotItem.value()->setPosition({ posX, posY });
4206 PRETTY_DEBUG << "ipV4FirstDotItem position: " << Recoded::myToString(ipV4FirstDotItem.value()->getPosition()) << std::endl;
4207 posX += ipTextDotSize;
4208 ipV4SecondChunkItem.value()->setPosition({ posX, posY });
4209 PRETTY_DEBUG << "ipV4SecondChunkItem position: " << Recoded::myToString(ipV4SecondChunkItem.value()->getPosition()) << std::endl;
4210 posX += ipXStep + ipTextSize;
4211 ipV4SecondDotItem.value()->setPosition({ posX, posY });
4212 PRETTY_DEBUG << "ipV4SecondDotItem position: " << Recoded::myToString(ipV4SecondDotItem.value()->getPosition()) << std::endl;
4213 posX += ipTextDotSize;
4214 ipV4ThirdChunkItem.value()->setPosition({ posX, posY });
4215 PRETTY_DEBUG << "ipV4ThirdChunkItem position: " << Recoded::myToString(ipV4ThirdChunkItem.value()->getPosition()) << std::endl;
4216 posX += ipXStep + ipTextSize;
4217 ipV4ThirdDotItem.value()->setPosition({ posX, posY });
4218 PRETTY_DEBUG << "ipV4ThirdDotItem position: " << Recoded::myToString(ipV4ThirdDotItem.value()->getPosition()) << std::endl;
4219 posX += ipTextDotSize;
4220 ipV4FourthChunkItem.value()->setPosition({ posX, posY });
4221 PRETTY_DEBUG << "ipV4FourthChunkItem position: " << Recoded::myToString(ipV4FourthChunkItem.value()->getPosition()) << std::endl;
4222 posX += ipXStep + ipTextSize;
4223 portV4ColumnItem.value()->setPosition({ posX, posY });
4224 PRETTY_DEBUG << "portV4ColumnItem position: " << Recoded::myToString(portV4ColumnItem.value()->getPosition()) << std::endl;
4225 posX += portTextColumnSize;
4226 portV4ChunkItem.value()->setPosition({ posX, posY });
4227 PRETTY_DEBUG << "portV4ChunkItem position: " << Recoded::myToString(portV4ChunkItem.value()->getPosition()) << std::endl;
4228 posX = padX;
4229 posY += yStep;
4230 PRETTY_DEBUG << "Current posX: " << Recoded::myToString(posX) << ", posY: " << Recoded::myToString(posY) << std::endl;
4231 ipChunkOneDownItem.value()->setPosition({ posX, posY });
4232 PRETTY_DEBUG << "ipChunkOneDownItem position: " << Recoded::myToString(ipChunkOneDownItem.value()->getPosition()) << std::endl;
4233 posX += ipXStep + ipTextSize;
4234 posX += ipTextDotSize;
4235 ipChunkTwoDownItem.value()->setPosition({ posX, posY });
4236 PRETTY_DEBUG << "ipChunkTwoDownItem position: " << Recoded::myToString(ipChunkTwoDownItem.value()->getPosition()) << std::endl;
4237 posX += ipXStep + ipTextSize;
4238 posX += ipTextDotSize;
4239 ipChunkThreeDownItem.value()->setPosition({ posX, posY });
4240 PRETTY_DEBUG << "ipChunkThreeDownItem position: " << Recoded::myToString(ipChunkThreeDownItem.value()->getPosition()) << std::endl;
4241 posX += ipXStep + ipTextSize;
4242 posX += ipTextDotSize;
4243 ipChunkFourDownItem.value()->setPosition({ posX, posY });
4244 PRETTY_DEBUG << "ipChunkFourDownItem position: " << Recoded::myToString(ipChunkFourDownItem.value()->getPosition()) << std::endl;
4245 posX += ipXStep + ipTextSize;
4246 posX += portTextColumnSize;
4247 portChunkDownItem.value()->setPosition({ posX, posY });
4248 PRETTY_DEBUG << "portChunkDownItem position: " << Recoded::myToString(portChunkDownItem.value()->getPosition()) << std::endl;
4249 posX = padX;
4250 posY += yStep * 2;
4251 PRETTY_DEBUG << "Current posX: " << Recoded::myToString(posX) << ", posY: " << Recoded::myToString(posY) << std::endl;
4252 PRETTY_DEBUG << "Setting the position of the connect button" << std::endl;
4253 connectItem.value()->setPosition({ posX, posY });
4254 PRETTY_DEBUG << "connectItem position: " << Recoded::myToString(connectItem.value()->getPosition()) << std::endl;
4255 posX += ipXStep * 10;
4256 PRETTY_DEBUG << "Current posX: " << Recoded::myToString(posX) << ", posY: " << Recoded::myToString(posY) << std::endl;
4257 PRETTY_DEBUG << "Setting the position of the home button" << std::endl;
4258 homeItem.value()->setPosition({ posX, posY });
4259 PRETTY_DEBUG << "homeItem position: " << Recoded::myToString(homeItem.value()->getPosition()) << std::endl;
4260 PRETTY_DEBUG << "Postions set" << std::endl;
4261
4262 PRETTY_DEBUG << "Rendering the content" << std::endl;
4263 if (backgroundItem.has_value()) {
4264 win.value()->draw(*(backgroundItem.value()));
4265 }
4266 PRETTY_DEBUG << "Rendered background" << std::endl;
4267 win.value()->draw(*(titleItem.value()));
4268 PRETTY_DEBUG << "Rendered title item" << std::endl;
4269 win.value()->draw(*(bodyItem.value()));
4270 PRETTY_DEBUG << "Rendered body item" << std::endl;
4271 win.value()->draw(*(homeItem.value()));
4272 PRETTY_DEBUG << "Rendered home item" << std::endl;
4273 win.value()->draw(*(connectItem.value()));
4274 PRETTY_DEBUG << "Rendered connect item" << std::endl;
4275 win.value()->draw(*(ipV4FirstChunkItem.value()));
4276 PRETTY_DEBUG << "Rendered ipV4FirstChunk item" << std::endl;
4277 win.value()->draw(*(ipV4FirstDotItem.value()));
4278 PRETTY_DEBUG << "Rendered ipV4FirstDot item" << std::endl;
4279 win.value()->draw(*(ipV4SecondChunkItem.value()));
4280 PRETTY_DEBUG << "Rendered ipV4SecondChunk item" << std::endl;
4281 win.value()->draw(*(ipV4SecondDotItem.value()));
4282 PRETTY_DEBUG << "Rendered ipV4SecondDotItem" << std::endl;
4283 win.value()->draw(*(ipV4ThirdChunkItem.value()));
4284 PRETTY_DEBUG << "Rendered ipV4ThirdChunk item" << std::endl;
4285 win.value()->draw(*(ipV4ThirdDotItem.value()));
4286 PRETTY_DEBUG << "Rendered ipV4ThirdDot item" << std::endl;
4287 win.value()->draw(*(ipV4FourthChunkItem.value()));
4288 PRETTY_DEBUG << "Rendered ipV4FourthChunk item" << std::endl;
4289 win.value()->draw(*(portV4ColumnItem.value()));
4290 PRETTY_DEBUG << "Rendered portV4Column item" << std::endl;
4291 win.value()->draw(*(portV4ChunkItem.value()));
4292 PRETTY_DEBUG << "Rendered portV4Chunk item" << std::endl;
4293 win.value()->draw(*(ipChunkOneUpItem.value()));
4294 PRETTY_DEBUG << "Rendered ipChunkOneUp item" << std::endl;
4295 win.value()->draw(*(ipChunkOneDownItem.value()));
4296 PRETTY_DEBUG << "Rendered ipChunkOneDown item" << std::endl;
4297 win.value()->draw(*(ipChunkTwoUpItem.value()));
4298 PRETTY_DEBUG << "Rendered ipChunkTwoUp item" << std::endl;
4299 win.value()->draw(*(ipChunkTwoDownItem.value()));
4300 PRETTY_DEBUG << "Rendered ipChunkTwoDown item" << std::endl;
4301 win.value()->draw(*(ipChunkThreeUpItem.value()));
4302 PRETTY_DEBUG << "Rendered ipChunkThreeUp item" << std::endl;
4303 win.value()->draw(*(ipChunkThreeDownItem.value()));
4304 PRETTY_DEBUG << "Rendered ipChunkThreeDown item" << std::endl;
4305 win.value()->draw(*(ipChunkFourUpItem.value()));
4306 PRETTY_DEBUG << "Rendered ipChunkFourUp item" << std::endl;
4307 win.value()->draw(*(ipChunkFourDownItem.value()));
4308 PRETTY_DEBUG << "Rendered ipChunkFourDown item" << std::endl;
4309 win.value()->draw(*(portChunkUpItem.value()));
4310 PRETTY_DEBUG << "Rendered portChunkUp item" << std::endl;
4311 win.value()->draw(*(portChunkDownItem.value()));
4312 PRETTY_DEBUG << "Rendered portChunkDown item" << std::endl;
4313 PRETTY_DEBUG << "Content rendered" << std::endl;
4314 PRETTY_DEBUG << "Base id: " << Recoded::myToString(_baseId) << std::endl;
4315}
4316
4317void Main::_lobbyList()
4318{
4319
4320 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
4321 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
4322 if (!win.has_value()) {
4323 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
4324 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
4325 }
4326 PRETTY_SUCCESS << "Window manager component found" << std::endl;
4327
4328 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
4329 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
4330 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
4331 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
4332 _goHome();
4333 }
4334}
4335
4336void Main::_lobbyRoom()
4337{
4338
4339 PRETTY_DEBUG << "Getting the window manager component" << std::endl;
4340 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> win = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>, CustomExceptions::NoWindow>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][_mainWindowIndex], true, "<No window to render on>");
4341 if (!win.has_value()) {
4342 PRETTY_CRITICAL << "There is no window to draw on." << std::endl;
4343 throw CustomExceptions::NoWindow("<There was no window found on which components could be rendered>");
4344 }
4345 PRETTY_SUCCESS << "Window manager component found" << std::endl;
4346
4347 std::shared_ptr<GUI::ECS::Systems::EventManager> events = _getEventManager();
4348 PRETTY_DEBUG << "Checking if the escape key was pressed" << std::endl;
4349 if (events->isKeyPressed(GUI::ECS::Systems::Key::Escape)) {
4350 PRETTY_DEBUG << "Escape key pressed, returning to the home screen" << std::endl;
4351 _goHome();
4352 }
4353}
4354
4361void Main::_goPlay()
4362{
4364};
4365
4374void Main::setPlayer(const std::string &player)
4375{
4376 if (player == "") {
4377 PRETTY_WARNING << "Player name is empty, defaulting to 'Player'" << std::endl;
4378 _player = "Player";
4379 }
4380 if (player.length() > 9) {
4381 PRETTY_WARNING << "The player name is to long, defaulting to 'Player'" << std::endl;
4382 _player = "Player";
4383 }
4384 _player = player;
4385 _networkManager->setPlayerName(_player);
4386}
4387
4393void Main::_goDemo()
4394{
4396};
4397
4403void Main::_goHome()
4404{
4406};
4407
4413void Main::_goExit()
4414{
4416};
4417
4423void Main::_goSettings()
4424{
4426};
4427
4433void Main::_goGameOver()
4434{
4436};
4437
4443void Main::_goGameWon()
4444{
4446};
4447
4453void Main::_goBossFight()
4454{
4456};
4457
4463void Main::_goUnknown()
4464{
4466};
4467
4473void Main::_goConnectionFailed()
4474{
4476};
4477
4489void Main::_goConnect()
4490{
4491 PRETTY_DEBUG << "Reconstructing ip" << std::endl;
4492 PRETTY_DEBUG << "Getting the chunk 1" << std::endl;
4493 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> chunkOne = _getTextComponent(_ipV4FirstChunkKey);
4494 if (!chunkOne.has_value()) {
4495 PRETTY_ERROR << "Could not find the text component for the first IP chunk." << std::endl;
4496 _goConnectionFailed();
4497 return;
4498 }
4499 PRETTY_DEBUG << "Got the chunk 1" << std::endl;
4500 PRETTY_DEBUG << "Getting the chunk 2" << std::endl;
4501 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> chunkTwo = _getTextComponent(_ipV4SecondChunkKey);
4502 if (!chunkTwo.has_value()) {
4503 PRETTY_ERROR << "Could not find the text component for the second IP chunk." << std::endl;
4504 _goConnectionFailed();
4505 return;
4506 }
4507 PRETTY_DEBUG << "Got the chunk 2" << std::endl;
4508 PRETTY_DEBUG << "Getting the chunk 3" << std::endl;
4509 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> chunkThree = _getTextComponent(_ipV4ThirdChunkKey);
4510 if (!chunkThree.has_value()) {
4511 PRETTY_ERROR << "Could not find the text component for the first IP chunk." << std::endl;
4512 _goConnectionFailed();
4513 return;
4514 }
4515 PRETTY_DEBUG << "Got the chunk 3" << std::endl;
4516 PRETTY_DEBUG << "Getting the chunk 4" << std::endl;
4517 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> chunkFour = _getTextComponent(_ipV4FourthChunkKey);
4518 if (!chunkFour.has_value()) {
4519 PRETTY_ERROR << "Could not find the text component for the first IP chunk." << std::endl;
4520 _goConnectionFailed();
4521 return;
4522 }
4523 PRETTY_DEBUG << "Got the chunk 4" << std::endl;
4524 _ip = chunkOne.value()->getText() + ".";
4525 _ip += chunkTwo.value()->getText() + ".";
4526 _ip += chunkThree.value()->getText() + ".";
4527 _ip += chunkFour.value()->getText();
4528 PRETTY_DEBUG << "Reconstructing port" << std::endl;
4529 const std::optional<std::shared_ptr<GUI::ECS::Components::TextComponent>> port = _getTextComponent(_portV4ChunkKey);
4530 if (!port.has_value()) {
4531 PRETTY_ERROR << "Could not find the text component for the port chunk." << std::endl;
4532 _goConnectionFailed();
4533 return;
4534 }
4535 try {
4536 PRETTY_DEBUG << "The text port is: " << port.value()->getText() << std::endl;
4537 _port = std::stoi(port.value()->getText());
4538 PRETTY_DEBUG << "The port is" << Recoded::myToString(_port) << std::endl;
4539 }
4540 catch (std::invalid_argument &e) {
4541 PRETTY_ERROR << "Could not convert the port to an integer." << std::endl;
4542 _goConnectionFailed();
4543 return;
4544 }
4545 PRETTY_DEBUG << "Current address: " << _ip << ":" << Recoded::myToString(_port) << std::endl;
4546 PRETTY_DEBUG << "Attempting to connect" << std::endl;
4547 _initialiseConnection();
4548 _connectionInitialised = _networkManager->isConnected();
4549 PRETTY_DEBUG << "Checking if we are connected" << std::endl;
4550 if (_connectionInitialised) {
4551 PRETTY_DEBUG << "We are connected" << std::endl;
4552 _goPlay();
4553 } else {
4554 PRETTY_DEBUG << "We are not connected" << std::endl;
4555 _goConnectionFailed();
4556 }
4557};
4558
4564void Main::_goConnectionAddress()
4565{
4567};
4568
4574void Main::_goLobbyList()
4575{
4577}
4578
4584void Main::_goLobbyRoom()
4585{
4587}
4588
4592void Main::_toggleMusic()
4593{
4594 PRETTY_DEBUG << "Getting the event manager component" << std::endl;
4595 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(_ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0], false);
4596 if (!event_ptr.has_value()) {
4597 throw CustomExceptions::NoEventManager("<std::any un-casting failed>");
4598 }
4599 PRETTY_SUCCESS << "Event manager component found" << std::endl;
4600 PRETTY_DEBUG << "Flushing stored events" << std::endl;
4601 event_ptr.value()->flushEvents();
4602 PRETTY_SUCCESS << "Events flushed" << std::endl;
4603
4604
4605 if (_playMusic) {
4606 _playMusic = false;
4607 _updateMusicStatus();
4608 return;
4609 }
4610 _updateMusicStatus();
4611 _playMusic = true;
4612}
4613
4617void Main::_toggleSound()
4618{
4619 PRETTY_DEBUG << "Getting the event manager component" << std::endl;
4620 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(_ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0], false);
4621 if (!event_ptr.has_value()) {
4622 throw CustomExceptions::NoEventManager("<std::any un-casting failed>");
4623 }
4624 PRETTY_SUCCESS << "Event manager component found" << std::endl;
4625 PRETTY_DEBUG << "Flushing stored events" << std::endl;
4626 event_ptr.value()->flushEvents();
4627 PRETTY_SUCCESS << "Events flushed" << std::endl;
4628
4629
4630 PRETTY_DEBUG << "Getting the sound library if present" << std::endl;
4631 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
4632 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
4633 return;
4634 }
4635 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
4636 if (!soundLib.has_value()) {
4637 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
4638 return;
4639 }
4640 PRETTY_DEBUG << "Fetched the sound library" << std::endl;
4641
4642
4643 if (soundLib.has_value() && soundLib.value()->isEnabled()) {
4644 soundLib.value()->setPlay(false);
4645 return;
4646 }
4647 if (soundLib.has_value()) {
4648 soundLib.value()->setPlay(true);
4649 }
4650}
4651
4652void Main::_updateMusicStatus()
4653{
4654 if (!_playMusic) {
4655 PRETTY_WARNING << "No music is supposed to play, not playing any" << std::endl;
4656 _stopMainMenuMusic();
4657 _stopGameLoopMusic();
4658 _stopBossFightMusic();
4659 return;
4660 }
4661 PRETTY_DEBUG << "Updating the current music that is supposed to play." << std::endl;
4662 if (_activeScreen == ActiveScreen::MENU || _activeScreen == ActiveScreen::SETTINGS || _activeScreen == ActiveScreen::CONNECTION_ADDRESS || _activeScreen == ActiveScreen::LOBBY_LIST || _activeScreen == ActiveScreen::LOBBY_ROOM) {
4663 PRETTY_DEBUG << "We're not in game nor in a boss fight, switching to menu music." << std::endl;
4664 _startMainMenuMusic();
4665 _stopGameLoopMusic();
4666 _stopBossFightMusic();
4667 } else if (_activeScreen == ActiveScreen::GAME || _activeScreen == ActiveScreen::DEMO) {
4668 PRETTY_DEBUG << "Were gaming, swithing to game music." << std::endl;
4669 _stopMainMenuMusic();
4670 _startGameLoopMusic();
4671 _stopBossFightMusic();
4672 } else if (_activeScreen == ActiveScreen::BOSS_FIGHT) {
4673 PRETTY_DEBUG << "Boss fight!, switching to boss fight music." << std::endl;
4674 _stopMainMenuMusic();
4675 _stopGameLoopMusic();
4676 _startBossFightMusic();
4677 } else if (_activeScreen == ActiveScreen::GAME_WON) {
4678 PRETTY_DEBUG << "Game won!, switching to game won music." << std::endl;
4679 _stopMainMenuMusic();
4680 _stopGameLoopMusic();
4681 _stopBossFightMusic();
4682 _winSound();
4683 } else if (_activeScreen == ActiveScreen::GAME_OVER) {
4684 PRETTY_DEBUG << "Game won!, switching to game won music." << std::endl;
4685 _stopMainMenuMusic();
4686 _stopGameLoopMusic();
4687 _stopBossFightMusic();
4688 _deadSound();
4689 _gameOverSound();
4690 } else if (_activeScreen == ActiveScreen::CONNECTION_FAILED) {
4691 PRETTY_DEBUG << "Game won!, switching to game won music." << std::endl;
4692 _stopMainMenuMusic();
4693 _stopGameLoopMusic();
4694 _stopBossFightMusic();
4695 _deadSound();
4696 } else {
4697 PRETTY_DEBUG << "No specific music rules, defaulting to no music" << std::endl;
4698 _stopMainMenuMusic();
4699 _stopGameLoopMusic();
4700 _stopBossFightMusic();
4701 }
4702 PRETTY_DEBUG << "Updated the current music that is supposed to play." << std::endl;
4703}
4704
4714void Main::_startMainMenuMusic()
4715{
4716 if (_mainMenuMusicStarted) {
4717 return;
4718 }
4719 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
4720 for (std::any music : musics) {
4721 std::optional<std::shared_ptr<GUI::ECS::Components::MusicComponent>> node = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::MusicComponent>, CustomExceptions::MusicNotInitialised>(music, true, "<There was no music found in the vector item>");
4722 if (!node.has_value()) {
4723 continue;
4724 }
4725 if (node.value()->getApplication() == "mainMenu" || node.value()->getMusicName() == "mainMenu") {
4726 node.value()->setLoopMusic(true);
4727 node.value()->play();
4728 _mainMenuMusicStarted = true;
4729 }
4730 }
4731}
4732
4742void Main::_stopMainMenuMusic()
4743{
4744 if (!_mainMenuMusicStarted) {
4745 return;
4746 }
4747 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
4748 for (std::any music : musics) {
4749 std::optional<std::shared_ptr<GUI::ECS::Components::MusicComponent>> node = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::MusicComponent>, CustomExceptions::MusicNotInitialised>(music, true, "<There was no music found in the vector item>");
4750 if (!node.has_value()) {
4751 continue;
4752 }
4753 if (
4754 node.value()->getApplication() == "mainMenu" ||
4755 node.value()->getMusicName() == "mainMenu" ||
4756 node.value()->getApplication() == "Main Menu" ||
4757 node.value()->getMusicName() == "Main Menu"
4758 ) {
4759 node.value()->stop();
4760 _mainMenuMusicStarted = false;
4761 }
4762 }
4763}
4764
4774void Main::_startGameLoopMusic()
4775{
4776 if (_gameMusicStarted) {
4777 return;
4778 }
4779 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
4780 for (std::any music : musics) {
4781 std::optional<std::shared_ptr<GUI::ECS::Components::MusicComponent>> node = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::MusicComponent>, CustomExceptions::MusicNotInitialised>(music, true, "<There was no music found in the vector item>");
4782 if (!node.has_value()) {
4783 continue;
4784 }
4785 if (
4786 node.value()->getApplication() == "gameLoop" ||
4787 node.value()->getMusicName() == "gameLoop" ||
4788 node.value()->getApplication() == "Game Loop" ||
4789 node.value()->getMusicName() == "Game Loop"
4790 ) {
4791 node.value()->setLoopMusic(true);
4792 node.value()->play();
4793 _gameMusicStarted = true;
4794 }
4795 }
4796}
4797
4798
4808void Main::_stopGameLoopMusic()
4809{
4810 if (!_gameMusicStarted) {
4811 return;
4812 }
4813 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
4814 for (std::any music : musics) {
4815 std::optional<std::shared_ptr<GUI::ECS::Components::MusicComponent>> node = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::MusicComponent>, CustomExceptions::MusicNotInitialised>(music, true, "<There was no music found in the vector item>");
4816 if (!node.has_value()) {
4817 continue;
4818 }
4819 if (
4820 node.value()->getApplication() == "gameLoop" ||
4821 node.value()->getMusicName() == "gameLoop" ||
4822 node.value()->getApplication() == "Game Loop" ||
4823 node.value()->getMusicName() == "Game Loop"
4824 ) {
4825 node.value()->stop();
4826 _gameMusicStarted = false;
4827 }
4828 }
4829}
4830
4840void Main::_startBossFightMusic()
4841{
4842 if (_bossFightMusicStarted) {
4843 return;
4844 }
4845 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
4846 for (std::any music : musics) {
4847 std::optional<std::shared_ptr<GUI::ECS::Components::MusicComponent>> node = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::MusicComponent>, CustomExceptions::MusicNotInitialised>(music, true, "<There was no music found in the vector item>");
4848 if (!node.has_value()) {
4849 continue;
4850 }
4851 if (
4852 node.value()->getApplication() == "bossFight" ||
4853 node.value()->getMusicName() == "bossFight" ||
4854 node.value()->getApplication() == "Boss Fight" ||
4855 node.value()->getMusicName() == "Boss Fight"
4856 ) {
4857 node.value()->setLoopMusic(true);
4858 node.value()->play();
4859 _bossFightMusicStarted = true;
4860 }
4861 }
4862}
4863
4873void Main::_stopBossFightMusic()
4874{
4875 if (!_bossFightMusicStarted) {
4876 return;
4877 }
4878 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
4879 for (std::any music : musics) {
4880 std::optional<std::shared_ptr<GUI::ECS::Components::MusicComponent>> node = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::MusicComponent>, CustomExceptions::MusicNotInitialised>(music, true, "<There was no music found in the vector item>");
4881 if (!node.has_value()) {
4882 continue;
4883 }
4884 if (
4885 node.value()->getApplication() == "bossFight" ||
4886 node.value()->getMusicName() == "bossFight" ||
4887 node.value()->getApplication() == "Boss Fight" ||
4888 node.value()->getMusicName() == "Boss Fight"
4889 ) {
4890 node.value()->stop();
4891 _bossFightMusicStarted = false;
4892 }
4893 }
4894}
4895
4904void Main::_shootSound()
4905{
4906 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
4907 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
4908 return;
4909 }
4910 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
4911 if (!soundLib.has_value()) {
4912 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
4913 return;
4914 }
4915 soundLib.value()->shootSound();
4916}
4917
4926void Main::_damageSound()
4927{
4928 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
4929 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
4930 return;
4931 }
4932 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
4933 if (!soundLib.has_value()) {
4934 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
4935 return;
4936 }
4937 soundLib.value()->damageSound();
4938}
4939
4948void Main::_deadSound()
4949{
4950 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
4951 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
4952 return;
4953 }
4954 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
4955 if (!soundLib.has_value()) {
4956 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
4957 return;
4958 }
4959 soundLib.value()->deadSound();
4960}
4961
4970void Main::_buttonSound()
4971{
4972 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
4973 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
4974 return;
4975 }
4976 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
4977 if (!soundLib.has_value()) {
4978 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
4979 return;
4980 }
4981 soundLib.value()->buttonSound();
4982}
4983
4992void Main::_gameOverSound()
4993{
4994 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
4995 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
4996 return;
4997 }
4998 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
4999 if (!soundLib.has_value()) {
5000 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
5001 return;
5002 }
5003 soundLib.value()->gameOverSound();
5004}
5005
5014void Main::_winSound()
5015{
5016 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
5017 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
5018 return;
5019 }
5020 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
5021 if (!soundLib.has_value()) {
5022 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
5023 return;
5024 }
5025 soundLib.value()->winSound();
5026}
5027
5032void Main::_testContent()
5033{
5034 std::vector<std::any> musics = _ecsEntities[typeid(GUI::ECS::Components::MusicComponent)];
5035
5036 for (unsigned int index = 0; index < musics.size(); index++) {
5037 try {
5038 std::shared_ptr<GUI::ECS::Components::MusicComponent> music_ptr = std::any_cast<std::shared_ptr<GUI::ECS::Components::MusicComponent>>(musics[index]);
5039 PRETTY_INFO << "Playing " << music_ptr->getMusicName() << " audio." << std::endl;
5040 music_ptr->play();
5041 }
5042 catch (std::bad_any_cast &e) {
5043 PRETTY_ERROR << "Error casting music component, system error: " + std::string(e.what()) << std::endl;
5044 }
5045 }
5046}
5047
5048
5049
5055void Main::_mainLoop()
5056{
5057 // Create the clock component for the ecs function.
5058 std::int64_t elapsedTime = 0;
5059 std::shared_ptr<GUI::ECS::Systems::Clock> ECSClock = std::make_shared<GUI::ECS::Systems::Clock>(_baseId);
5060 _ecsEntities[typeid(GUI::ECS::Systems::Clock)].push_back(ECSClock);
5061
5062 // Get the window and event
5063 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> window_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>>(_ecsEntities[typeid(GUI::ECS::Systems::Window)][0], false);
5064 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(_ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0], false);
5065
5066 if (!window_ptr.has_value()) {
5067 throw CustomExceptions::NoWindow("<std::any un-casting failed>");
5068 }
5069 std::shared_ptr<GUI::ECS::Systems::Window> window = window_ptr.value();
5070
5071 if (!event_ptr.has_value()) {
5072 throw CustomExceptions::NoEventManager("<std::any un-casting failed>");
5073 }
5074 std::shared_ptr<GUI::ECS::Systems::EventManager> event = event_ptr.value();
5075
5076 // Get the fonts
5077 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> font_title_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][0], false);
5078 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> font_body_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][1], false);
5079 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> font_default_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][2], false);
5080 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> font_button_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(_ecsEntities[typeid(GUI::ECS::Systems::Font)][3], false);
5081
5082 if (!font_title_ptr.has_value()) {
5083 throw CustomExceptions::NoFont("Title font", "<std::any un-casting failed>");
5084 }
5085 if (!font_body_ptr.has_value()) {
5086 throw CustomExceptions::NoFont("Body font", "<std::any un-casting failed>");
5087 }
5088 if (!font_default_ptr.has_value()) {
5089 throw CustomExceptions::NoFont("Default font", "<std::any un-casting failed>");
5090 }
5091 if (!font_button_ptr.has_value()) {
5092 throw CustomExceptions::NoFont("Button font", "<std::any un-casting failed>");
5093 }
5094
5095 const std::shared_ptr<GUI::ECS::Systems::Font> font_title = font_title_ptr.value();
5096 const std::shared_ptr<GUI::ECS::Systems::Font> font_body = font_body_ptr.value();
5097 const std::shared_ptr<GUI::ECS::Systems::Font> font_default = font_default_ptr.value();
5098 const std::shared_ptr<GUI::ECS::Systems::Font> font_button = font_button_ptr.value();
5099
5100 // Update the loading text a final time to say that everything has been loaded (yes, even if it will only appear for a fraction of a second).
5101 PRETTY_INFO << "Updating loading text to 'All the ressources have been loaded'." << std::endl;
5102 _updateLoadingText("All the ressources have been loaded.");
5103 PRETTY_INFO << "Updated loading text to 'All the ressources have been loaded'." << std::endl;
5104
5105 // PRETTY_DEBUG << "Checking if the network thread is initialised" << std::endl;
5106 // if (!_networkManager->isThreadAlive()) {
5107 // PRETTY_DEBUG << "Initialising network thread" << std::endl;
5108 // _networkManager->initialize();
5109 // PRETTY_DEBUG << "Initialised network thread" << std::endl;
5110 // }
5111 // PRETTY_DEBUG << "Checked if the network thread is initialised" << std::endl;
5112
5114
5115 PRETTY_DEBUG << "Going to start the mainloop." << std::endl;
5116 while (window->isOpen()) {
5117 PRETTY_DEBUG << "The active screen is: '" << _activeScreen << "'" << std::endl;
5118 elapsedTime = ECSClock->reset();
5119 PRETTY_DEBUG << "Since the last clock reset, the time that has elapsed is: '" << elapsedTime << "'" << std::endl;
5120 PRETTY_INFO << "Sending all the packets" << std::endl;
5121 _sendAllPackets();
5122 PRETTY_INFO << "All the packets have been sent" << std::endl;
5123 PRETTY_INFO << "Processing incoming packets" << std::endl;
5124 _processIncommingPackets();
5125 PRETTY_SUCCESS << "Processed incoming packets" << std::endl;
5126 event->processEvents(*window, getActiveScreen());
5127 PRETTY_SUCCESS << "Processed window events (user input basically)" << std::endl;
5128 _updateMouseForAllRendererables(event->getMouseInfo());
5129 PRETTY_SUCCESS << "Updated mouse position for all rendererables" << std::endl;
5130 if (event->isKeyPressed(GUI::ECS::Systems::Key::End)) {
5131 PRETTY_INFO << "Caps lock is pressed, switching to debug mode" << std::endl;
5132 _testContent();
5133 }
5134 PRETTY_INFO << "Mouse position: " << Recoded::myToString(event->getMousePosition()) << std::endl;
5135 if (_activeScreen == ActiveScreen::MENU) {
5136 PRETTY_DEBUG << "Menu screen components are going to be set to be displayed" << std::endl;
5137 _mainMenuScreen();
5138 PRETTY_SUCCESS << "Menu screen components are set to be displayed" << std::endl;
5139 } else if (_activeScreen == ActiveScreen::GAME) {
5140 PRETTY_DEBUG << "Game screen components are going to be set to be displayed" << std::endl;
5141 _gameScreen();
5142 PRETTY_SUCCESS << "Game screen components are set to be displayed" << std::endl;
5143 } else if (_activeScreen == ActiveScreen::DEMO) {
5144 PRETTY_DEBUG << "Demo screen components are going to be set to be displayed" << std::endl;
5145 _demoScreen();
5146 PRETTY_SUCCESS << "Demo screen components are set to be displayed" << std::endl;
5147 } else if (_activeScreen == ActiveScreen::SETTINGS) {
5148 PRETTY_DEBUG << "Settings screen components are going to be set to be displayed" << std::endl;
5149 _settingsMenu();
5150 PRETTY_SUCCESS << "Settings screen components are set to be displayed" << std::endl;
5151 } else if (_activeScreen == ActiveScreen::GAME_OVER) {
5152 PRETTY_DEBUG << "Game Over screen components are going to be set to be displayed" << std::endl;
5153 _gameOverScreen();
5154 PRETTY_SUCCESS << "Game Over screen components are set to be displayed" << std::endl;
5155 } else if (_activeScreen == ActiveScreen::GAME_WON) {
5156 PRETTY_DEBUG << "Game Won screen components are going to be set to be displayed" << std::endl;
5157 _gameWonScreen();
5158 PRETTY_SUCCESS << "Game Won screen components are set to be displayed" << std::endl;
5159 } else if (_activeScreen == ActiveScreen::BOSS_FIGHT) {
5160 PRETTY_DEBUG << "Boss Fight screen components are going to be set to be displayed" << std::endl;
5161 _bossFightScreen();
5162 PRETTY_SUCCESS << "Boss Fight screen components are set to be displayed" << std::endl;
5163 } else if (_activeScreen == ActiveScreen::CONNECTION_FAILED) {
5164 PRETTY_DEBUG << "Connection Failed screen components are going to be set to be displayed" << std::endl;
5165 _connectionFailedScreen();
5166 PRETTY_SUCCESS << "Connection Failed screen components are set to be displayed" << std::endl;
5167 } else if (_activeScreen == ActiveScreen::CONNECTION_ADDRESS) {
5168 PRETTY_DEBUG << "Connection Address screen components are going to be set to be displayed" << std::endl;
5169 _connectionAddressScreen();
5170 PRETTY_SUCCESS << "Connection Address screen components are set to be displayed" << std::endl;
5171 } else if (_activeScreen == ActiveScreen::LOBBY_LIST) {
5172 PRETTY_DEBUG << "Lobby list screen components are going to be set to be displayed" << std::endl;
5173 _lobbyList();
5174 PRETTY_SUCCESS << "Lobby list screen components are set to be displayed" << std::endl;
5175 } else if (_activeScreen == ActiveScreen::LOBBY_ROOM) {
5176 PRETTY_DEBUG << "Lobby room screen components are going to be set to be displayed" << std::endl;
5177 _lobbyRoom();
5178 PRETTY_SUCCESS << "Lobby room screen components are set to be displayed" << std::endl;
5179 } else if (_activeScreen == ActiveScreen::LOADING) {
5180 PRETTY_DEBUG << "Update loading text screen components are going to be set to be displayed" << std::endl;
5181 _updateLoadingText("Apparently we are loading something...");
5182 PRETTY_SUCCESS << "Update loading text screen components are set to be displayed" << std::endl;
5183 } else if (_activeScreen == ActiveScreen::EXIT) {
5184 PRETTY_INFO << "Exit choice detected, stopping" << std::endl;
5185 window->close();
5186 _closeConnection();
5187 _updateMusicStatus();
5188 PRETTY_INFO << "The window is set to close" << std::endl;
5189 continue;
5190 } else {
5191 PRETTY_DEBUG << "Unknown screen components are set to be displayed" << std::endl;
5192 _unknownScreen();
5193 PRETTY_ERROR << "Unknown active screen: " << _activeScreen << std::endl;
5194 }
5195 window->display();
5196 window->clear(GUI::ECS::Systems::Colour::Black);
5197 }
5198}
5199
5206{
5207 _initialiseRessources();
5208 _mainLoop();
5209 _closeConnection();
5210}
5211
5221void Main::setIp(const std::string &ip)
5222{
5223 if (_isIpInRange(ip) == true) {
5224 _ip = ip;
5225 _networkManager->setIp(ip);
5226 } else {
5228 }
5229}
5230
5238void Main::setPort(const unsigned int port)
5239{
5240 if (_isPortCorrect(port) == true) {
5241 _port = port;
5242 _networkManager->setPort(_port);
5243 } else {
5244 throw CustomExceptions::InvalidPort(std::to_string(port));
5245 }
5246}
5247
5253void Main::setWindowWidth(unsigned int width)
5254{
5255 _windowWidth = width;
5256}
5257
5263void Main::setWindowHeight(unsigned int height)
5264{
5265 _windowHeight = height;
5266}
5267
5273void Main::setWindowCursor(bool cursorVisible)
5274{
5275 _windowCursor = cursorVisible;
5276}
5277
5283void Main::setWindowFullscreen(bool fullscreen)
5284{
5285 _windowFullscreen = fullscreen;
5286}
5287
5293void Main::setWindowTitle(const std::string &title)
5294{
5295 _windowTitle = title;
5296}
5297
5304void Main::setWindowPosition(unsigned int x, unsigned int y)
5305{
5306 _windowX = x;
5307 _windowY = y;
5308}
5309
5315void Main::setWindowPositionX(unsigned int x)
5316{
5317 _windowX = x;
5318}
5319
5325void Main::setWindowPositionY(unsigned int y)
5326{
5327 _windowY = y;
5328}
5329
5338void Main::setWindowCursorIcon(const std::string cursorImage)
5339{
5340 if (cursorImage == "" || cursorImage == "NULL") {
5341 _windowCursorIcon = nullptr;
5342 } else if (_isFilePresent(cursorImage) == true) {
5343 _windowCursorIcon = cursorImage;
5344 } else {
5345 throw CustomExceptions::FileNotFound(cursorImage);
5346 }
5347}
5348
5354void Main::setWindowCursorSprite(bool imageIsSprite)
5355{
5356 _imageIsSprite = imageIsSprite;
5357}
5358
5365void Main::setWindowCursorSpriteWidth(unsigned int spriteWidth)
5366{
5367 _spriteWidth = spriteWidth;
5368}
5369
5376{
5377 _spriteStartTop = spriteStartTop;
5378}
5379
5386{
5387 _spriteStartLeft = spriteStartLeft;
5388}
5389
5396void Main::setWindowCursorSpriteHeight(unsigned int spriteHeight)
5397{
5398 _spriteHeight = spriteHeight;
5399}
5400
5407void Main::setWindowSize(unsigned int width, unsigned int height)
5408{
5409 _spriteWidth = width;
5410 _spriteHeight = height;
5411}
5412
5418void Main::setFrameLimit(unsigned int frameLimit)
5419{
5420 if (_isFrameLimitCorrect(frameLimit) == false) {
5421 throw CustomExceptions::InvalidFrameLimit(frameLimit);
5422 }
5423 _windowFrameLimit = frameLimit;
5424}
5425
5431void Main::setConfigFile(const std::string &configFile)
5432{
5433 _configFilePath = configFile;
5434 _loadToml();
5435}
5436
5442void Main::setLog(const bool log)
5443{
5444 _log = log;
5446}
5447
5453void Main::setDebug(const bool debug)
5454{
5455 _debug = debug;
5457}
5458
5467{
5468 PRETTY_DEBUG << "Getting the event manager component" << std::endl;
5469 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(_ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0], false);
5470 if (!event_ptr.has_value()) {
5471 throw CustomExceptions::NoEventManager("<std::any un-casting failed>");
5472 }
5473 PRETTY_SUCCESS << "Event manager component found" << std::endl;
5474 PRETTY_DEBUG << "Flushing stored events" << std::endl;
5475 event_ptr.value()->flushEvents();
5476 PRETTY_SUCCESS << "Events flushed" << std::endl;
5477
5478 PRETTY_DEBUG << "Setting active screen to: '" << Recoded::myToString(screen) << "'" << std::endl;
5479 _activeScreen = screen;
5480 PRETTY_DEBUG << "Set active screen to: '" << getActiveScreenAsString() << "'." << std::endl;
5481 _updateMusicStatus();
5482}
5483
5489const std::string Main::getIp()
5490{
5491 return _ip;
5492}
5493
5499const unsigned int Main::getPort()
5500{
5501 return _port;
5502}
5503
5510{
5511 return _windowWidth;
5512}
5513
5520{
5521 return _windowHeight;
5522}
5523
5531{
5532 return _windowCursor;
5533}
5534
5542{
5543 return _windowFullscreen;
5544}
5545
5551const std::string &Main::getWindowTitle()
5552{
5553 return _windowTitle;
5554}
5555
5563const std::string &Main::getWindowCursorIcon()
5564{
5565 return _windowCursorIcon;
5566}
5567
5575{
5576 return _imageIsSprite;
5577}
5578
5586{
5587 return _spriteStartTop;
5588}
5589
5597{
5598 return _spriteStartLeft;
5599}
5600
5607{
5608 return _spriteWidth;
5609}
5610
5617{
5618 return _spriteHeight;
5619}
5620
5627const bool Main::getLog() const
5628{
5629 return _log;
5630}
5631
5638const bool Main::getDebug() const
5639{
5640 return _debug;
5641}
5642
5643
5649unsigned int Main::getFrameLimit() const
5650{
5651 return _windowFrameLimit;
5652}
5653
5654
5660std::string Main::getConfigFile() const
5661{
5662 return _configFilePath;
5663}
5664
5672std::tuple<unsigned int, unsigned int> Main::getWindowPosition()
5673{
5674 std::tuple<unsigned int, unsigned int> position;
5675 position = std::make_tuple(_windowX, _windowY);
5676 return position;
5677}
5678
5686std::tuple<unsigned int, unsigned int> Main::getWindowSize()
5687{
5688 std::tuple<unsigned int, unsigned int> dimension;
5689 dimension = std::make_tuple(_windowWidth, _windowHeight);
5690 return dimension;
5691}
5692
5699{
5700 return _activeScreen;
5701}
5702
5710const std::string Main::getActiveScreenAsString() const
5711{
5712 return Recoded::myToString(_activeScreen);
5713}
5714
5722const std::string Main::getPlayer() const
5723{
5724 return _player;
5725}
5726
5731void Main::_loadToml()
5732{
5733 _tomlContent.setTOMLPath(_configFilePath);
5734}
ActiveScreen
This is the enum class in charge of the window switcher code. This enum allows the mainloop of the pr...
#define PRETTY_ERROR
Error log with details and colour.
#define PRETTY_DEBUG
Debug log with details and colour.
#define PRETTY_INFO
Info log with details and colour.
#define PRETTY_CRITICAL
Critical log with details and colour.
#define PRETTY_WARNING
Warning log with details and colour.
#define PRETTY_SUCCESS
Success log with details and colour.
This is the file in charge of containing the main class and other ressources at the root of the progr...
This is the class in charge of informing the user that the provided file path could not be found.
Definition NotFound.hpp:27
This is the class in charge of informing the user that the background configuration they provided is ...
Definition Invalid.hpp:210
This is the class in charge of informing the user that the font configuration they provided is incorr...
Definition Invalid.hpp:88
This is the class in charge of informing the user that the window frame limit is invalid.
Definition Invalid.hpp:357
This is the class in charge of informing the user that the icon configuration they provided is incorr...
Definition Invalid.hpp:179
This is the class in charge of informing the user that the entered ip is incorrect.
Definition Invalid.hpp:30
This is the class in charge of informing the user that the music configuration they provided is incor...
Definition Invalid.hpp:118
This is the class in charge of informing the user that the port is incorrect.
Definition Invalid.hpp:59
This is the class in charge of informing the user that the sprite configuration they provided is inco...
Definition Invalid.hpp:148
This is the class in charge of informing the user that the type of the toml key is not the one that w...
Definition Invalid.hpp:737
This is the class in charge of informing the user that they tried to play music from a class that has...
This is the class in charge of informing the user that the program could not find the Background sect...
Definition No.hpp:913
This is the class in charge of informing the user that there is no configuration for the font in char...
Definition No.hpp:653
This is the class in charge of informing the user that there is no configuration for the font in char...
Definition No.hpp:713
This is the class in charge of informing the user that there is no configuration for the font in char...
Definition No.hpp:683
This is the class in charge of informing the user that they tried to access a non-existant Event Mana...
Definition No.hpp:87
This is the class in charge of informing the user that they tried to access a non-existant font insta...
Definition No.hpp:358
This is the class in charge of informing the user that they tried to access a non-existant Icon.
Definition No.hpp:147
This is the class in charge of informing the user that they tried to access a non-existant toml key i...
Definition No.hpp:772
This is the class in charge of informing the user that they tried to access a non-existant text insta...
Definition No.hpp:417
This is the class in charge of informing the user that there is no configuration for the font in char...
Definition No.hpp:623
This is the class in charge of informing the user that they tried to access a non-existant window.
Definition No.hpp:57
Manages button functionalities, including appearance, position, and callbacks.
Represents an image component in the GUI ECS system.
Manages music playback and properties for an entity in the ECS system.
Manages shapes and their associated properties in the ECS framework.
Represents a drawable and interactive sprite in the ECS system.
A class that represents a text component in the GUI system. It manages font, size,...
void render()
Renders the game entities to the window.
void tick()
Updates the game state for the current frame.
void stop()
Stops the game logic and resets the playing state.
const bool isGameOver() const
Checks if the game is over.
const bool isGameWon() const
Checks if the game has been won.
void start()
Starts the game logic and sets the game to a playing state.
void initialiseClass(std::unordered_map< std::type_index, std::vector< std::any > > &ecsEntities)
Initializes the ECS entities managed by the orchestrator.
void reset()
Resets the game state, clearing all entities and resetting conditions.
const bool isGameWon() const
Checks if the game has been won.
void tick(const std::vector< GUI::Network::MessageNode > &packets)
Updates the game state for the current frame.
void start()
Starts the game logic and sets the game to a playing state.
void reset()
Resets the game state, clearing all entities and resetting conditions.
const bool isGameOver() const
Checks if the game is over.
void render()
Renders the game entities to the window.
void stop()
Stops the game logic and resets the playing state.
void initialiseClass(std::unordered_map< std::type_index, std::vector< std::any > > &ecsEntities)
Initializes the ECS entities managed by the orchestrator.
void setNetworkClass(const std::shared_ptr< GUI::Network::ThreadCapsule > &network)
A class for managing time tracking within the ECS system.
Definition Clock.hpp:36
A class for representing and manipulating colors using RGBA components. Inherits from EntityNode to a...
Definition Colour.hpp:37
static const Colour MediumAquamarine
Definition Colour.hpp:543
static const Colour Aquamarine
Definition Colour.hpp:539
static const Colour CadetBlue
Definition Colour.hpp:504
static const Colour Grey50
Definition Colour.hpp:867
static const Colour YellowGreen
Definition Colour.hpp:599
static const Colour Cyan
Definition Colour.hpp:524
static const Colour Pink
Definition Colour.hpp:341
static const Colour Wheat
Definition Colour.hpp:660
static const Colour Transparent
Definition Colour.hpp:974
static const Colour Black
Definition Colour.hpp:969
static const Colour White
Definition Colour.hpp:757
static const Colour DeepSkyBlue
Definition Colour.hpp:486
static const Colour Chartreuse
Definition Colour.hpp:584
static const Colour Gold
Definition Colour.hpp:633
static const Colour Firebrick
Definition Colour.hpp:327
static const Colour GreenYellow
Definition Colour.hpp:589
static const Colour Aqua
Definition Colour.hpp:523
static const Colour Red
Definition Colour.hpp:322
static const Colour Coral4
Definition Colour.hpp:745
static const Colour OrangeRed
Definition Colour.hpp:732
static const Colour Chartreuse1
Definition Colour.hpp:585
static const Colour BlueViolet
Definition Colour.hpp:415
static const Colour Green
Definition Colour.hpp:581
Manages input events such as mouse movements, key presses, and window interactions.
Manages font entities in the GUI ECS.
Definition Font.hpp:45
Manages an SFML-based graphical window and handles rendering of ECS components.
Definition Window.hpp:67
void setLogEnabled(bool enabled)
Enables or disables the logging.
Definition Log.cpp:30
static Log & getInstance(const bool debug=false)
Provides access to the singleton instance of the Debug class.
Definition Log.cpp:16
void setDebugEnabled(bool enabled)
Enables or disables the debug logging.
Definition Log.cpp:35
void run()
This is the function used to start the program's main section.
bool getWindowCursor()
Get the status of the window cursor.
const std::string getIp()
Get the value of the ip that was set.
const unsigned int getPort()
Get the value of the port.
std::tuple< unsigned int, unsigned int > getWindowPosition()
Get the window's position.
void setWindowFullscreen(bool fullscreen)
Start the window in full screen mode.
const ActiveScreen getActiveScreen() const
Function in charge of returning the screen that is currently active.
const std::string & getWindowCursorIcon()
Get the icon to display for the window's cursor.
void setWindowCursor(bool cursorVisible)
Set if the cursor is visible when in the window.
std::tuple< unsigned int, unsigned int > getWindowSize()
Get the windows dimensions.
void setDebug(const bool debug)
Toggle the debug mode for the program.
const std::string getActiveScreenAsString() const
Function in charge of returning the screen that is currently active but here, the type will be conver...
void setWindowCursorSprite(bool imageIsSprite)
Set if the image passed is of type sprite or not.
bool getWindowCursorSprite()
Get the status if the cursor is of type image or spritesheet.
~Main()
Destroy the Main:: Main object.
bool getWindowCursorSpriteReadFromLeft()
Get if the program is supposed to read from the left or the rigth.
unsigned int getWindowCursorSpriteWidth()
Get the width of the sprite texture.
void setWindowPositionX(unsigned int x)
Set the X position of the window.
void setWindowCursorSpriteReadFromTop(bool spriteStartTop)
Inform if the animation should start from the top.
void setFrameLimit(unsigned int frameLimit)
The function in charge of setting the frame Limit.
void setWindowCursorIcon(const std::string cursorImage)
Set the icon of the cursor (if the user wishes to change the default icon)
void setWindowCursorSpriteWidth(unsigned int spriteWidth)
Set the height for the sprite's overlay texture, which is used to draw the sprite's texture during an...
void setIp(const std::string &ip)
This is the function in charge of setting the ip on which the GUI is going to use to communicate abou...
std::string getConfigFile() const
Function in charge of returning the path to the config file.
unsigned int getWindowCursorSpriteHeight()
Get the height of the sprite texture.
void setWindowSize(unsigned int width, unsigned int height)
The window width and height that will be created.
bool getWindowFullscreen()
Get the status of the window (if it is in fullscreen)
const std::string getPlayer() const
Retrieves the player's name.
void setPlayer(const std::string &player)
Sets the player's name.
void setWindowPosition(unsigned int x, unsigned int y)
Set the position of the window.
unsigned int getWindowHeight()
Get the value of the window height.
unsigned int getFrameLimit() const
Function in charge of returning the current frame limit.
void setWindowHeight(unsigned int height)
Set the height of the window.
void setWindowCursorSpriteHeight(unsigned int spriteHeight)
Set the height for the sprite's overlay texture, which is used to draw the sprite's texture during an...
void setPort(const unsigned int port)
Set the port on which the GUI is going to connect to.
void setConfigFile(const std::string &configFile)
This is the function in charge of seting the config filepath.
void setWindowPositionY(unsigned int y)
Set the Y position of the window.
void setActiveScreen(const ActiveScreen screen)
Function in charge of updating the type of screen that is supposed to be displayed as well as change ...
void setLog(const bool debug)
Toggle the logging mode for the program.
bool getWindowCursorSpriteReadFromTop()
Get if the program is supposed to read from the top or not.
const std::string & getWindowTitle()
Get the title of the window.
const bool getLog() const
The function in charge of returning the status of the logging variable.
void setWindowWidth(unsigned int width)
Set the width of the window.
void setWindowTitle(const std::string &title)
Set the title of the window.
const bool getDebug() const
The function in charge of returning the status of the debug variable.
void setWindowCursorSpriteReadFromLeft(bool spriteStartLeft)
Inform if the animation should start from the left.
Main(const std::string &ip="127.0.0.1", unsigned int port=9000, unsigned int windowWidth=800, unsigned int windowHeight=600, bool windowCursor=true, bool windowFullscreen=false, const std::string &windowTitle="R-Type", unsigned int windowX=0, unsigned int windowY=0, const std::string &windowCursorIcon="NULL", bool imageIsSprite=false, bool spriteStartTop=false, bool spriteStartLeft=false, unsigned int spriteWidth=20, unsigned int spriteHeight=20, unsigned int frameLimit=60, const std::string &configFilePath="client_config.toml", const bool log=false, const bool debug=false, const std::string &player="Player")
Constructor for the Main class.
Definition MainClass.cpp:43
unsigned int getWindowWidth()
Get the value of the window width.
The SoundLib class manages sound effects and interactions with ECS entities.
Definition SoundLib.hpp:35
A utility class for parsing, navigating, and managing TOML files and data.
const toml::node_type getValueType(const std::string &key) const
Retrieves the type of a value for a specific key as a TOML node type.
const std::string getTOMLPath() const
Retrieves the path of the loaded TOML file.
toml::table getTable(const std::string &key) const
Retrieves a TOML table for a specific key.
const bool hasKey(const std::string &key) const
Checks if a specific key exists in the TOML data.
void setTOMLPath(const std::string &tomlPath)
Sets the path of the TOML file to load.
void printTOML() const
Prints the TOML data to the debug stream.
std::vector< std::string > getKeys() const
Retrieves all keys from the TOML table.
const std::string getTypeAsString(const std::string &key) const
Retrieves the type of a value for a specific key as a string (alias).
T getValue(const std::string &key) const
Retrieves a value of type T from the TOML table.
const std::string myToString(const Rect< RectType > &rectangle)
Converts a Rect<T> object to its string representation.
Definition Rect.hpp:223
std::optional< T > unCast(const std::any &classNode, const bool raiseOnError=true, const std::string customErrorMessage="")
Casts the content of a std::any back to its original type.
Definition UnCast.hpp:65