#include "GamePiecesAppMenu.h" #include "AppMenu.h" #include "GameDistributionAppMenu.h" #include "../PlayerCursor.h" #include #include #include GamePiecesAppMenu::GamePiecesAppMenu(std::shared_ptr menuStack, std::shared_ptr settings, std::shared_ptr renderWindow) : AppMenu(menuStack, settings, renderWindow), playerCursor({1, (unsigned int) this->settings->getSelectedPieces().size() + 1u}) { for (int i = 1; i <= this->settings->getLoadablePiecesSize(); i++) { this->playerCursor.addRow(i + 1, this->settings->getMenu().readPiecesList().getNumberOfPieces(i) + 4); } if (this->settings->getLoadablePiecesSize() < MAXIMUM_PIECES_SIZE) { this->playerCursor.addRow(this->settings->getLoadablePiecesSize() + 2, 1); } } void GamePiecesAppMenu::computeFrame() { this->updateMetaBinds(); this->playerCursor.updatePosition(); if (this->playerCursor.movedDown() && this->playerCursor.getPosition().y == 2) { this->playerCursor.goToPosition({0, 2}); } if (this->enterReleased) { if (this->playerCursor.getPosition().y == 0) { this->menuStack->push(std::make_shared(this->menuStack, this->settings, this->renderWindow)); } if (this->playerCursor.getPosition().y == (this->settings->getLoadablePiecesSize() + 2)) { int newMaxSize = this->settings->getLoadablePiecesSize() + 1; this->settings->loadPieces(newMaxSize); this->playerCursor.removeRow(newMaxSize + 1); this->playerCursor.addRow(newMaxSize + 1, this->settings->getMenu().readPiecesList().getNumberOfPieces(newMaxSize) + 4); this->playerCursor.goToPosition({0u, newMaxSize + 1u}); if (newMaxSize < MAXIMUM_PIECES_SIZE) { this->playerCursor.addRow(newMaxSize + 2, 1); } } else if (this->playerCursor.getPosition().y > 1) { if (this->playerCursor.getPosition().x >= 4) { this->settings->selectPieces(createSinglePieceType(this->playerCursor.getPosition().y - 1), this->playerCursor.getPosition().x - 4); } else { switch (this->playerCursor.getPosition().x) { case 0 : {this->settings->selectPieces(ALL_PIECES, this->playerCursor.getPosition().y - 1); break;} case 1 : {this->settings->selectPieces(CONVEX_PIECES, this->playerCursor.getPosition().y - 1); break;} case 2 : {this->settings->selectPieces(HOLELESS_PIECES, this->playerCursor.getPosition().y - 1); break;} case 3 : {this->settings->selectPieces(OTHER_PIECES, this->playerCursor.getPosition().y - 1); break;} } } this->playerCursor.addPosition(0, 1); } } if (this->escReleased) { if (this->playerCursor.getPosition().y == 1) { if (this->playerCursor.getPosition().x > 0) { this->settings->unselectPieces(this->playerCursor.getPosition().x - 1); this->playerCursor.removePosition(this->playerCursor.getPosition().x - 1, 1); } } else { this->settings->confirmSelectedPieces(); this->menuStack->pop(); } } } void GamePiecesAppMenu::drawFrame() const { this->renderWindow->clear(sf::Color(200, 200, 200)); sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2); text.setFillColor(sf::Color(0, 0, 0)); text.setOutlineColor(sf::Color(255, 255, 255)); this->placeTitle(text, {}, "PIECES SELECT", 5.f, {}); if (this->playerCursor.getPosition().y == 0) { this->placeText(text, this->playerCursor, "PIECES DISTRIBUTION", 5.f, 15.f, sf::Vector2u{0, 0}); this->drawSelectedPiecesRow(25.f); this->drawRow(1, 35.f, true); this->drawRow(2, 45.f, true); } else { this->drawSelectedPiecesRow(15.f); bool drawFromFirstElem = (this->playerCursor.getPosition().y == 1); bool addExtraLine = (this->settings->getLoadablePiecesSize() < MAXIMUM_PIECES_SIZE); int firstElem = std::clamp(((int) this->playerCursor.getPosition().y) - 2, 1, this->settings->getLoadablePiecesSize() - 2 + (addExtraLine ? 1 : 0)); this->drawRow(firstElem, 25.f, drawFromFirstElem); this->drawRow(firstElem + 1, 35.f, drawFromFirstElem); this->drawRow(firstElem + 2, 45.f, drawFromFirstElem); } this->renderWindow->display(); } void GamePiecesAppMenu::drawSelectedPiecesRow(float yPos) const { sf::RectangleShape rect({(float) this->renderWindow->getSize().x, 8.f * this->settings->getWindowSizeMultiplier()}); rect.setPosition({0.f, (yPos - 4.f) * this->settings->getWindowSizeMultiplier()}); rect.setFillColor({240, 240, 240}); this->renderWindow->draw(rect); sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier()); text.setFillColor({0, 0, 0}); int elem = (this->playerCursor.getPosition().y == 1) ? std::max(((int) this->playerCursor.getPosition().x) - 4, 0) : 0; float xProgress = 1.f; bool first = true; while (true) { if ((this->playerCursor.getPosition().y == 1) && (elem == this->playerCursor.getPosition().x)) { this->placeText(text, {}, "|", xProgress, yPos, {}); xProgress += (1.f + (text.getGlobalBounds().size.x / this->settings->getWindowSizeMultiplier())); } if (elem >= this->settings->getSelectedPieces().size()) return; const auto& [pieceType, value] = this->settings->getSelectedPieces().at(elem); int pieceSize = getSizeOfPieces(pieceType); if (pieceSize > 0) { if (!(pieceSize > this->settings->getLoadablePiecesSize())) { const Piece& piece = this->settings->getMenu().readPiecesList().lookAtPiece({pieceSize, value}); int cellSize = (8 * this->settings->getWindowSizeMultiplier()) / (piece.getLength()); sf::FloatRect piecePosition(sf::Vector2f(xProgress, yPos - 4.f) * (float) this->settings->getWindowSizeMultiplier(), sf::Vector2f(8 , 8) * (float) this->settings->getWindowSizeMultiplier()); this->drawPiece(piece, cellSize, piecePosition, false); xProgress += (1.f + 8.f); } else { this->placeText(text, {}, "UNLOADED_" + std::to_string(pieceSize), xProgress, yPos, {}); xProgress += (1.f + (text.getGlobalBounds().size.x / this->settings->getWindowSizeMultiplier())); } } else { if (!(value > this->settings->getLoadablePiecesSize())) { this->placeText(text, {}, ((first) ? "" : " ") + getPiecesTypeName(pieceType) + "_" + std::to_string(value), xProgress, yPos, {}); xProgress += (1.f + (text.getGlobalBounds().size.x / this->settings->getWindowSizeMultiplier())); } else { this->placeText(text, {}, "UNLOADED_" + std::to_string(pieceSize), xProgress, yPos, {}); xProgress += (1.f + (text.getGlobalBounds().size.x / this->settings->getWindowSizeMultiplier())); } } elem++; } } void GamePiecesAppMenu::drawRow(int piecesSize, float yPos, bool drawFromFirstElem) const { if (piecesSize > this->settings->getLoadablePiecesSize()) { sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier() * 2); text.setOutlineThickness(this->settings->getWindowSizeMultiplier() / 2); if (this->playerCursor.getPosition().y == (piecesSize + 1)) { text.setOutlineColor({255, 255, 255}); } else { text.setOutlineColor({0, 0, 0}); } std::string sizeString = "LOAD SIZE " + std::to_string(piecesSize) + "? "; if (piecesSize <= 10) { text.setFillColor({0, 255, 0}); this->placeText(text, {}, sizeString + "(LOW LOAD TIME)", 1.f, yPos, {}); } else if (piecesSize <= 13) { text.setFillColor({255, 255, 0}); this->placeText(text, {}, sizeString + "(MEDIUM LOAD TIME)", 1.f, yPos, {}); } else { text.setFillColor({255, 0, 0}); this->placeText(text, {}, sizeString + "(LONG LOAD TIME)", 1.f, yPos, {}); } } else { int numberOfPieces = this->settings->getMenu().readPiecesList().getNumberOfPieces(piecesSize); int firstElem = (drawFromFirstElem) ? -4 : std::max(((int) this->playerCursor.getPosition().x) - 7, -4); sf::Text text(this->pressStartFont, "", this->settings->getWindowSizeMultiplier()); text.setFillColor({0, 0, 0}); text.setOutlineColor({255, 255, 255}); this->placeText(text, {}, "SIZE " + std::to_string(piecesSize), 1.f, yPos, {}); for (int i = 0; i < 7; i++) { if (i + firstElem >= numberOfPieces) return; if ((i + firstElem) < 0) { switch (i + firstElem) { case -4 : {this->placeText(text, this->playerCursor, "ALL", 10.f + (i * 10.f), yPos, sf::Vector2u{0, piecesSize + 1u}); break;} case -3 : {this->placeText(text, this->playerCursor, "CONVEX", 10.f + (i * 10.f), yPos, sf::Vector2u{1, piecesSize + 1u}); break;} case -2 : {this->placeText(text, this->playerCursor, "HOLELESS", 10.f + (i * 10.f), yPos, sf::Vector2u{2, piecesSize + 1u}); break;} case -1 : {this->placeText(text, this->playerCursor, "OTHER", 10.f + (i * 10.f), yPos, sf::Vector2u{3, piecesSize + 1u}); break;} } } else { const Piece& piece = this->settings->getMenu().readPiecesList().lookAtPiece({piecesSize, firstElem + i}); int cellSize = (8 * this->settings->getWindowSizeMultiplier()) / (piece.getLength()); sf::FloatRect piecePosition(sf::Vector2f(10.f + (i * 10.f), yPos - 4.f) * (float) this->settings->getWindowSizeMultiplier(), sf::Vector2f(8 , 8) * (float) this->settings->getWindowSizeMultiplier()); this->drawPiece(piece, cellSize, piecePosition, this->playerCursor.getPosition() == sf::Vector2u{i + firstElem + 4u, piecesSize + 1u}); } } } } void GamePiecesAppMenu::drawPiece(const Piece& piece, int cellSize, const sf::FloatRect& piecePosition, bool selected) const { sf::RectangleShape rect(piecePosition.size); rect.setPosition(piecePosition.position); rect.setFillColor({180, 180, 180}); if (selected) { rect.setOutlineColor({0, 0, 0}); rect.setOutlineThickness(this->settings->getWindowSizeMultiplier() / 2); } this->renderWindow->draw(rect); sf::RectangleShape cell(sf::Vector2f(cellSize, cellSize)); cell.setFillColor(this->getColorOfBlock(piece.getBlockType(), 0)); for (const Position& cellPosition : piece.getPositions()) { cell.setPosition(sf::Vector2f(piecePosition.position.x + (cellPosition.x * cellSize), piecePosition.position.y + ((piece.getLength() - cellPosition.y - 1) * cellSize) )); this->renderWindow->draw(cell); } }