LCOV - code coverage report
Current view: top level - client - GameWindow.cpp (source / functions) Hit Total Coverage
Test: code-coverage.info.cleaned Lines: 0 508 0.0 %
Date: 2023-01-28 00:08:57 Functions: 0 31 0.0 %

          Line data    Source code
       1             : #include <client.hpp>
       2             : #include <dirent.h>
       3             : #include <iostream>
       4             : #include <fstream>
       5             : #include <json/json.h>
       6             : #include <cmath>
       7             : #include <string>
       8             : #include <codecvt>
       9             : #include <variant>
      10             : 
      11             : #define MAP_X_OFFSET 175
      12             : #define MAP_Y_OFFSET 50
      13             : 
      14             : #define NUMBER_OF_FIELD 12
      15             : 
      16             : #define TCHAT_MAX_SIZE 200
      17             : 
      18             : #define WINDOW_LENGTH 1600
      19             : #define WINDOW_WIDTH 900
      20             : 
      21             : #define ACTION_CARD_PROPORTION 0.125
      22             : #define NBR_CHAR_MAX_PER_LIGNE 22
      23             : #define TURN_NUMBER 2
      24             : 
      25             : #define ASCI_BEGIN 19
      26             : #define ASCI_END 127
      27             : 
      28             : #define CARD_BORDER 18
      29             : 
      30             : #define INDEX_CHAT_BUTTON 8
      31             : #define INDEX_MAP_BUTTON 9
      32             : #define INDEX_QUIT_BUTTON 10
      33             : 
      34             : #define ARROW_INDEX 5
      35             : 
      36             : #define ELEMENT_PATH "/map/element/"
      37             : #define CHAT_MIN_SIZE 7
      38             : 
      39             : #ifndef RESOURCES_PATH
      40             : #define RESOURCES_PATH "../resources"
      41             : #endif
      42             : 
      43             : typedef std::variant<shared::Caravan, shared::Barbarian, shared::BarbarianVillage, shared::ControlPawn, shared::City> variantElement;
      44             : 
      45             : const std::vector<sf::Color> PLAYER_COLOR = {sf::Color(119, 238, 217, 160), sf::Color(251, 76, 255, 160), sf::Color(93, 109, 126, 160), sf::Color(230, 176, 170, 160)};
      46             : const sf::Color TEXT_COLOR = sf::Color(240, 230, 230);
      47             : const sf::Color TEXT_FOR_USER_BUTTON_COLOR = sf::Color(255, 255, 255, 100);
      48             : const sf::Color TEXT_FOR_USER_COLOR = sf::Color(204, 0, 102);
      49             : const sf::Color END_OF_TURN_BUTTON_COLOR = sf::Color(247, 200, 195);
      50             : 
      51             : using namespace client;
      52             : 
      53             : /*!
      54             :  * @brief Constructor
      55             :  *
      56             :  * Constructor of GameWindow class
      57             :  */
      58           0 : GameWindow::GameWindow()
      59             : {
      60           0 :     firstHexagonPosition = {MAP_X_OFFSET, MAP_Y_OFFSET};
      61           0 :     chatBox = std::make_unique<Chat>();
      62             : 
      63           0 :     const Json::Value &data = openJsonFile("/pop-up/dataButton.json");
      64           0 :     validateBoxesWindow = std::make_unique<PopUpWindow>(WINDOW_LENGTH, WINDOW_WIDTH, data, true);
      65           0 :     winnerWindow = std::make_unique<PopUpWindow>(WINDOW_LENGTH, WINDOW_WIDTH, data, false);
      66           0 :     validateBoxesWindow->gameWindow = this;
      67             : 
      68           0 :     chatBox = std::make_unique<Chat>();
      69           0 : }
      70             : 
      71             : /*!
      72             :  * @brief Display all the different variable in the screen
      73             :  */
      74           0 : void GameWindow::displayWindow()
      75             : {
      76             : 
      77           0 :     gameEnginePtr->clientWindow->clear(sf::Color::Blue);
      78             : 
      79           0 :     backgroundTexture->drawTextureDisplayerSprite(gameEnginePtr->clientWindow);
      80             : 
      81           0 :     for (auto &mapTexture : mapTextureToDisplay)
      82             :     {
      83           0 :         mapTexture.drawTextureDisplayerSprite(gameEnginePtr->clientWindow);
      84             :     }
      85             : 
      86           0 :     std::unique_lock<std::mutex> lock(updatePlayerMutex);
      87           0 :     for (auto &elementTexture : elementTextureToDisplay)
      88             :     {
      89           0 :         elementTexture.second->drawTextureDisplayerSprite(gameEnginePtr->clientWindow);
      90             :     }
      91           0 :     lock.unlock();
      92             : 
      93           0 :     for (auto &priorityCardTexture : priorityCards)
      94             :     {
      95           0 :         priorityCardTexture.texture->drawTextureDisplayerSprite(gameEnginePtr->clientWindow);
      96           0 :         gameEnginePtr->clientWindow->draw(*priorityCardTexture.title);
      97           0 :         gameEnginePtr->clientWindow->draw(*priorityCardTexture.nbOfBoxesText);
      98           0 :         if (priorityCardTexture.isUp)
      99             :         {
     100           0 :             gameEnginePtr->clientWindow->draw(*priorityCardTexture.body);
     101           0 :             priorityCardTexture.validateButton->drawButton(gameEnginePtr->clientWindow);
     102             :         }
     103             :     }
     104           0 :     boxTexture->drawTextureDisplayerSprite(gameEnginePtr->clientWindow);
     105             : 
     106           0 :     for (auto &actionCardTexture : actionCardsToDisplay)
     107             :     {
     108           0 :         gameEnginePtr->clientWindow->draw(actionCardTexture.texture->getSprite(0));
     109           0 :         gameEnginePtr->clientWindow->draw(*actionCardTexture.title);
     110           0 :         gameEnginePtr->clientWindow->draw(*actionCardTexture.body);
     111             :     }
     112             : 
     113           0 :     for (auto &whoIsPlayingButton : whoIsPlayingButtons)
     114             :     {
     115           0 :         whoIsPlayingButton.drawButton(gameEnginePtr->clientWindow);
     116             :     }
     117             : 
     118           0 :     gameEnginePtr->clientWindow->draw(hudTextureToDisplay.at(TURN_NUMBER % 5).getSprite());
     119             : 
     120           0 :     for (auto &hudTexture : hudTextureToDisplay)
     121             :     {
     122           0 :         hudTexture.drawTextureDisplayerSprite(gameEnginePtr->clientWindow);
     123             :     }
     124             : 
     125           0 :     textForTheUser->drawButton(gameEnginePtr->clientWindow);
     126           0 :     endOfRoundButton->drawButton(gameEnginePtr->clientWindow);
     127             : 
     128           0 :     if (validateBoxesWindow->isWindowActive)
     129             :     {
     130           0 :         validateBoxesWindow->drawValidateBoxesButtons(gameEnginePtr->clientWindow);
     131             :     }
     132             : 
     133           0 :     if (isChatOpen)
     134             :     {
     135           0 :         chatBox->drawChat(gameEnginePtr->clientWindow);
     136             :     }
     137             : 
     138           0 :     if (winnerWindow->isWindowActive)
     139             :     {
     140           0 :         winnerWindow->drawWinnerWindow(gameEnginePtr->clientWindow);
     141             :     }
     142             : 
     143           0 :     gameEnginePtr->clientWindow->display();
     144           0 : }
     145             : 
     146             : /*!
     147             :  * @brief Loop that look for events to happend and call displayWindow()
     148             :  * @param clientWindow is window that comes from the engine
     149             :  * @param quitGame is the function used to quit the menu, it is load as an attribut
     150             :  * @param callback is the function used to return where the user click on the screen
     151             :  */
     152           0 : void GameWindow::startGame()
     153             : {
     154           0 :     if (gameEnginePtr == nullptr)
     155             :     {
     156           0 :         return;
     157             :     }
     158             : 
     159           0 :     loadMapTexture();
     160           0 :     loadElementTexture();
     161           0 :     updateElementTexture();
     162           0 :     loadHudTexture();
     163           0 :     gameEnginePtr->areTextureLoaded.store(true);
     164           0 :     addPlayer(gameEnginePtr->myself->getName());
     165             : 
     166           0 :     std::shared_ptr<bool> moveMode = std::make_shared<bool>(false);
     167           0 :     std::shared_ptr<bool> clickMode = std::make_shared<bool>(false);
     168             : 
     169           0 :     sf::Vector2i clickStartingPoint;
     170             : 
     171           0 :     long lastUpdateTimer = getCurrentTime(false);
     172             : 
     173           0 :     while (gameEnginePtr->clientWindow->isOpen())
     174             :     {
     175             : 
     176           0 :         if (getCurrentTime(false) - lastUpdateTimer > (100 / 3))
     177             :         {
     178           0 :             displayWindow();
     179           0 :             lastUpdateTimer = getCurrentTime(false);
     180             :         }
     181             : 
     182             :         // handle events
     183             :         sf::Event event;
     184           0 :         while (gameEnginePtr->clientWindow->pollEvent(event))
     185             :         {
     186           0 :             if (handleGameEvent(event, clickStartingPoint, moveMode, clickMode))
     187             :             {
     188           0 :                 return;
     189             :             }
     190             :         }
     191             :     }
     192           0 : }
     193             : 
     194             : /*!
     195             :  * @brief Test events and do actions corresponding to the event
     196             :  * @param event pointer to the event
     197             :  * @param clickStartingPoint reference used to know where the user start pressing mouse
     198             :  * @param moveMode pointer to know if the map is moving on the screen
     199             :  * @param clickMode pointer to know if the user is clicking on the screen
     200             :  */
     201           0 : bool GameWindow::handleGameEvent(sf::Event &event, sf::Vector2i &clickStartingPoint, std::shared_ptr<bool> moveMode, std::shared_ptr<bool> clickMode)
     202             : {
     203           0 :     std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
     204           0 :     switch (event.type)
     205             :     {
     206           0 :     case sf::Event::MouseButtonPressed:
     207             : 
     208           0 :         *clickMode = true;
     209           0 :         clickStartingPoint = sf::Mouse::getPosition(*gameEnginePtr->clientWindow);
     210           0 :         if (clickAction(event, clickStartingPoint, moveMode))
     211             :         {
     212           0 :             std::cout << "You have quit the game\n";
     213           0 :             gameEnginePtr->handleQuitMenu(true);
     214           0 :             return true;
     215             :         }
     216           0 :         break;
     217             : 
     218           0 :     case sf::Event::MouseButtonReleased:
     219           0 :         *clickMode = false;
     220           0 :         break;
     221             : 
     222           0 :     case sf::Event::MouseMoved:
     223           0 :         if (*moveMode && *clickMode)
     224             :         {
     225           0 :             moveMap(clickStartingPoint, sf::Mouse::getPosition(*gameEnginePtr->clientWindow));
     226             :         }
     227           0 :         break;
     228             : 
     229           0 :     case sf::Event::TextEntered:
     230           0 :         if (event.text.unicode > ASCI_BEGIN && event.text.unicode < ASCI_END && isChatOpen)
     231             :         {
     232           0 :             chatBox->addChatChar(converter.to_bytes(event.text.unicode));
     233             :         }
     234           0 :         break;
     235             : 
     236           0 :     case sf::Event::KeyPressed:
     237           0 :         if (handleKeyboardEvent(event.key))
     238           0 :             return true;
     239           0 :         break;
     240             : 
     241           0 :     case sf::Event::Closed:
     242           0 :         gameEnginePtr->handleQuitMenu(true);
     243           0 :         return true;
     244             : 
     245           0 :     default:
     246           0 :         break;
     247             :     }
     248           0 :     return false;
     249           0 : }
     250             : 
     251             : /*!
     252             :  * @brief Test keyboard events and do actions corresponding to the event
     253             :  * @param keyEvent The event
     254             :  * @param moveMode pointer to know if the map is moving on the screen
     255             :  * @param clickStartingPoint reference used to know where the user start pressing mouse
     256             :  */
     257           0 : bool GameWindow::handleKeyboardEvent(sf::Event::KeyEvent keyEvent)
     258             : {
     259           0 :     switch (keyEvent.code)
     260             :     {
     261           0 :     case sf::Keyboard::Enter:
     262           0 :         if (isChatOpen)
     263             :         {
     264           0 :             sendMessage();
     265             :         }
     266           0 :         break;
     267             : 
     268           0 :     case sf::Keyboard::BackSpace:
     269           0 :         chatBox->deleteChatChar();
     270           0 :         break;
     271             : 
     272           0 :     default:
     273           0 :         break;
     274             :     }
     275           0 :     return false;
     276             : }
     277             : 
     278             : /*!
     279             :  * @brief This function send a message to the server
     280             :  */
     281           0 : void GameWindow::sendMessage()
     282             : {
     283           0 :     std::unique_lock<std::mutex> lock(chatBox->mutexChat);
     284           0 :     std::string message = "chat " + chatBox->message + "\n";
     285           0 :     lock.unlock();
     286             : 
     287           0 :     if (message.size() < CHAT_MIN_SIZE)
     288           0 :         return;
     289             : 
     290           0 :     std::unique_lock<std::mutex> lock2(gameEnginePtr->myself->qAndA.sharedDataMutex);
     291           0 :     gameEnginePtr->myself->qAndA.question = message;
     292           0 :     lock2.unlock();
     293           0 :     gameEnginePtr->askServer();
     294           0 : }
     295             : 
     296             : /*!
     297             :  * @brief Change the cursor type to a hand or an arrow
     298             :  * @param moveMode pointer to know if the map is moving on the screen
     299             :  */
     300           0 : void GameWindow::changeMouseCursor(sf::Event &event, std::shared_ptr<bool> moveMode)
     301             : {
     302           0 :     if (event.mouseButton.button == sf::Mouse::Right)
     303             :     {
     304           0 :         sf::Vector2i nullPosition(0, 0);
     305           0 :         moveMap(nullPosition, {MAP_X_OFFSET, MAP_Y_OFFSET}, true);
     306           0 :         gameEnginePtr->clientWindow->setMouseCursor(clientCursor);
     307           0 :         return;
     308             :     }
     309             : 
     310           0 :     if (*moveMode)
     311             :     {
     312           0 :         *moveMode = false;
     313           0 :         clientCursor.loadFromSystem(sf::Cursor::Arrow);
     314             :     }
     315             :     else
     316             :     {
     317           0 :         *moveMode = true;
     318           0 :         clientCursor.loadFromSystem(sf::Cursor::Hand);
     319             :     }
     320           0 :     gameEnginePtr->clientWindow->setMouseCursor(clientCursor);
     321             : }
     322             : 
     323             : /*!
     324             :  * @brief Move the map on the screen
     325             :  * @param clickStartingPoint reference used to know where the user start pressing mouse
     326             :  * @param position position of the mouse
     327             :  * @param reset if true, reset the map to the original position, false by default
     328             :  */
     329           0 : void GameWindow::moveMap(sf::Vector2i &clickStartingPoint, sf::Vector2i position, bool reset)
     330             : {
     331           0 :     if (reset)
     332             :     {
     333           0 :         clickStartingPoint.x = firstHexagonPosition[0];
     334           0 :         clickStartingPoint.y = firstHexagonPosition[1];
     335             :     }
     336           0 :     std::array<int, 2> newMapOffset = {position.x - clickStartingPoint.x,
     337           0 :                                        position.y - clickStartingPoint.y};
     338             : 
     339           0 :     if (reset)
     340             :     {
     341           0 :         firstHexagonPosition = {MAP_X_OFFSET, MAP_Y_OFFSET};
     342             :     }
     343             :     else
     344             :     {
     345           0 :         firstHexagonPosition = {firstHexagonPosition[0] + newMapOffset[0],
     346           0 :                                 firstHexagonPosition[1] + newMapOffset[1]};
     347             :     }
     348             : 
     349           0 :     for (unsigned i = 0; i < mapTextureToDisplay.size(); i++)
     350             :     {
     351           0 :         mapTextureToDisplay[i].moveSpritePosition(newMapOffset[0], newMapOffset[1]);
     352             :     }
     353             : 
     354           0 :     for (auto &kv : elementTextureToDisplay)
     355             :     {
     356           0 :         kv.second->moveSpritePosition(newMapOffset[0], newMapOffset[1]);
     357             :     }
     358             : 
     359           0 :     clickStartingPoint = sf::Mouse::getPosition(*gameEnginePtr->clientWindow);
     360           0 : }
     361             : 
     362             : /*!
     363             :  * @brief Open JSON File
     364             :  * @param path path of the JSON File
     365             :  */
     366           0 : const Json::Value GameWindow::openJsonFile(std::string path)
     367             : {
     368           0 :     std::ifstream file(RESOURCES_PATH + path);
     369             : 
     370           0 :     if (!file.is_open())
     371             :     {
     372           0 :         std::cerr << "Error while opening json ressources file" << std::endl;
     373           0 :         std::cerr << path << std::endl;
     374           0 :         exit(1);
     375             :     }
     376           0 :     std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
     377             : 
     378           0 :     std::unique_ptr<Json::CharReader> reader = std::unique_ptr<Json::CharReader>(Json::CharReaderBuilder().newCharReader());
     379           0 :     Json::Value obj;
     380           0 :     std::string errors;
     381           0 :     reader->parse(str.c_str(), str.c_str() + str.size(), &obj, &errors);
     382             : 
     383           0 :     const Json::Value &data = obj["data"];
     384             : 
     385           0 :     return data;
     386           0 : }
     387             : 
     388             : /*!
     389             :  * @brief Move to right priority cards when a player play one
     390             :  * @param difficulty level of difficulty when the card is played (0 to 4 for the 5 different field)
     391             :  */
     392           0 : void GameWindow::moveToRightPriorityCards(int difficulty)
     393             : {
     394           0 :     const Json::Value &dataNumber = openJsonFile("/hud/data-number.json");
     395             : 
     396             :     int xPos;
     397             :     int yPos;
     398             : 
     399           0 :     for (unsigned i = difficulty; i > 0; i--)
     400             :     {
     401           0 :         priorityCards[i - 1].difficulty = i;
     402           0 :         std::iter_swap(priorityCards.begin() + i, priorityCards.begin() + (i - 1));
     403             :     }
     404           0 :     priorityCards[0].difficulty = 0;
     405             : 
     406           0 :     for (int i = 0; i <= difficulty; i++)
     407             :     {
     408           0 :         xPos = dataNumber["priority-card-offset"].asFloat() * WINDOW_LENGTH * i + dataNumber["priority-card-first-offset"].asFloat() * WINDOW_LENGTH;
     409           0 :         yPos = priorityCards[i].texture->getSprite().getPosition().y;
     410           0 :         priorityCards[i].texture->getSprite().setPosition(xPos, yPos);
     411           0 :         priorityCards[i].movePriorityCardElements(dataNumber);
     412             :     }
     413           0 : }
     414             : 
     415             : /*!
     416             :  * @brief Detect when we click on a priority card or on the play button on priorityCard and make the action associated
     417             :  * @param cursorRect emplacement of the mouse
     418             :  * Example to use the winner window in this function:
     419             :  * setWinnerWindow("Lasso", "1. Tech-Wheel level >=24 \n2. More than 15 control pawns \n3. You are the best");
     420             :  */
     421           0 : bool GameWindow::priorityCardClickAction(sf::Vector2i clickPosition)
     422             : {
     423           0 :     std::string questionString;
     424           0 :     std::string nbOfBoxesOnPriorityCard;
     425             :     int newNumberOfBoxes;
     426             : 
     427           0 :     sf::FloatRect spriteArrowMoreBoxes = validateBoxesWindow->arrowMoreTexture->getSprite().getGlobalBounds();
     428           0 :     sf::FloatRect spriteArrowLessBoxes = validateBoxesWindow->arrowLessTexture->getSprite().getGlobalBounds();
     429           0 :     sf::FloatRect spriteValidateBoxesButton = validateBoxesWindow->doneTexture->getSprite().getGlobalBounds();
     430             : 
     431             :     // If we click on the done button to accept the number of boxes to play
     432           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, spriteValidateBoxesButton) && validateBoxesWindow->isWindowActive)
     433             :     {
     434           0 :         validateBoxesWindow->isWindowActive = false;
     435           0 :         moveToRightPriorityCards(validateBoxesWindow->priorityCardPlayed);
     436           0 :         newNumberOfBoxes = validateBoxesWindow->nbOfBoxesMax - validateBoxesWindow->nbOfBoxesChosen;
     437           0 :         validateBoxesWindow->nbOfBoxesMax = newNumberOfBoxes;
     438           0 :         priorityCards[0].nbOfBoxesText->setString(std::to_string(newNumberOfBoxes) + " x");
     439             : 
     440           0 :         gameEnginePtr->handlePriorityCardPlay(
     441           0 :             validateBoxesWindow->priorityCardPlayedType,
     442           0 :             validateBoxesWindow->priorityCardPlayed,
     443           0 :             validateBoxesWindow->nbOfBoxesChosen);
     444             :             
     445           0 :             return true;
     446             :     }
     447             : 
     448             :     // if we click on the little arrow to add boxes
     449           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, spriteArrowMoreBoxes) &&
     450           0 :         validateBoxesWindow->isWindowActive &&
     451           0 :         validateBoxesWindow->nbOfBoxesChosen < validateBoxesWindow->nbOfBoxesMax)
     452             :     {
     453           0 :         validateBoxesWindow->nbOfBoxesChosen++;
     454           0 :         validateBoxesWindow->chooseNumberOfBoxesButton->buttonText->setString(std::to_string(validateBoxesWindow->nbOfBoxesChosen)); // sent by the server
     455           0 :         return true;
     456             :     }
     457             : 
     458             :     // if we click on the little arrow to delete boxes
     459           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, spriteArrowLessBoxes) &&
     460           0 :         validateBoxesWindow->isWindowActive &&
     461           0 :         validateBoxesWindow->nbOfBoxesChosen > 0)
     462             :     {
     463           0 :         validateBoxesWindow->nbOfBoxesChosen--;
     464           0 :         validateBoxesWindow->chooseNumberOfBoxesButton->buttonText->setString(std::to_string(validateBoxesWindow->nbOfBoxesChosen)); // sent by the server
     465           0 :         return true;
     466             :     }
     467             : 
     468           0 :     for (auto &priorityCard : priorityCards)
     469             :     {
     470           0 :         sf::FloatRect spriteCards = priorityCard.texture->getSprite().getGlobalBounds();
     471           0 :         sf::FloatRect spriteValidateButton = priorityCard.validateButton->buttonRect->getGlobalBounds();
     472             : 
     473             :         // if we click on the play button on priorityCards
     474           0 :         if (gameEnginePtr->intersectPointRect(clickPosition, spriteValidateButton) && priorityCard.isUp)
     475             :         {
     476           0 :             validateBoxesWindow->isWindowActive = true;
     477           0 :             validateBoxesWindow->priorityCardPlayed = priorityCard.difficulty;
     478           0 :             validateBoxesWindow->priorityCardPlayedType = priorityCard.type;
     479             : 
     480           0 :             nbOfBoxesOnPriorityCard = priorityCard.nbOfBoxesText->getString().substring(0, 1);
     481           0 :             validateBoxesWindow->nbOfBoxesChosen = std::stoi(nbOfBoxesOnPriorityCard); // sent by the server
     482           0 :             validateBoxesWindow->nbOfBoxesMax = std::stoi(nbOfBoxesOnPriorityCard);    // sent by the server
     483             : 
     484           0 :             validateBoxesWindow->chooseNumberOfBoxesButton->buttonText->setString(nbOfBoxesOnPriorityCard); // sent by the server
     485           0 :             questionString = "You have " + nbOfBoxesOnPriorityCard + " boxes \nHow many boxes do you want to play?";
     486           0 :             validateBoxesWindow->title->setString(questionString);
     487           0 :             return true;
     488             :         }
     489             : 
     490             :         // if we click on a priorityCard card
     491           0 :         if (gameEnginePtr->intersectPointRect(clickPosition, spriteCards))
     492             :         {
     493           0 :             priorityCard.moveUpPriorityCard();
     494           0 :             return true;
     495             :         }
     496             :     }
     497             : 
     498           0 :     return false;
     499           0 : }
     500             : 
     501             : /*!
     502             :  * @brief Function that deteck where the user click and what to send to the engine
     503             :  * @param clickPosition is the position on the cursor when the user click
     504             :  * @brief Dectect click and actions to do after
     505             :  */
     506           0 : bool GameWindow::clickAction(sf::Event &event, sf::Vector2i clickPosition, std::shared_ptr<bool> moveMode)
     507             : {
     508           0 :     if (!*moveMode)
     509             :     {
     510           0 :         if (priorityCardClickAction(clickPosition))
     511             :         {
     512           0 :             return false;
     513             :         }
     514             : 
     515           0 :         if (onHexagonClick(clickPosition))
     516             :         {
     517           0 :             return false;
     518             :         }
     519             :     }
     520             : 
     521           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, endOfRoundButton->buttonRect->getGlobalBounds()))
     522             :     {
     523           0 :         gameEnginePtr->handleEndTurnButton();
     524           0 :         return false;
     525             :     }
     526             : 
     527             :     // Check if the click position is inside the move map button
     528           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, hudTextureToDisplay[INDEX_MAP_BUTTON].getSprite().getGlobalBounds()))
     529             :     {
     530           0 :         changeMouseCursor(event, moveMode);
     531           0 :         return false;
     532             :     }
     533             : 
     534             :     // Check if the click position is inside the chat button
     535           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, hudTextureToDisplay[INDEX_CHAT_BUTTON].getSprite().getGlobalBounds()))
     536             :     {
     537           0 :         isChatOpen = !isChatOpen;
     538           0 :         return false;
     539             :     }
     540             : 
     541             :     // Check if the click position is inside the chat button
     542           0 :     if (gameEnginePtr->intersectPointRect(clickPosition, hudTextureToDisplay[INDEX_QUIT_BUTTON].getSprite().getGlobalBounds()))
     543             :     {
     544           0 :         return true;
     545             :     }
     546           0 :     return false;
     547             : }
     548             : 
     549           0 : void GameWindow::rotateTechWheel(int newLevel)
     550             : {
     551           0 :     int newRotation = techWheelRotation[newLevel];
     552           0 :     hudTextureToDisplay[ARROW_INDEX].getSprite(0).setRotation(newRotation);
     553           0 : }
     554             : 
     555             : /*!
     556             :  * @brief Display text on the cards
     557             :  * @param cards pointer to the card you want to setUp the text
     558             :  * @param title text to be display on the top of the card
     559             :  * @param body text to be display on body of the card, float
     560             :  * @param titleFont Font that will be used for the titile of the card
     561             :  * @param bodyFont Font that will be used for the body of the card
     562             :  * @param titleTextSizeProportion Proportion of the title
     563             :  * @param bodyTextSizeProportion Proportion of the body
     564             :  */
     565           0 : void GameWindow::setUpText(
     566             :     GraphicCard &card,
     567             :     std::string title,
     568             :     std::string body,
     569             :     sf::Font &titleFont,
     570             :     sf::Font &bodyFont,
     571             :     const Json::Value &dataNumber,
     572             :     float titleTextProportion,
     573             :     float bodyTextProportion)
     574             : {
     575           0 :     int titleTextSize = titleTextProportion * WINDOW_LENGTH;
     576           0 :     int bodyTextSize = bodyTextProportion * WINDOW_LENGTH;
     577             : 
     578             :     // display the title on the card
     579           0 :     card.title = std::make_unique<sf::Text>(title, titleFont, titleTextSize);
     580           0 :     card.title->setStyle(sf::Text::Bold);
     581           0 :     card.title->setFillColor(TEXT_COLOR);
     582           0 :     auto titleSize = card.title->getLocalBounds();
     583           0 :     int xTitleOffset = (card.texture->getWidth() - titleSize.width) / 2;
     584           0 :     int xTitlePosition = card.texture->getSprite().getPosition().x + xTitleOffset;
     585           0 :     int yTitlePosition = card.texture->getSprite().getPosition().y;
     586           0 :     card.title->setPosition(xTitlePosition, yTitlePosition);
     587             : 
     588             :     // display the body on the card
     589           0 :     card.body = std::make_unique<sf::Text>(body, bodyFont, bodyTextSize);
     590             : 
     591             :     // to have the text on several lines without exceeding the card
     592           0 :     int countEndLine = 1;
     593           0 :     while (card.body->getLocalBounds().width > card.texture->getWidth() - CARD_BORDER) // 18 to not touch the black border
     594             :     {
     595             : 
     596           0 :         for (int i = countEndLine * NBR_CHAR_MAX_PER_LIGNE; i > 0; i--)
     597             :         {
     598           0 :             if ((char)body[i] == ' ')
     599             :             {
     600           0 :                 body.replace(i, 1, "\n");
     601           0 :                 countEndLine++;
     602           0 :                 break;
     603             :             }
     604             :         }
     605           0 :         card.body->setString(body);
     606             :     }
     607             : 
     608           0 :     card.body->setFillColor(TEXT_COLOR);
     609           0 :     card.body->setLineSpacing(dataNumber["body-line-space"].asFloat());
     610           0 :     int xBodyOffset = dataNumber["body-x-proportion"].asFloat() * WINDOW_LENGTH;
     611           0 :     int yBodyOffset = dataNumber["body-y-proportion"].asFloat() * WINDOW_WIDTH;
     612           0 :     int xBodyPosition = card.texture->getSprite().getPosition().x + xBodyOffset;
     613           0 :     int yBodyPosition = card.texture->getSprite().getPosition().y + yBodyOffset;
     614           0 :     card.body->setPosition(xBodyPosition, yBodyPosition);
     615           0 : }
     616             : 
     617           0 : bool GameWindow::onHexagonClick(sf::Vector2i clickPosition)
     618             : {
     619           0 :     bool isClickable = false;
     620           0 :     std::array<int, 2> hexagonOnClick = {0, 0};
     621           0 :     int minimumDistance = WINDOW_LENGTH;
     622             : 
     623           0 :     for (auto &mapTexture : mapTextureToDisplay)
     624             :     {
     625           0 :         for (unsigned j = 0; j < mapTexture.getSize(); j++)
     626             :         {
     627           0 :             if (validateBoxesWindow->isWindowActive || !gameEnginePtr->intersectPointRect(clickPosition, mapTexture.getSprite(j).getGlobalBounds()))
     628             :             {
     629           0 :                 continue;
     630             :             }
     631           0 :             isClickable = true;
     632             : 
     633           0 :             int x = mapTexture.getSprite(j).getGlobalBounds().left;
     634           0 :             int y = mapTexture.getSprite(j).getGlobalBounds().top;
     635           0 :             int width = mapTexture.getSprite(j).getGlobalBounds().width;
     636           0 :             int height = mapTexture.getSprite(j).getGlobalBounds().height;
     637             : 
     638           0 :             int distance = sqrt(pow(x + width / 2 - clickPosition.x, 2) +
     639           0 :                                 pow(y + height / 2 - clickPosition.y, 2));
     640             : 
     641           0 :             if (distance < minimumDistance)
     642             :             {
     643             : 
     644           0 :                 minimumDistance = distance;
     645           0 :                 hexagonOnClick[1] = (int)((y - firstHexagonPosition[1])) / (int)((height * 3 / 4));
     646           0 :                 hexagonOnClick[0] = (int)((x - firstHexagonPosition[0])) / (int)((width - 1));
     647             :             }
     648             :         }
     649             :     }
     650             : 
     651           0 :     if (isClickable)
     652             :     {
     653           0 :         gameEnginePtr->handleInformation(hexagonOnClick[0], hexagonOnClick[1]);
     654           0 :         return true;
     655             :     }
     656           0 :     return false;
     657             : }
     658             : 
     659             : /*!
     660             :  * @brief Load all the textures of the map
     661             :  */
     662           0 : void GameWindow::loadMapTexture()
     663             : {
     664           0 :     std::string hexagonImgPath = RESOURCES_PATH "/map/field/field-";
     665             :     std::array<std::string, 12> mapField = {"water", "grassland", "hill", "forest", "desert", "mountain",
     666             :                                             "wonder-everest", "wonder-galapagos", "wonder-kilimanjaro",
     667           0 :                                             "wonder-messa", "wonder-pantanal", "wonder-volcanic"};
     668             : 
     669           0 :     for (unsigned i{0}; i < mapField.size(); i++)
     670             :     {
     671           0 :         std::string mapElementPath = hexagonImgPath + mapField.at(i) + ".png";
     672           0 :         mapTextureToDisplay.emplace_back(mapElementPath);
     673           0 :     }
     674             : 
     675           0 :     for (unsigned i = 0; i < mapShared->getMapHeight(); i++)
     676             :     {
     677           0 :         for (unsigned j = 0; j < mapShared->getMapWidth(); j++)
     678             :         {
     679           0 :             int indexSprite = mapTextureToDisplay.at((int)(*mapShared)(j, i)->getFieldLevel()).getSize();
     680           0 :             mapTextureToDisplay.at((int)(*mapShared)(j, i)->getFieldLevel()).addSprite();
     681           0 :             mapTextureToDisplay.at((int)(*mapShared)(j, i)->getFieldLevel())
     682           0 :                 .setSpritePosition(indexSprite, j, i, MAP_X_OFFSET, MAP_Y_OFFSET, {0, 0});
     683             :         }
     684             :     }
     685           0 : }
     686             : 
     687             : /*!
     688             :  * @brief Load all the textures of the elements
     689             :  */
     690           0 : void GameWindow::loadElementTexture()
     691             : {
     692           0 :     std::string folder_path = RESOURCES_PATH "/map/element/";
     693           0 :     std::vector<std::string> png_files;
     694           0 :     DIR *dir = opendir(folder_path.c_str());
     695             : 
     696             :     struct dirent *entry;
     697           0 :     while ((entry = readdir(dir)) != nullptr)
     698             :     {
     699             : 
     700           0 :         if (entry->d_name[0] == '.')
     701             :         {
     702           0 :             continue;
     703             :         }
     704             : 
     705           0 :         std::string filename = entry->d_name;
     706           0 :         if (filename.size() >= 4 && filename.substr(filename.size() - 4) == ".png")
     707             :         {
     708           0 :             png_files.push_back(filename);
     709             :         }
     710           0 :     }
     711             : 
     712           0 :     closedir(dir);
     713             : 
     714             :     // Affiche les noms de fichiers trouvés
     715           0 :     for (const std::string &filename : png_files)
     716             :     {
     717           0 :         std::string path = RESOURCES_PATH ELEMENT_PATH + filename;
     718           0 :         elementTextureToDisplay[path] = std::make_unique<TextureDisplayer>(path);
     719           0 :     }
     720           0 : }
     721             : 
     722             : /*!
     723             :  * @brief Update all the textures of the map
     724             :  */
     725           0 : void GameWindow::updateElementTexture()
     726             : {
     727           0 :     std::lock_guard<std::mutex> lock(updatePlayerMutex);
     728           0 :     for (auto &kv : elementTextureToDisplay)
     729             :     {
     730           0 :         kv.second->clearSprites();
     731             :     }
     732             : 
     733           0 :     for (unsigned i = 0; i < mapShared->getMapHeight(); i++)
     734             :     {
     735           0 :         for (unsigned j = 0; j < mapShared->getMapWidth(); j++)
     736             :         {
     737           0 :             selectElementToDisplay(j, i);
     738             :         }
     739             :     }
     740           0 : }
     741             : 
     742           0 : void GameWindow::selectElementToDisplay(int x, int y)
     743             : {
     744           0 :     const Json::Value &elementData = openJsonFile("/map/elementPath.json");
     745           0 :     const Json::Value &resourceData = openJsonFile("/map/resourcePath.json");
     746           0 :     const Json::Value &stateCityData = openJsonFile("/map/stateCityPath.json");
     747             : 
     748           0 :     std::array<int, 2> hexSize = {mapTextureToDisplay.at(0).getWidth(), mapTextureToDisplay.at(0).getHeight()};
     749             : 
     750           0 :     for (unsigned k = 0; k < (*mapShared)(x, y)->getElements().size(); k++)
     751             :     {
     752           0 :         std::shared_ptr<variantElement> variant = (*mapShared)(x, y)->getElements()[k];
     753             : 
     754             :         int index;
     755           0 :         std::string path;
     756             : 
     757           0 :         std::visit([&index](auto &&arg)
     758           0 :                    { index = (int)arg.getType(); },
     759           0 :                    *variant);
     760             : 
     761           0 :         if (std::holds_alternative<shared::City>(*variant))
     762             :         {
     763           0 :             shared::City city = std::get<shared::City>(*variant);
     764             : 
     765           0 :             if (city.isStateCity)
     766             :             {
     767           0 :                 path = stateCityData[(int)city.stateCityType]["path"].asString();
     768             :             }
     769             :             else
     770             :             {
     771           0 :                 path = elementData[index]["path"].asString();
     772             : 
     773           0 :                 path = path.substr(0, 20) + std::to_string(getPlayerNumber(city.player)) + (city.isMature ? "-mature" : (city.isCapital ? "-capital" : "-city")) + ".png";
     774             :             }
     775           0 :         }
     776           0 :         else if (std::holds_alternative<shared::ControlPawn>(*variant))
     777             :         {
     778           0 :             shared::ControlPawn pawn = std::get<shared::ControlPawn>(*variant);
     779             : 
     780           0 :             path = elementData[index]["path"].asString();
     781             : 
     782           0 :             path = path.substr(0, 20) + std::to_string(getPlayerNumber(pawn.player)) + (pawn.isReinforced() ? "-reinforced" : "") + ".png";
     783             : 
     784           0 :         }
     785           0 :         else if (std::holds_alternative<shared::Caravan>(*variant))
     786             :         {
     787           0 :             shared::Caravan caravan = std::get<shared::Caravan>(*variant);
     788             : 
     789           0 :             path = elementData[index]["path"].asString();
     790             : 
     791           0 :             path = path.substr(0, 20) + std::to_string(getPlayerNumber(caravan.player)) + path.substr(21);
     792           0 :         }
     793             :         else
     794             :         {
     795           0 :             path = elementData[index]["path"].asString();
     796             :         }
     797             : 
     798           0 :         path = RESOURCES_PATH + path;
     799             : 
     800           0 :         elementTextureToDisplay[path]->addSprite();
     801             : 
     802           0 :         elementTextureToDisplay[path]->setSpritePosition(elementTextureToDisplay[path]->getSize() - 1, x, y, firstHexagonPosition[0], firstHexagonPosition[1], hexSize);
     803           0 :     }
     804             : 
     805           0 :     if ((*mapShared)(x, y)->hexResource != nullptr)
     806             :     {
     807           0 :         shared::Resource resource = *(*mapShared)(x, y)->hexResource;
     808             : 
     809           0 :         int index = (int)resource.getType();
     810             : 
     811           0 :         std::string path = RESOURCES_PATH + resourceData[index]["path"].asString();
     812             : 
     813           0 :         elementTextureToDisplay[path]->addSprite();
     814             : 
     815           0 :         elementTextureToDisplay[path]->setSpritePosition(elementTextureToDisplay[path]->getSize() - 1, x, y, firstHexagonPosition[0], firstHexagonPosition[1], hexSize);
     816           0 :     }
     817           0 : }
     818             : 
     819           0 : int GameWindow::getPlayerNumber(std::string username)
     820             : {
     821           0 :     for (unsigned i = 0; i < whoIsPlayingButtons.size(); i++)
     822             :     {
     823           0 :         std::string buttonText = whoIsPlayingButtons[i].buttonText->getString();
     824           0 :         if (username.compare(buttonText) == 0)
     825             :         {
     826           0 :             return i + 1;
     827             :         }
     828           0 :     }
     829           0 :     return 1;
     830             : }
     831             : 
     832             : /*!
     833             :  * @brief Get position of number of boxes and boxes on priority cards
     834             :  * @param boxXProportion proportion of the box on x axis
     835             :  * @param boxYProportion proportion of the box on y axis
     836             :  * @param priorityCard pointer to the card you want to setUp the text
     837             :  */
     838           0 : sf::Vector2i GameWindow::getBoxesElementsPosition(float boxXProportion, float boxYProportion, GraphicCard &priorityCard)
     839             : {
     840             :     int xBoxPos;
     841             :     int yBoxPos;
     842             :     int xBoxOffset;
     843             :     int yBoxOffset;
     844             : 
     845           0 :     xBoxOffset = boxXProportion * WINDOW_LENGTH;
     846           0 :     yBoxOffset = boxYProportion * WINDOW_WIDTH;
     847             : 
     848           0 :     xBoxPos = priorityCard.texture->getSprite().getPosition().x + xBoxOffset;
     849           0 :     yBoxPos = priorityCard.texture->getSprite().getPosition().y + yBoxOffset;
     850             : 
     851           0 :     return (sf::Vector2i(xBoxPos, yBoxPos));
     852             : }
     853             : 
     854             : /*!
     855             :  * @brief Load all the HUD textures
     856             :  */
     857           0 : void GameWindow::loadHudTexture()
     858             : {
     859             : 
     860           0 :     int rotation = 0;
     861           0 :     int priorityCardIndex = 0;
     862             : 
     863           0 :     const Json::Value &dataNumber = openJsonFile("/hud/data-number.json");
     864             : 
     865           0 :     backgroundTexture = std::make_unique<TextureDisplayer>(RESOURCES_PATH "/hud/background.png");
     866           0 :     backgroundTexture->addSprite();
     867           0 :     float backgroundScale = 1 / (float(backgroundTexture->getWidth()) / float(WINDOW_LENGTH));
     868           0 :     backgroundTexture->setHudSpritePosition(backgroundScale, WINDOW_LENGTH, WINDOW_WIDTH, rotation, priorityCardIndex);
     869             : 
     870           0 :     const Json::Value &data = openJsonFile("/hud/files.json");
     871             : 
     872           0 :     for (unsigned index = 0; index < data.size(); ++index)
     873             :     {
     874           0 :         hudTextureToDisplay.emplace_back(RESOURCES_PATH + data[index]["path"].asString());
     875           0 :         hudTextureToDisplay.back().addSprite();
     876           0 :         float scale = data[index]["scale"].asFloat() / (float(hudTextureToDisplay.back().getWidth()) / float(WINDOW_LENGTH));
     877           0 :         hudTextureToDisplay.back().setImageType((HudTextureType)index);
     878           0 :         hudTextureToDisplay.back().setHudSpritePosition(scale, WINDOW_LENGTH, WINDOW_WIDTH, data[index]["rotation"].asInt(), priorityCardIndex);
     879             :     }
     880             : 
     881             :     // load the priorityCard
     882           0 :     boxTexture = std::make_unique<TextureDisplayer>(RESOURCES_PATH "/hud/box.png");
     883           0 :     std::vector<int> numberOfBoxesPerCard = {2, 4, 2, 1, 0}; // sent by the server
     884           0 :     std::string boxString = "0";
     885             : 
     886           0 :     if (!titleFont.loadFromFile(RESOURCES_PATH "/font/EnchantedLand.otf"))
     887             :     {
     888           0 :         std::cerr << "Font not loaded" << std::endl;
     889             :     }
     890             : 
     891           0 :     if (!bodyFont.loadFromFile(RESOURCES_PATH "/font/MorrisRomanBlack.otf"))
     892             :     {
     893           0 :         std::cerr << "Font not loaded" << std::endl;
     894             :     }
     895             : 
     896           0 :     const Json::Value &priorityData = openJsonFile("/hud/priority-card.json");
     897             : 
     898           0 :     float priorityTitleTextProportion = dataNumber["priority-card-title-proportion"].asFloat();
     899           0 :     float priorityBodyTextProportion = dataNumber["priority-card-body-proportion"].asFloat();
     900             : 
     901           0 :     for (unsigned index = 0; index < priorityData.size(); ++index)
     902             :     {
     903           0 :         priorityCards.emplace_back(
     904           0 :             RESOURCES_PATH + priorityData[index]["path"].asString(),
     905             :             dataNumber,
     906           0 :             WINDOW_LENGTH,
     907           0 :             WINDOW_WIDTH,
     908             :             index,
     909           0 :             bodyFont);
     910             : 
     911             :         // title and body
     912             : 
     913           0 :         setUpText(
     914           0 :             priorityCards.back(),
     915           0 :             priorityData[index]["title"].asString(),
     916           0 :             priorityData[index]["body"][priorityCards.back().level].asString(),
     917           0 :             titleFont,
     918           0 :             bodyFont,
     919             :             dataNumber,
     920             :             priorityTitleTextProportion,
     921             :             priorityBodyTextProportion);
     922             : 
     923             :         // boxes
     924             : 
     925           0 :         boxString = std::to_string(numberOfBoxesPerCard[index]) + " x";
     926             : 
     927           0 :         priorityCards.back().nbOfBoxesText = std::make_unique<sf::Text>(
     928             :             boxString,
     929           0 :             titleFont,
     930           0 :             dataNumber["box-number-text-size"].asInt());
     931             : 
     932           0 :         sf::Vector2i boxNumberPosition = getBoxesElementsPosition(
     933           0 :             dataNumber["box-x-number-offset-proportion"].asFloat(),
     934           0 :             dataNumber["box-y-number-offset-proportion"].asFloat(),
     935           0 :             priorityCards.back());
     936             : 
     937           0 :         priorityCards.back().nbOfBoxesText->setPosition(boxNumberPosition.x, boxNumberPosition.y);
     938             : 
     939           0 :         boxTexture->addSprite();
     940           0 :         sf::Vector2i boxPosition = getBoxesElementsPosition(
     941           0 :             dataNumber["box-x-offset-proportion"].asFloat(),
     942           0 :             dataNumber["box-y-offset-proportion"].asFloat(),
     943           0 :             priorityCards.back());
     944           0 :         boxTexture->getSprite(index).setPosition(boxPosition.x, boxPosition.y);
     945             :     }
     946             : 
     947             :     // actionCard
     948           0 :     const Json::Value &actionCardData = openJsonFile("/hud/action-card.json");
     949           0 :     float actionTitleTextProportion = dataNumber["action-card-title-proportion"].asFloat();
     950           0 :     float actionBodyTextProportion = dataNumber["action-card-body-proportion"].asFloat();
     951             : 
     952           0 :     std::vector<int> actionCardOwned = {1, 3, 7}; // array that will be sent by shared
     953             : 
     954           0 :     for (unsigned index = 0; index < actionCardOwned.size(); ++index)
     955             :     {
     956           0 :         actionCardsToDisplay.emplace_back(
     957           0 :             RESOURCES_PATH + actionCardData[actionCardOwned[index]]["path"].asString(),
     958           0 :             ACTION_CARD_PROPORTION,
     959           0 :             WINDOW_LENGTH,
     960           0 :             WINDOW_WIDTH,
     961           0 :             actionCardOwned[index],
     962             :             index);
     963             : 
     964           0 :         std::string titleCardAction = actionCardData[actionCardOwned[index]]["type"].asString();
     965           0 :         std::string bodyCardAction = actionCardData[actionCardOwned[index]]["body"].asString();
     966             : 
     967           0 :         setUpText(
     968           0 :             actionCardsToDisplay.back(),
     969             :             titleCardAction,
     970             :             bodyCardAction,
     971           0 :             titleFont,
     972           0 :             bodyFont,
     973             :             dataNumber,
     974             :             actionTitleTextProportion,
     975             :             actionBodyTextProportion);
     976           0 :     }
     977             : 
     978             :     // rotation of the techWheel
     979           0 :     const Json::Value &dataRotation = openJsonFile("/hud/tech-wheel-rotation.json");
     980           0 :     for (unsigned index = 0; index < dataRotation.size(); ++index)
     981             :     {
     982           0 :         techWheelRotation[index] = dataRotation[index]["rotation"].asInt();
     983             :     }
     984             : 
     985             :     // text for the user
     986           0 :     std::string textForTheUserString = "";
     987           0 :     textForTheUser = std::make_shared<Button>(sf::Vector2f(dataNumber["text-for-user-size-x"].asFloat(), dataNumber["text-for-user-size-y"].asFloat()),
     988           0 :                                               sf::Vector2f(dataNumber["text-for-user-pos-x"].asFloat(), dataNumber["text-for-user-pos-y"].asFloat()),
     989             :                                               TEXT_FOR_USER_BUTTON_COLOR,
     990           0 :                                               false);
     991           0 :     textForTheUser->setText(dataNumber["text-for-user-string-size"].asInt(),
     992             :                             sf::Vector2f(0, 0),
     993             :                             textForTheUserString,
     994           0 :                             bodyFont,
     995           0 :                             dataNumber["text-for-user-max-char"].asInt());
     996           0 :     textForTheUser->buttonText->setFillColor(TEXT_FOR_USER_COLOR);
     997             : 
     998             :     // end of round button
     999           0 :     endOfRoundButton = std::make_unique<Button>(sf::Vector2f(dataNumber["end-of-round-size-x"].asFloat(), dataNumber["end-of-round-size-y"].asFloat()),
    1000           0 :                                                 sf::Vector2f(dataNumber["text-for-user-pos-x"].asFloat(), dataNumber["end-of-round-pos-y"].asFloat()),
    1001             :                                                 END_OF_TURN_BUTTON_COLOR,
    1002           0 :                                                 false);
    1003           0 :     endOfRoundButton->setText(dataNumber["end-of-round-text-size"].asInt(),
    1004             :                               sf::Vector2f(0, 0),
    1005             :                               "End of turn",
    1006           0 :                               bodyFont);
    1007           0 :     endOfRoundButton->buttonRect->setOutlineThickness(2.0f);
    1008           0 : }
    1009             : 
    1010             : /*!
    1011             :  * @brief Function to modify the text that is specified at a player
    1012             :  * @param text string: text we want to set
    1013             :  */
    1014           0 : void GameWindow::modifyTextForUser(std::string text)
    1015             : {
    1016           0 :     textForTheUser->buttonText->setString(text);
    1017           0 :     textForTheUser->centerText();
    1018           0 : }
    1019             : 
    1020           0 : void GameWindow::addPlayer(std::string username)
    1021             : {
    1022           0 :     for (auto &button : whoIsPlayingButtons)
    1023             :     {
    1024           0 :         std::string buttonText = button.buttonText->getString();
    1025           0 :         if (!username.compare(buttonText))
    1026             :         {
    1027           0 :             return;
    1028             :         }
    1029           0 :     }
    1030             : 
    1031           0 :     whoIsPlayingButtons.emplace_back(
    1032           0 :         sf::Vector2f(75, 90 / 2),
    1033           0 :         sf::Vector2f(0, 0),
    1034           0 :         PLAYER_COLOR[whoIsPlayingButtons.size()],
    1035           0 :         false);
    1036             : 
    1037           0 :     whoIsPlayingButtons.back().setText(18, sf::Vector2f(0, 0), username, titleFont);
    1038             : 
    1039           0 :     for (unsigned i = 0; i < whoIsPlayingButtons.size(); i++)
    1040             :     {
    1041           0 :         whoIsPlayingButtons[i].buttonRect->setPosition(
    1042           0 :             (WINDOW_LENGTH - 75 * whoIsPlayingButtons.size() - 30 * (whoIsPlayingButtons.size() - 1)) / 2 + 105 * i,
    1043             :             0);
    1044           0 :         whoIsPlayingButtons[i].centerText(true);
    1045             :     }
    1046             : }
    1047             : 
    1048             : /*!
    1049             :  * @brief Function that deteck where the user click and what to send to the engine
    1050             :  * @param timeSecond is a boolean used to
    1051             :  */
    1052           0 : long GameWindow::getCurrentTime(bool timeSecond)
    1053             : {
    1054           0 :     if (timeSecond)
    1055             :     {
    1056           0 :         return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    1057             :     }
    1058             :     else
    1059             :     {
    1060           0 :         return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    1061             :     }
    1062             : }
    1063             : 
    1064             : /*!
    1065             :  * @brief Function to set the winnee window at the end of the party
    1066             :  * @param winner string: who is the winner
    1067             :  * @param causes string: why the winner have won
    1068             :  */
    1069           0 : void GameWindow::setWinnerWindow(std::string winner, std::string causes)
    1070             : {
    1071             : 
    1072           0 :     winnerWindow->title->setString(winner + " is the winner !!!");
    1073           0 :     winnerWindow->body->setString(causes);
    1074           0 :     winnerWindow->centerText();
    1075           0 :     winnerWindow->isWindowActive = true;
    1076           0 : }

Generated by: LCOV version 1.14