File indexing completed on 2024-04-14 03:59:50

0001 /*
0002     SPDX-FileCopyrightText: 2012 Christian Krippendorf <Coding@Christian-Krippendorf.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 // own
0008 #include "gameitem.h"
0009 
0010 // Qt
0011 #include <QGraphicsSceneMouseEvent>
0012 #include <QGuiApplication>
0013 #include <QPainter>
0014 #include <QPixmap>
0015 #include <QTimer>
0016 
0017 GameItem::GameItem(bool selected, QGraphicsObject * item)
0018     : QGraphicsObject(item)
0019     , m_dying(false)
0020     , m_shadowWidth(0)
0021     , m_shadowHeight(0)
0022     , m_angle()
0023     , m_selPix(new QPixmap())
0024     , m_unselPix(new QPixmap())
0025     , m_facePix(new QPixmap())
0026 {
0027     // Init POSITION
0028     m_stPos.y = 0;
0029     m_stPos.x = 0;
0030     m_stPos.z = 0;
0031     m_stPos.f = 0;
0032 
0033     setSelected(selected);
0034     setOpacity(1.0);
0035 }
0036 
0037 GameItem::~GameItem()
0038 {
0039     delete m_unselPix;
0040     delete m_selPix;
0041     delete m_facePix;
0042 }
0043 
0044 TileViewAngle GameItem::getAngle() const
0045 {
0046     return m_angle;
0047 }
0048 
0049 void GameItem::setAngle(TileViewAngle angle, QPixmap * selPix, QPixmap * unselPix, int shadowWidth, int shadowHeight)
0050 {
0051     m_angle = angle;
0052 
0053     // Set the new pictures tilted to the new angle.
0054     *m_selPix = *selPix;
0055     *m_unselPix = *unselPix;
0056 
0057     // Set the new shadow width and height.
0058     m_shadowWidth = shadowWidth;
0059     m_shadowHeight = shadowHeight;
0060 
0061     // Update the face offset.
0062     updateFaceOffset();
0063 }
0064 
0065 bool GameItem::isShadow(QPointF const position) const
0066 {
0067     int newPosX = position.x() + getShadowDeltaX();
0068     int newPosY = position.y() + getShadowDeltaY();
0069 
0070     const qreal dpr = qApp->devicePixelRatio();
0071     if ((newPosX < 0 || newPosX > m_selPix->width() / dpr) ||
0072         (newPosY < 0 || newPosY > m_selPix->height() / dpr)) {
0073         return true;
0074     }
0075 
0076     return false;
0077 }
0078 
0079 int GameItem::getShadowDeltaX() const
0080 {
0081     const qreal dpr = qApp->devicePixelRatio();
0082     return ((m_angle == NE || m_angle == SE) ? 1 * m_shadowWidth : -1 * m_shadowWidth) / dpr;
0083 }
0084 
0085 int GameItem::getShadowDeltaY() const
0086 {
0087     const qreal dpr = qApp->devicePixelRatio();
0088     return ((m_angle == NW || m_angle == NE) ? 1 * m_shadowHeight : -1 * m_shadowHeight) / dpr;
0089 }
0090 
0091 void GameItem::prepareForGeometryChange()
0092 {
0093     prepareGeometryChange();
0094 }
0095 
0096 void GameItem::updateFaceOffset()
0097 {
0098     const qreal dpr = qApp->devicePixelRatio();
0099     int horizontalOffset = (m_selPix->width() - m_facePix->width()) / dpr;
0100     int verticalOffset = (m_selPix->height() - m_facePix->height()) / dpr;
0101 
0102     switch (m_angle) {
0103         case NW:
0104             m_faceOffset = QPointF(horizontalOffset, 0);
0105             break;
0106         case NE:
0107             m_faceOffset = QPointF(0, 0);
0108             break;
0109         case SE:
0110             m_faceOffset = QPointF(0, verticalOffset);
0111             break;
0112         case SW:
0113             m_faceOffset = QPointF(horizontalOffset, verticalOffset);
0114             break;
0115     }
0116 }
0117 
0118 void GameItem::paint(QPainter * pPainter, const QStyleOptionGraphicsItem *, QWidget *)
0119 {
0120     if (isSelected()) {
0121         pPainter->drawPixmap(QPointF(0.0, 0.0), *m_selPix);
0122         pPainter->drawPixmap(QPointF(0.0, 0.0) + m_faceOffset, *m_facePix);
0123     } else {
0124         pPainter->drawPixmap(QPointF(0.0, 0.0), *m_unselPix);
0125         pPainter->drawPixmap(QPointF(0.0, 0.0) + m_faceOffset, *m_facePix);
0126     }
0127 }
0128 
0129 void GameItem::setFace(QPixmap * facePix)
0130 {
0131     *m_facePix = *facePix;
0132     updateFaceOffset();
0133 }
0134 
0135 void GameItem::fadeOut()
0136 {
0137     m_dying = true;
0138     setOpacity(opacity() - 0.05);
0139 
0140     if (opacity() <= 0) {
0141         // cancel fade and schedule our destruction
0142         deleteLater();
0143 
0144         return;
0145     }
0146 
0147     // keep fading
0148     QTimer::singleShot(40, this, &GameItem::fadeOut);
0149 }
0150 
0151 void GameItem::fadeIn()
0152 {
0153     if (m_dying) {
0154         return;
0155     }
0156 
0157     setOpacity(opacity() + 0.05);
0158 
0159     if (opacity() == 1.00 || m_dying) {
0160         //cancel fade in
0161         return;
0162     }
0163 
0164     //keep fading
0165     QTimer::singleShot(40, this, &GameItem::fadeIn);
0166 }
0167 
0168 QRectF GameItem::boundingRect() const
0169 {
0170     const qreal dpr = qApp->devicePixelRatio();
0171     return QRectF(QPointF(0.0, 0.0), m_selPix->size() / dpr);
0172 }
0173 
0174 QRectF GameItem::rect() const
0175 {
0176     return boundingRect();
0177 }
0178 
0179 void GameItem::setGridPos(USHORT x, USHORT y, USHORT z)
0180 {
0181     m_stPos.z = z;
0182     m_stPos.y = y;
0183     m_stPos.x = x;
0184 }
0185 
0186 void GameItem::setGridPos(POSITION & stPos)
0187 {
0188     m_stPos = stPos;
0189 }
0190 
0191 POSITION GameItem::getGridPos() const
0192 {
0193     return m_stPos;
0194 }
0195 
0196 void GameItem::setFaceId(USHORT faceId)
0197 {
0198     m_stPos.f = faceId;
0199 }
0200 
0201 USHORT GameItem::getFaceId() const
0202 {
0203     return m_stPos.f;
0204 }
0205 
0206 USHORT GameItem::getGridPosX() const
0207 {
0208     return m_stPos.x;
0209 }
0210 
0211 USHORT GameItem::getGridPosY() const
0212 {
0213     return m_stPos.y;
0214 }
0215 
0216 USHORT GameItem::getGridPosZ() const
0217 {
0218     return m_stPos.z;
0219 }
0220 
0221 #include "moc_gameitem.cpp"