File indexing completed on 2024-05-05 04:02:04

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 John-Paul Stanford <jp@stanwood.org.uk>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 // own
0008 #include "building.h"
0009 
0010 // Qt
0011 #include <QRandomGenerator>
0012 
0013 // KDEGames
0014 #include <KGameRenderedItem>
0015 
0016 // Bomber
0017 #include "board.h"
0018 
0019 /**
0020  * How big is a building in relation to the tiles width.
0021  * 1.0 means it's the same size as the tile.
0022  */
0023 const qreal BUILDING_RELATIVE_WIDTH = 1.0;
0024 /**
0025  * How big is a building in relation to the tiles height.
0026  * 1.0 means it's the same size as the tile.
0027  */
0028 const qreal BUILDING_RELATIVE_HEIGHT = 1.0;
0029 
0030 /** The vertical tile number of the bottom tile in the building */
0031 const unsigned int Building::BUILD_BASE_LOCATION = 16;
0032 
0033 Building::Building(KGameRenderer * renderer, BomberBoard * board, unsigned int position,
0034                    unsigned int height)
0035     : m_height(0)
0036     , m_renderer(renderer)
0037     , m_board(board)
0038     , m_xPos(position)
0039 {
0040     setHeight(height);
0041     setupBuildingTiles();
0042 }
0043 
0044 Building::~Building()
0045 {
0046     for (KGameRenderedItem * tile : std::as_const(m_buildingTiles)) {
0047         m_board->removeItem(tile);
0048     }
0049     qDeleteAll(m_buildingTiles);
0050 }
0051 
0052 void Building::setHeight(unsigned int height)
0053 {
0054     if (height < m_height) {
0055         // Building getting smaller so remove the top
0056         for (unsigned int i = 1; i <= m_height - height; ++i) {
0057             m_buildingTiles.at(m_height - i)->hide();
0058             m_board->removeItem(m_buildingTiles.at(m_height - i));
0059             delete m_buildingTiles.at(m_height - i);
0060             m_buildingTiles.removeAt(m_height - i);
0061         }
0062     }
0063 
0064     m_height = height;
0065     m_boundingRect.moveTo(m_xPos, BUILD_BASE_LOCATION - m_height + 1);
0066     m_boundingRect.setSize(QSizeF(BUILDING_RELATIVE_WIDTH,
0067                                   BUILDING_RELATIVE_HEIGHT * height));
0068 }
0069 
0070 void Building::setupBuildingTiles()
0071 {
0072     //determine number of building styles
0073     static signed int styleCount = -1;
0074     if (styleCount == -1) {
0075         styleCount = 0;
0076         while (m_renderer->spriteExists(QStringLiteral("building_%1_0").arg(styleCount))) {
0077             ++styleCount;
0078         }
0079     }
0080     unsigned int style = QRandomGenerator::global()->bounded(styleCount);
0081     unsigned int maxVarient = m_renderer->frameCount(QStringLiteral("building_%1").arg(style));
0082 
0083     for (unsigned int heightIndex = 0; heightIndex < m_height - 1; ++heightIndex) {
0084         unsigned int varient = QRandomGenerator::global()->bounded(maxVarient);
0085         const QString pixmap = QStringLiteral("building_%1_%2").arg(style).arg(varient);
0086         m_buildingTiles.append(createBuildingTile(pixmap));
0087     }
0088 
0089     const QString pixmap = QStringLiteral("roof_%1_0").arg(style);
0090     m_buildingTiles.append(createBuildingTile(pixmap));
0091     m_boundingRect.moveTo(m_xPos, BUILD_BASE_LOCATION - m_height + 1);
0092     for (KGameRenderedItem * tile : std::as_const(m_buildingTiles)) {
0093         m_board->addItem(tile);
0094     }
0095 }
0096 
0097 KGameRenderedItem * Building::createBuildingTile(const QString & pixmap)
0098 {
0099     auto tile = new KGameRenderedItem(m_renderer, pixmap);
0100     tile->setRenderSize(QSize(32, 64));
0101     return tile;
0102 }
0103 
0104 void Building::show()
0105 {
0106     for (KGameRenderedItem * tile : std::as_const(m_buildingTiles)) {
0107         tile->show();
0108     }
0109 }
0110 
0111 void Building::resize(const QSize & size)
0112 {
0113     QSize tileSize(static_cast<unsigned int>(BUILDING_RELATIVE_WIDTH * size.width()),
0114                    static_cast<unsigned int>(BUILDING_RELATIVE_HEIGHT * size.height()));
0115     for (int i = 0; i < m_buildingTiles.size(); ++i) {
0116         KGameRenderedItem * tile = m_buildingTiles.at(i);
0117         tile->setRenderSize(tileSize);
0118         tile->setPos(m_board->mapPosition(QPointF(m_xPos, BUILD_BASE_LOCATION - i)));
0119     }
0120 }
0121 
0122 QRectF Building::boundingRect() const
0123 {
0124     return m_boundingRect;
0125 }
0126 
0127 void Building::destoryTop()
0128 {
0129     setHeight(m_height - 1);
0130 }
0131 
0132 QPointF Building::position() const
0133 {
0134     return QPointF(m_xPos, BUILD_BASE_LOCATION);
0135 }
0136 
0137 unsigned int Building::height() const
0138 {
0139     return m_height;
0140 }