mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-22 09:35:08 -07:00
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
* Introduce generic IAnimatedItem interface for scene animations GameScene's shared 10ms animation timer previously only knew about CardItems (cardsToAnimate). Generalize it so any scene item can tick on the shared timer instead of owning its own QTimer: - New IAnimatedItem interface with a single animationEvent() tick. - GameScene tracks animated items in a QHash keyed by QObject and auto-unregisters items when they are destroyed, so an item deleted mid-animation (concede, removePlayer, deleteLater) can never leave a dangling pointer in the set. - GameScene::~GameScene disconnects incoming connections before the animation timer is deleted; all timer stops are null-guarded so destruction ordering no longer matters. - AbstractCardItem implements IAnimatedItem with a no-op tick so the existing tap-animation registration path keeps working; CardItem overrides it with the real rotate animation. Took 5 minutes * Add Enable/Disable all animations buttons to settings The animation settings group gets two push buttons that toggle every per-effect animation checkbox at once. The base branch carries the buttons and the shared slots; per-effect toggles (life counter, battlefield, arrow draw) are added by the feature branches on top. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
174 lines
4.9 KiB
C++
174 lines
4.9 KiB
C++
/**
|
|
* @file card_item.h
|
|
* @ingroup GameGraphicsCards
|
|
*/
|
|
//! \todo Document this file.
|
|
|
|
#ifndef CARDITEM_H
|
|
#define CARDITEM_H
|
|
|
|
#include "../../game/board/card_state.h"
|
|
#include "../../game/zones/card_zone_logic.h"
|
|
#include "abstract_card_item.h"
|
|
|
|
#include <libcockatrice/network/server/remote/game/server_card.h>
|
|
|
|
class CardDatabase;
|
|
class CardDragItem;
|
|
class CardZone;
|
|
class ServerInfo_Card;
|
|
class PlayerLogic;
|
|
class QAction;
|
|
class QColor;
|
|
|
|
const int ROTATION_DEGREES_PER_FRAME = 10;
|
|
|
|
class CardItem : public AbstractCardItem
|
|
{
|
|
Q_OBJECT
|
|
private:
|
|
CardState *state;
|
|
|
|
QPoint gridPoint;
|
|
CardDragItem *dragItem;
|
|
QList<CardItem *> attachedCards;
|
|
|
|
void prepareDelete();
|
|
void handleClickedToPlay(bool shiftHeld);
|
|
public slots:
|
|
void deleteLater();
|
|
|
|
public:
|
|
enum
|
|
{
|
|
Type = typeCard
|
|
};
|
|
[[nodiscard]] int type() const override
|
|
{
|
|
return Type;
|
|
}
|
|
explicit CardItem(PlayerLogic *_owner,
|
|
QGraphicsItem *parent = nullptr,
|
|
const CardRef &cardRef = {},
|
|
int _cardid = -1,
|
|
CardZoneLogic *_zone = nullptr);
|
|
|
|
void retranslateUi();
|
|
[[nodiscard]] CardState *getState() const
|
|
{
|
|
return state;
|
|
}
|
|
[[nodiscard]] CardZoneLogic *getZone() const
|
|
{
|
|
return state->getZone();
|
|
}
|
|
void setZone(CardZoneLogic *_zone);
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
|
[[nodiscard]] QPoint getGridPoint() const
|
|
{
|
|
return gridPoint;
|
|
}
|
|
void setGridPoint(const QPoint &_gridPoint)
|
|
{
|
|
gridPoint = _gridPoint;
|
|
}
|
|
[[nodiscard]] QPoint getGridPos() const
|
|
{
|
|
return gridPoint;
|
|
}
|
|
[[nodiscard]] PlayerLogic *getOwner() const
|
|
{
|
|
return owner;
|
|
}
|
|
void setOwner(PlayerLogic *_owner)
|
|
{
|
|
owner = _owner;
|
|
}
|
|
[[nodiscard]] bool getAttacking() const
|
|
{
|
|
return state->getAttacking();
|
|
}
|
|
void setAttacking(bool _attacking);
|
|
[[nodiscard]] const QMap<int, int> &getCounters() const
|
|
{
|
|
return state->getCounters();
|
|
}
|
|
void setCounter(int _id, int _value);
|
|
[[nodiscard]] QString getAnnotation() const
|
|
{
|
|
return state->getAnnotation();
|
|
}
|
|
void setAnnotation(const QString &_annotation);
|
|
[[nodiscard]] bool getDoesntUntap() const
|
|
{
|
|
return state->getDoesntUntap();
|
|
}
|
|
void setDoesntUntap(bool _doesntUntap);
|
|
[[nodiscard]] QString getPT() const
|
|
{
|
|
return state->getPT();
|
|
}
|
|
void setPT(const QString &_pt);
|
|
[[nodiscard]] bool getDestroyOnZoneChange() const
|
|
{
|
|
return state->getDestroyOnZoneChange();
|
|
}
|
|
void setDestroyOnZoneChange(bool _destroy)
|
|
{
|
|
state->setDestroyOnZoneChange(_destroy);
|
|
}
|
|
[[nodiscard]] CardItem *getAttachedTo() const
|
|
{
|
|
return state->getAttachedTo();
|
|
}
|
|
void setAttachedTo(CardItem *_attachedTo);
|
|
void addAttachedCard(CardItem *card)
|
|
{
|
|
attachedCards.append(card);
|
|
}
|
|
void removeAttachedCard(CardItem *card)
|
|
{
|
|
attachedCards.removeOne(card);
|
|
}
|
|
[[nodiscard]] const QList<CardItem *> &getAttachedCards() const
|
|
{
|
|
return attachedCards;
|
|
}
|
|
void resetState(bool keepAnnotations = false);
|
|
void processCardInfo(const ServerInfo_Card &_info);
|
|
|
|
bool animationEvent() override;
|
|
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown);
|
|
void deleteDragItem();
|
|
void drawArrow(const QColor &arrowColor);
|
|
void drawAttachArrow();
|
|
void playCard(bool faceDown);
|
|
|
|
/**
|
|
* @brief Parses a string representing a p/t in order to extract the values from it.
|
|
*
|
|
* If the string contains '/', the string will be split at the '/' and each side will be parsed separately,
|
|
* which means the result list will have two elements.
|
|
*
|
|
* If '/' is not found, then the entire string is parsed together, which means the result list will
|
|
* have a single element.
|
|
*
|
|
* If either side of the split is empty, there will also only be a single element in the result list.
|
|
*
|
|
* This function will attempt to parse each substring as an int first, handling plus and minus prefixes.
|
|
* If successful, it will put the parsed value into the QVariant as an int.
|
|
* If failed, it will just put the substring into the QVariant as a QString.
|
|
*
|
|
* @param pt The p/t string
|
|
* @return A QVariantList that can contain one or two elements, where each QVariant can be either int or QString
|
|
*/
|
|
static QVariantList parsePT(const QString &pt);
|
|
|
|
protected:
|
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
|
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
|
|
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
|
};
|
|
|
|
#endif
|