diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index bd99d08bf..3efaf7c93 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -349,6 +349,8 @@ set(cockatrice_SOURCES src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h src/interface/widgets/utility/compact_push_button.cpp src/interface/widgets/utility/compact_push_button.h + src/game/board/abstract_card_state.cpp + src/game/board/abstract_card_state.h ) add_subdirectory(sounds) diff --git a/cockatrice/src/game/abstract_game.cpp b/cockatrice/src/game/abstract_game.cpp index c20003ece..b542141b4 100644 --- a/cockatrice/src/game/abstract_game.cpp +++ b/cockatrice/src/game/abstract_game.cpp @@ -42,7 +42,7 @@ void AbstractGame::setActiveCard(CardItem *card) activeCard = card; } -CardItem *AbstractGame::getCard(int playerId, const QString &zoneName, int cardId) const +CardState *AbstractGame::getCard(int playerId, const QString &zoneName, int cardId) const { PlayerLogic *player = playerManager->getPlayer(playerId); if (!player) { diff --git a/cockatrice/src/game/abstract_game.h b/cockatrice/src/game/abstract_game.h index 5115ed5ca..109a31ad7 100644 --- a/cockatrice/src/game/abstract_game.h +++ b/cockatrice/src/game/abstract_game.h @@ -7,6 +7,7 @@ #ifndef COCKATRICE_ABSTRACT_GAME_H #define COCKATRICE_ABSTRACT_GAME_H +#include "board/card_state.h" #include "game_event_handler.h" #include "game_meta_info.h" #include "game_state.h" @@ -55,7 +56,7 @@ public: void loadReplay(GameReplay *replay); - CardItem *getCard(int playerId, const QString &zoneName, int cardId) const; + CardState *getCard(int playerId, const QString &zoneName, int cardId) const; void setActiveCard(CardItem *card); CardItem *getActiveCard() const diff --git a/cockatrice/src/game/board/abstract_card_state.cpp b/cockatrice/src/game/board/abstract_card_state.cpp new file mode 100644 index 000000000..3141d3538 --- /dev/null +++ b/cockatrice/src/game/board/abstract_card_state.cpp @@ -0,0 +1,81 @@ +#include "abstract_card_state.h" + +#include "libcockatrice/card/database/card_database_manager.h" + +AbstractCardState::AbstractCardState(PlayerLogic *_owner, const CardRef &_cardRef, int _id) + : owner(_owner), cardRef(_cardRef), id(_id), tapped(false), facedown(false) +{ + refreshCardInfo(); +} + +/** + * Convenience method to get the CardInfo of the exactCard + * @return A const reference to the CardInfo, or an empty CardInfo if card was null + */ +const CardInfo &AbstractCardState::getCardInfo() const +{ + return exactCard.getInfo(); +} + +void AbstractCardState::refreshCardInfo() +{ + exactCard = CardDatabaseManager::query()->getCard(cardRef); + + if (!exactCard && !cardRef.name.isEmpty()) { + CardInfo::UiAttributes attributes = {.tableRow = -1}; + auto info = CardInfo::newInstance(cardRef.name, "", true, {}, {}, {}, {}, attributes); + exactCard = ExactCard(info); + } + + emit cardInfoRefreshed(exactCard); + + emit colorChanged(); +} + +void AbstractCardState::setCardRef(const CardRef &_cardRef) +{ + if (cardRef == _cardRef) { + return; + } + + // TODO emit deleteCardInfoPopup(cardRef.name); + if (exactCard) { + disconnect(exactCard.getCardPtr().data(), nullptr, this, nullptr); + } + cardRef = _cardRef; + + refreshCardInfo(); +} + +void AbstractCardState::setTapped(bool _tapped, bool canAnimate) +{ + if (tapped == _tapped) { + return; + } + + tapped = _tapped; + Q_UNUSED(canAnimate); + // TODO + /*if (SettingsCache::instance().getTapAnimation() && canAnimate) { + static_cast(scene())->registerAnimationItem(this); + } else { + tapAngle = tapped ? 90 : 0; + setTransform(QTransform() + .translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F) + .rotate(tapAngle) + .translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F)); + update(); + }*/ +} + +void AbstractCardState::setFaceDown(bool _facedown) +{ + facedown = _facedown; + emit faceDownChanged(facedown); +} + +void AbstractCardState::setColor(const QString &_color) +{ + color = _color; + emit colorChanged(); +} \ No newline at end of file diff --git a/cockatrice/src/game/board/abstract_card_state.h b/cockatrice/src/game/board/abstract_card_state.h new file mode 100644 index 000000000..6590c6d29 --- /dev/null +++ b/cockatrice/src/game/board/abstract_card_state.h @@ -0,0 +1,86 @@ +#ifndef COCKATRICE_ABSTRACT_CARD_STATE_H +#define COCKATRICE_ABSTRACT_CARD_STATE_H +#include +#include +#include + +class PlayerLogic; + +class AbstractCardState : public QObject +{ + Q_OBJECT + +signals: + void cardChanged(ExactCard *card); + void cardRefChanged(CardRef *cardRef); + void tappedChanged(bool tapped); + void faceDownChanged(bool faceDown); + void cardInfoRefreshed(ExactCard card); + void colorChanged(); + +protected: + PlayerLogic *owner; + CardRef cardRef; + ExactCard exactCard; + int id; + bool tapped; + bool facedown; + QString color; + +public slots: + void refreshCardInfo(); + +public: + AbstractCardState(PlayerLogic *_owner = nullptr, const CardRef &cardRef = {}, int _id = -1); + PlayerLogic *getOwner() const + { + return owner; + } + void setOwner(PlayerLogic *_owner) + { + owner = _owner; + } + ExactCard getCard() const + { + return exactCard; + } + const CardInfo &getCardInfo() const; + int getId() const + { + return id; + } + void setId(int _id) + { + id = _id; + } + QString getName() const + { + return cardRef.name; + } + QString getProviderId() const + { + return cardRef.providerId; + } + void setCardRef(const CardRef &_cardRef); + CardRef getCardRef() const + { + return cardRef; + } + bool getTapped() const + { + return tapped; + } + void setTapped(bool _tapped, bool canAnimate = false); + bool getFaceDown() const + { + return facedown; + } + void setFaceDown(bool _facedown); + QString getColor() const + { + return color; + } + void setColor(const QString &_color); +}; + +#endif // COCKATRICE_ABSTRACT_CARD_STATE_H diff --git a/cockatrice/src/game/board/card_list.cpp b/cockatrice/src/game/board/card_list.cpp index 0080b5ae6..7f27d0b2e 100644 --- a/cockatrice/src/game/board/card_list.cpp +++ b/cockatrice/src/game/board/card_list.cpp @@ -6,7 +6,7 @@ #include #include -CardList::CardList(bool _contentsKnown) : QList(), contentsKnown(_contentsKnown) +CardList::CardList(bool _contentsKnown) : QList(), contentsKnown(_contentsKnown) { } @@ -18,7 +18,7 @@ CardList::CardList(bool _contentsKnown) : QList(), contentsKnown(_co * * @returns A pointer to the CardItem, or a nullptr if not found. */ -CardItem *CardList::findCard(const int cardId) const +CardState *CardList::findCard(const int cardId) const { if (!contentsKnown && !empty()) { return at(0); @@ -46,7 +46,7 @@ void CardList::sortBy(const QList &option) return; } - auto comparator = [&option](CardItem *a, CardItem *b) { + auto comparator = [&option](CardState *a, CardState *b) { for (auto prop : option) { auto extractor = getExtractorFor(prop); QString t1 = extractor(a); @@ -113,24 +113,24 @@ static QString getColorSortString(const CardInfo &c, bool appendAtEnd) /** * @brief returns the function that extracts the given property from the CardItem. */ -std::function CardList::getExtractorFor(SortOption option) +std::function CardList::getExtractorFor(SortOption option) { switch (option) { case NoSort: - return [](CardItem *) { return ""; }; + return [](CardState *) { return ""; }; case SortByMainType: - return [](CardItem *c) { return c->getCardInfo().getMainCardType(); }; + return [](CardState *c) { return c->getCardInfo().getMainCardType(); }; case SortByManaValue: // getCmc returns the int as a string. We pad with 0's so that string comp also works on it - return [](CardItem *c) { return c->getCard() ? c->getCardInfo().getCmc().rightJustified(4, '0') : ""; }; + return [](CardState *c) { return c->getCard() ? c->getCardInfo().getCmc().rightJustified(4, '0') : ""; }; case SortByColorGrouping: - return [](CardItem *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), false) : ""; }; + return [](CardState *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), false) : ""; }; case SortByName: - return [](CardItem *c) { return c->getName(); }; + return [](CardState *c) { return c->getName(); }; case SortByType: - return [](CardItem *c) { return c->getCardInfo().getCardType(); }; + return [](CardState *c) { return c->getCardInfo().getCardType(); }; case SortByManaCost: - return [](CardItem *c) { + return [](CardState *c) { if (!c->getCard()) { return QString(); } @@ -142,18 +142,18 @@ std::function CardList::getExtractorFor(SortOption option) return QString("%1%2").arg(info.getCmc(), 4, QChar('0')).arg(info.getManaCost()); }; case SortByColors: - return [](CardItem *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), true) : ""; }; + return [](CardState *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), true) : ""; }; case SortByPt: // do the same padding trick as above return - [](CardItem *c) { return c->getCard() ? c->getCardInfo().getPowTough().rightJustified(10, '0') : ""; }; + [](CardState *c) { return c->getCard() ? c->getCardInfo().getPowTough().rightJustified(10, '0') : ""; }; case SortBySet: - return [](CardItem *c) { return c->getCardInfo().getSetsNames(); }; + return [](CardState *c) { return c->getCardInfo().getSetsNames(); }; case SortByPrinting: - return [](CardItem *c) { return c->getProviderId(); }; + return [](CardState *c) { return c->getProviderId(); }; } // this line should never be reached qCWarning(CardListLog) << "cardlist.cpp: Could not find extractor for SortOption" << option; - return [](CardItem *) { return ""; }; + return [](CardState *) { return ""; }; } \ No newline at end of file diff --git a/cockatrice/src/game/board/card_list.h b/cockatrice/src/game/board/card_list.h index 85a6848b7..1b4fc8874 100644 --- a/cockatrice/src/game/board/card_list.h +++ b/cockatrice/src/game/board/card_list.h @@ -12,9 +12,8 @@ inline Q_LOGGING_CATEGORY(CardListLog, "card_list"); -class CardItem; - -class CardList : public QList +class CardState; +class CardList : public QList { protected: bool contentsKnown; @@ -41,7 +40,7 @@ public: SortByPrinting }; explicit CardList(bool _contentsKnown); - CardItem *findCard(const int cardId) const; + CardState *findCard(const int cardId) const; bool getContentsKnown() const { return contentsKnown; @@ -49,7 +48,7 @@ public: void sortBy(const QList &options); - static std::function getExtractorFor(SortOption option); + static std::function getExtractorFor(SortOption option); }; #endif diff --git a/cockatrice/src/game/board/card_state.cpp b/cockatrice/src/game/board/card_state.cpp index 4319400d7..eff651a80 100644 --- a/cockatrice/src/game/board/card_state.cpp +++ b/cockatrice/src/game/board/card_state.cpp @@ -1,5 +1,54 @@ #include "card_state.h" +#include "../player/player_logic.h" +#include "../zones/card_zone_logic.h" + +CardState::CardState(PlayerLogic *_owner, const CardRef &cardRef, int _id, CardZoneLogic *_zone) + : AbstractCardState(_owner, cardRef, _id), zone(_zone) +{ + owner->addCard(this); +} + +void CardState::prepareDelete() +{ + while (!attachedCards.isEmpty()) { + attachedCards.first()->setZone(nullptr); // so that it won't try to call reorganizeCards() + attachedCards.first()->setAttachedTo(nullptr); + } + + if (getAttachedTo() != nullptr) { + getAttachedTo()->removeAttachedCard(this); + setAttachedTo(nullptr); + } +} + +void CardState::deleteLater() +{ + prepareDelete(); + QObject::deleteLater(); +} + +void CardState::processCardInfo(const ServerInfo_Card &_info) +{ + clearCounters(); + const int counterListSize = _info.counter_list_size(); + for (int i = 0; i < counterListSize; ++i) { + const ServerInfo_CardCounter &counterInfo = _info.counter_list(i); + insertCounter(counterInfo.id(), counterInfo.value()); + } + + setId(_info.id()); + setCardRef({QString::fromStdString(_info.name()), QString::fromStdString(_info.provider_id())}); + setAttacking(_info.attacking()); + setFaceDown(_info.face_down()); + setPT(QString::fromStdString(_info.pt())); + setAnnotation(QString::fromStdString(_info.annotation())); + setColor(QString::fromStdString(_info.color())); + setTapped(_info.tapped()); + setDestroyOnZoneChange(_info.destroy_on_zone_change()); + setDoesntUntap(_info.doesnt_untap()); +} + void CardState::resetState(bool keepAnnotations) { attacking = false; @@ -11,6 +60,11 @@ void CardState::resetState(bool keepAnnotations) attachedTo = nullptr; } +void CardState::clearAttachedCards() +{ + attachedCards.clear(); +} + void CardState::setZone(CardZoneLogic *_zone) { if (zone == _zone) { @@ -100,7 +154,7 @@ void CardState::setDestroyOnZoneChange(bool _destroyOnZoneChange) emit stateChanged(); } -void CardState::setAttachedTo(CardItem *_attachedTo) +void CardState::setAttachedTo(CardState *_attachedTo) { if (attachedTo == _attachedTo) { return; @@ -108,4 +162,40 @@ void CardState::setAttachedTo(CardItem *_attachedTo) attachedTo = _attachedTo; emit attachedToChanged(_attachedTo); emit stateChanged(); -} \ No newline at end of file +} + +/* +void CardItem::setAttachedTo(CardItem *_attachedTo) +{ + if (state->getAttachedTo() != nullptr) { + state->getAttachedTo()->removeAttachedCard(this); + } + + gridPoint.setX(-1); + state->setAttachedTo(_attachedTo); + if (state->getAttachedTo() != nullptr) { + // If the zone is being torn down, it might already be null by the time a card tries to un-attach all its + // attached cards + if (state->getAttachedTo()->getState()->getZone() == nullptr) { + deleteLater(); + } else { + emit state->getAttachedTo()->getState()->getZone()->cardAdded(this); + state->getAttachedTo()->addAttachedCard(this); + if (state->getZone() != state->getAttachedTo()->getState()->getZone()) { + state->getAttachedTo()->getState()->getZone()->reorganizeCards(); + } + } + } else { + // If the zone is being torn down, it might already be null by the time a card tries to un-attach all its + // attached cards + if (state->getZone() == nullptr) { + deleteLater(); + } else { + emit state->getZone()->cardAdded(this); + } + } + + if (state->getZone() != nullptr) { + state->getZone()->reorganizeCards(); + } +}*/ \ No newline at end of file diff --git a/cockatrice/src/game/board/card_state.h b/cockatrice/src/game/board/card_state.h index 0498b1aa2..1ab6fd181 100644 --- a/cockatrice/src/game/board/card_state.h +++ b/cockatrice/src/game/board/card_state.h @@ -1,12 +1,15 @@ #ifndef COCKATRICE_CARD_STATE_H #define COCKATRICE_CARD_STATE_H +#include "abstract_card_state.h" + #include #include +#include +#include class CardZoneLogic; -class CardItem; -class CardState : public QObject +class CardState : public AbstractCardState { Q_OBJECT @@ -17,8 +20,12 @@ private: QString pt; bool doesntUntap = false; bool destroyOnZoneChange = false; + bool visible = false; - CardItem *attachedTo = nullptr; + QPoint gridPoint; + + CardState *attachedTo = nullptr; + QList attachedCards; CardZoneLogic *zone = nullptr; signals: @@ -30,15 +37,20 @@ signals: void ptChanged(const QString &newPt); void doesntUntapChanged(bool newValue); void destroyOnZoneChangeChanged(bool newValue); - void attachedToChanged(CardItem *newAttachedTo); + void attachedToChanged(CardState *newAttachedTo); void zoneChanged(CardState *changedCard, CardZoneLogic *newZone); + void visibleChanged(bool visible); + +public slots: + void deleteLater(); public: - explicit CardState(QObject *parent, CardZoneLogic *_zone) : QObject(parent), zone(_zone) - { - } + explicit CardState(PlayerLogic *_owner, const CardRef &cardRef = {}, int _id = -1, CardZoneLogic *_zone = nullptr); + void prepareDelete(); + void processCardInfo(const ServerInfo_Card &_info); void resetState(bool keepAnnotations); + void clearAttachedCards(); CardZoneLogic *getZone() const { @@ -92,12 +104,51 @@ public: void setDestroyOnZoneChange(bool _destroyOnZoneChange); - CardItem *getAttachedTo() const + CardState *getAttachedTo() const { return attachedTo; } - void setAttachedTo(CardItem *_attachedTo); + [[nodiscard]] QPoint getGridPoint() const + { + return gridPoint; + } + void setGridPoint(const QPoint &_gridPoint) + { + gridPoint = _gridPoint; + } + [[nodiscard]] QPoint getGridPos() const + { + return gridPoint; + } + + bool getVisible() const + { + return visible; + } + + void setVisible(bool _visible) + { + if (_visible == visible) { + return; + } + visible = _visible; + emit visibleChanged(visible); + } + + void setAttachedTo(CardState *_attachedTo); + void addAttachedCard(CardState *card) + { + attachedCards.append(card); + } + void removeAttachedCard(CardState *card) + { + attachedCards.removeOne(card); + } + [[nodiscard]] const QList &getAttachedCards() const + { + return attachedCards; + } }; #endif // COCKATRICE_CARD_STATE_H diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index fffd23ccf..244abc8b6 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -45,7 +45,7 @@ PlayerActions::PlayerActions(PlayerLogic *_player) connect(moveTopCardTimer, &QTimer::timeout, [this]() { actMoveTopCardToPlay(); }); } -void PlayerActions::playCard(CardItem *card, bool faceDown) +void PlayerActions::playCard(CardState *card, bool faceDown) { if (card == nullptr) { return; @@ -105,13 +105,13 @@ void PlayerActions::playCardToTable(const CardItem *card, bool faceDown) } Command_MoveCard cmd; - cmd.set_start_player_id(card->getZone()->getPlayer()->getPlayerInfo()->getId()); - cmd.set_start_zone(card->getZone()->getName().toStdString()); + cmd.set_start_player_id(card->getState()->getZone()->getPlayer()->getPlayerInfo()->getId()); + cmd.set_start_zone(card->getState()->getZone()->getName().toStdString()); cmd.set_target_player_id(player->getPlayerInfo()->getId()); CardToMove *cardToMove = cmd.mutable_cards_to_move()->add_card(); - cardToMove->set_card_id(card->getId()); + cardToMove->set_card_id(card->getState()->getId()); - ExactCard exactCard = card->getCard(); + ExactCard exactCard = card->getState()->getCard(); if (!exactCard) { return; } @@ -503,7 +503,7 @@ void PlayerActions::moveTopCardsUntil(const QString &expr, MoveTopCardsUntilOpti } } -void PlayerActions::moveOneCardUntil(CardItem *card) +void PlayerActions::moveOneCardUntil(CardState *card) { moveTopCardTimer->stop(); @@ -695,6 +695,8 @@ void PlayerActions::actMoveBottomCardToTop() sendGameCommand(cmd); } +// TODO: None of these should know about CardItems and instead get the correct states passed in. PlayerActions is not +// the place to do this. /** * Selects all cards in the given zone. * @@ -709,11 +711,13 @@ static void selectCardsInZone( return; } - for (auto &cardItem : zone->getCards()) { + Q_UNUSED(filter); + // TODO Fix this + /*for (auto &cardItem : zone->getCards()) { if (cardItem && filter(cardItem)) { cardItem->setSelected(true); } - } + }*/ } void PlayerActions::actSelectAll() @@ -723,7 +727,7 @@ void PlayerActions::actSelectAll() return; } - selectCardsInZone(card->getZone()); + selectCardsInZone(card->getState()->getZone()); } void PlayerActions::actSelectRow() @@ -736,7 +740,7 @@ void PlayerActions::actSelectRow() auto isSameRow = [card](const CardItem *cardItem) { return qAbs(card->scenePos().y() - cardItem->scenePos().y()) < 50; }; - selectCardsInZone(card->getZone(), isSameRow); + selectCardsInZone(card->getState()->getZone(), isSameRow); } void PlayerActions::actSelectColumn() @@ -747,7 +751,7 @@ void PlayerActions::actSelectColumn() } auto isSameColumn = [card](const CardItem *cardItem) { return cardItem->x() == card->x(); }; - selectCardsInZone(card->getZone(), isSameColumn); + selectCardsInZone(card->getState()->getZone(), isSameColumn); } void PlayerActions::actDrawBottomCard() @@ -965,7 +969,7 @@ void PlayerActions::actCreateRelatedCard() auto *action = static_cast(sender()); // If there is a better way of passing a CardRelation through a QAction, please add it here. - auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards(); + auto relatedCards = sourceCard->getState()->getCardInfo().getAllRelatedCards(); CardRelation *cardRelation = relatedCards.at(action->data().toInt()); actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation); @@ -978,7 +982,7 @@ void PlayerActions::actCreateAllRelatedCards() return; } - auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards(); + auto relatedCards = sourceCard->getState()->getCardInfo().getAllRelatedCards(); if (relatedCards.isEmpty()) { return; } @@ -1106,7 +1110,7 @@ bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard, // move card onto table first if attaching from some other zone // we only do this for AttachTo because cross-zone TransformInto is already handled server-side - if (attachType == CardRelationType::AttachTo && sourceCard->getZone()->getName() != ZoneNames::TABLE) { + if (attachType == CardRelationType::AttachTo && sourceCard->getZone()->getLogic()->getName() != ZoneNames::TABLE) { playCardToTable(sourceCard, false); } @@ -1128,8 +1132,8 @@ void PlayerActions::onRelatedCardCreated(const CardItem *sourceCard, const CardR return; } - ExactCard relatedCard = - CardDatabaseManager::query()->getCardFromSameSet(cardRelation->getName(), sourceCard->getCard().getPrinting()); + ExactCard relatedCard = CardDatabaseManager::query()->getCardFromSameSet( + cardRelation->getName(), sourceCard->getState()->getCard().getPrinting()); setLastToken(relatedCard.getCardPtr()); } @@ -1173,8 +1177,8 @@ void PlayerActions::createCard(const CardItem *sourceCard, cmd.set_x(gridPoint.x()); cmd.set_y(gridPoint.y()); - ExactCard relatedCard = - CardDatabaseManager::query()->getCardFromSameSet(cardInfo->getName(), sourceCard->getCard().getPrinting()); + ExactCard relatedCard = CardDatabaseManager::query()->getCardFromSameSet( + cardInfo->getName(), sourceCard->getState()->getCard().getPrinting()); switch (attachType) { case CardRelationType::DoesNotAttach: @@ -1185,18 +1189,19 @@ void PlayerActions::createCard(const CardItem *sourceCard, case CardRelationType::AttachTo: cmd.set_target_zone(ZoneNames::TABLE); // We currently only support creating tokens on the table cmd.set_card_provider_id(relatedCard.getPrinting().getUuid().toStdString()); - cmd.set_target_card_id(sourceCard->getId()); + cmd.set_target_card_id(sourceCard->getState()->getId()); cmd.set_target_mode(Command_CreateToken::ATTACH_TO); break; case CardRelationType::TransformInto: // allow cards to directly transform on stack - cmd.set_zone(sourceCard->getZone()->getName() == ZoneNames::STACK ? ZoneNames::STACK : ZoneNames::TABLE); + cmd.set_zone(sourceCard->getZone()->getLogic()->getName() == ZoneNames::STACK ? ZoneNames::STACK + : ZoneNames::TABLE); // Transform card zone changes are handled server-side - cmd.set_target_zone(sourceCard->getZone()->getName().toStdString()); - cmd.set_target_card_id(sourceCard->getId()); + cmd.set_target_zone(sourceCard->getZone()->getLogic()->getName().toStdString()); + cmd.set_target_card_id(sourceCard->getState()->getId()); cmd.set_target_mode(Command_CreateToken::TRANSFORM_INTO); - cmd.set_card_provider_id(sourceCard->getProviderId().toStdString()); + cmd.set_card_provider_id(sourceCard->getState()->getProviderId().toStdString()); break; } @@ -1218,7 +1223,7 @@ void PlayerActions::actRequestMoveCardXCardsFromTopDialog() emit requestMoveCardXCardsFromTopDialog(defaultNumberTopCardsToPlaceBelow, deckSize); } -void PlayerActions::actMoveCardXCardsFromTop(QList selectedCards, int number) +void PlayerActions::actMoveCardXCardsFromTop(QList selectedCards, int number) { defaultNumberTopCardsToPlaceBelow = number; @@ -1252,7 +1257,7 @@ void PlayerActions::actMoveCardXCardsFromTop(QList selectedCards, in } } -void PlayerActions::actIncPT(QList selectedCards, int deltaP, int deltaT) +void PlayerActions::actIncPT(QList selectedCards, int deltaP, int deltaT) { int playerid = player->getPlayerInfo()->getId(); @@ -1285,7 +1290,7 @@ void PlayerActions::actIncPT(QList selectedCards, int deltaP, int de player->getGame()->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid); } -void PlayerActions::actResetPT(QList selectedCards) +void PlayerActions::actResetPT(QList selectedCards) { int playerid = player->getPlayerInfo()->getId(); QList commandList; @@ -1318,7 +1323,7 @@ void PlayerActions::actResetPT(QList selectedCards) } } -void PlayerActions::actRequestSetPTDialog(QList selectedCards) +void PlayerActions::actRequestSetPTDialog(QList selectedCards) { QString oldPT; @@ -1331,7 +1336,7 @@ void PlayerActions::actRequestSetPTDialog(QList selectedCards) emit requestSetPTDialog(oldPT); } -void PlayerActions::actSetPT(QList selectedCards, const QString &pt) +void PlayerActions::actSetPT(QList selectedCards, const QString &pt) { int playerid = player->getPlayerInfo()->getId(); @@ -1383,47 +1388,47 @@ void PlayerActions::actDrawArrow() } } -void PlayerActions::actIncP(QList selectedCards) +void PlayerActions::actIncP(QList selectedCards) { actIncPT(selectedCards, 1, 0); } -void PlayerActions::actDecP(QList selectedCards) +void PlayerActions::actDecP(QList selectedCards) { actIncPT(selectedCards, -1, 0); } -void PlayerActions::actIncT(QList selectedCards) +void PlayerActions::actIncT(QList selectedCards) { actIncPT(selectedCards, 0, 1); } -void PlayerActions::actDecT(QList selectedCards) +void PlayerActions::actDecT(QList selectedCards) { actIncPT(selectedCards, 0, -1); } -void PlayerActions::actIncPT(QList selectedCards) +void PlayerActions::actIncPT(QList selectedCards) { actIncPT(selectedCards, 1, 1); } -void PlayerActions::actDecPT(QList selectedCards) +void PlayerActions::actDecPT(QList selectedCards) { actIncPT(selectedCards, -1, -1); } -void PlayerActions::actFlowP(QList selectedCards) +void PlayerActions::actFlowP(QList selectedCards) { actIncPT(selectedCards, 1, -1); } -void PlayerActions::actFlowT(QList selectedCards) +void PlayerActions::actFlowT(QList selectedCards) { actIncPT(selectedCards, -1, 1); } -void PlayerActions::actReduceLifeByPower(QList selectedCards) +void PlayerActions::actReduceLifeByPower(QList selectedCards) { // find life counter auto lifeCounter = player->getLifeCounter(); @@ -1458,7 +1463,7 @@ void AnnotationDialog::keyPressEvent(QKeyEvent *event) QInputDialog::keyPressEvent(event); } -void PlayerActions::actRequestSetAnnotationDialog(QList selectedCards) +void PlayerActions::actRequestSetAnnotationDialog(QList selectedCards) { QString oldAnnotation; for (auto card : selectedCards) { @@ -1470,7 +1475,7 @@ void PlayerActions::actRequestSetAnnotationDialog(QList selectedCard emit requestSetAnnotationDialog(oldAnnotation); } -void PlayerActions::actSetAnnotation(QList selectedCards, const QString &annotation) +void PlayerActions::actSetAnnotation(QList selectedCards, const QString &annotation) { QList commandList; for (auto card : selectedCards) { @@ -1494,7 +1499,7 @@ void PlayerActions::actAttach() card->drawAttachArrow(); } -void PlayerActions::actUnattach(QList selectedCards) +void PlayerActions::actUnattach(QList selectedCards) { QList commandList; for (auto card : selectedCards) { @@ -1510,17 +1515,17 @@ void PlayerActions::actUnattach(QList selectedCards) sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actAddCardCounter(QList selectedCards, int counterId) +void PlayerActions::actAddCardCounter(QList selectedCards, int counterId) { offsetCardCounter(selectedCards, counterId, 1); } -void PlayerActions::actRemoveCardCounter(QList selectedCards, int counterId) +void PlayerActions::actRemoveCardCounter(QList selectedCards, int counterId) { offsetCardCounter(selectedCards, counterId, -1); } -void PlayerActions::offsetCardCounter(QList selectedCards, int counterId, int offset) +void PlayerActions::offsetCardCounter(QList selectedCards, int counterId, int offset) { QList commandList; for (auto card : selectedCards) { @@ -1543,7 +1548,7 @@ void PlayerActions::offsetCardCounter(QList selectedCards, int count sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actRequestSetCardCounterDialog(QList selectedCards, int counterId) +void PlayerActions::actRequestSetCardCounterDialog(QList selectedCards, int counterId) { // If a single card is selected, we show the old value in the dialog. Otherwise, we show "x" QString oldValueForDlg = "x"; @@ -1555,7 +1560,7 @@ void PlayerActions::actRequestSetCardCounterDialog(QList selectedCar emit requestSetCardCounterDialog(counterId, oldValueForDlg); } -void PlayerActions::actSetCardCounter(QList selectedCards, int counterId, const QString &counterValue) +void PlayerActions::actSetCardCounter(QList selectedCards, int counterId, const QString &counterValue) { QList commandList; for (auto card : selectedCards) { @@ -1576,11 +1581,11 @@ void PlayerActions::actSetCardCounter(QList selectedCards, int count sendGameCommand(prepareGameCommand(commandList)); } -void PlayerActions::actIncrementAllCardCounters(QList cardsToUpdate) +void PlayerActions::actIncrementAllCardCounters(QList cardsToUpdate) { if (cardsToUpdate.isEmpty()) { // If no cards selected, update all cards on table - cardsToUpdate = static_cast>(player->getTableZone()->getCards()); + cardsToUpdate = static_cast>(player->getTableZone()->getCards()); } QList commandList; @@ -1623,7 +1628,7 @@ static bool isUnwritableRevealZone(CardZoneLogic *zone) return false; } -void PlayerActions::playSelectedCards(QList selectedCards, const bool faceDown) +void PlayerActions::playSelectedCards(QList selectedCards, const bool faceDown) { // CardIds will get shuffled downwards when cards leave the deck. // We need to iterate through the cards in reverse order so cardIds don't get changed out from under us as we play @@ -1638,27 +1643,27 @@ void PlayerActions::playSelectedCards(QList selectedCards, const boo } } -void PlayerActions::actPlay(QList selectedCards) +void PlayerActions::actPlay(QList selectedCards) { playSelectedCards(selectedCards, false); } -void PlayerActions::actPlayFacedown(QList selectedCards) +void PlayerActions::actPlayFacedown(QList selectedCards) { playSelectedCards(selectedCards, true); } -void PlayerActions::actHide(QList selectedCards) +void PlayerActions::actHide(QList selectedCards) { for (const auto &item : selectedCards) { - auto *card = static_cast(item); + auto *card = static_cast(item); if (card && isUnwritableRevealZone(card->getZone())) { card->getZone()->removeCard(card); } } } -void PlayerActions::actReveal(QList selectedCards, QAction *action) +void PlayerActions::actReveal(QList selectedCards, QAction *action) { const int otherPlayerId = action->data().toInt(); @@ -1749,9 +1754,9 @@ void PlayerActions::actRevealRandomGraveyardCard(int revealToPlayerId) sendGameCommand(cmd); } -void PlayerActions::cardMenuAction(QList selectedCards, CardMenuActionType type) +void PlayerActions::cardMenuAction(QList selectedCards, CardMenuActionType type) { - QList cardList = selectedCards; + QList cardList = selectedCards; QList commandList; if (type <= cmClone) { diff --git a/cockatrice/src/game/player/player_actions.h b/cockatrice/src/game/player/player_actions.h index 3f1960892..aba98e666 100644 --- a/cockatrice/src/game/player/player_actions.h +++ b/cockatrice/src/game/player/player_actions.h @@ -50,7 +50,7 @@ public: PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd); PendingCommand *prepareGameCommand(const QList &cmdList); - void moveOneCardUntil(CardItem *card); + void moveOneCardUntil(CardState *card); void stopMoveTopCardsUntil(); [[nodiscard]] bool isMovingCardsUntil() const @@ -92,7 +92,7 @@ signals: public slots: void setLastToken(CardInfoPtr cardInfo); void setLastTokenInfo(CardInfoPtr cardInfo); - void playCard(CardItem *c, bool faceDown); + void playCard(CardState *card, bool faceDown); void playCardToTable(const CardItem *c, bool faceDown); void actUntapAll(); @@ -124,9 +124,9 @@ public slots: void actMulliganMinusOne(); void doMulligan(int number); - void actPlay(QList selectedCards); - void actPlayFacedown(QList selectedCards); - void actHide(QList selectedCards); + void actPlay(QList selectedCards); + void actPlayFacedown(QList selectedCards); + void actHide(QList selectedCards); void actMoveTopCardToPlay(); void actMoveTopCardToPlayFaceDown(); @@ -183,40 +183,40 @@ public slots: void actCreateAllRelatedCards(); void actRequestMoveCardXCardsFromTopDialog(); - void actMoveCardXCardsFromTop(QList selectedCards, int number); - void actRemoveCardCounter(QList selectedCards, int counterId); - void actAddCardCounter(QList selectedCards, int counterId); - void actRequestSetCardCounterDialog(QList selectedCards, int counterId); - void actSetCardCounter(QList selectedCards, int counterId, const QString &counterValue); - void actIncrementAllCardCounters(QList cardsToUpdate); + void actMoveCardXCardsFromTop(QList selectedCards, int number); + void actRemoveCardCounter(QList selectedCards, int counterId); + void actAddCardCounter(QList selectedCards, int counterId); + void actRequestSetCardCounterDialog(QList selectedCards, int counterId); + void actSetCardCounter(QList selectedCards, int counterId, const QString &counterValue); + void actIncrementAllCardCounters(QList cardsToUpdate); void actAttach(); - void actUnattach(QList selectedCards); + void actUnattach(QList selectedCards); void actDrawArrow(); - void actIncPT(QList selectedCards, int deltaP, int deltaT); - void actResetPT(QList selectedCards); - void actRequestSetPTDialog(QList selectedCards); - void actSetPT(QList selectedCards, const QString &pt); - void actIncP(QList selectedCards); - void actDecP(QList selectedCards); - void actIncT(QList selectedCards); - void actDecT(QList selectedCards); - void actIncPT(QList selectedCards); - void actDecPT(QList selectedCards); - void actFlowP(QList selectedCards); - void actFlowT(QList selectedCards); + void actIncPT(QList selectedCards, int deltaP, int deltaT); + void actResetPT(QList selectedCards); + void actRequestSetPTDialog(QList selectedCards); + void actSetPT(QList selectedCards, const QString &pt); + void actIncP(QList selectedCards); + void actDecP(QList selectedCards); + void actIncT(QList selectedCards); + void actDecT(QList selectedCards); + void actIncPT(QList selectedCards); + void actDecPT(QList selectedCards); + void actFlowP(QList selectedCards); + void actFlowT(QList selectedCards); - void actReduceLifeByPower(QList selectedCards); + void actReduceLifeByPower(QList selectedCards); - void actRequestSetAnnotationDialog(QList selectedCards); - void actSetAnnotation(QList selectedCards, const QString &annotation); - void actReveal(QList selectedCards, QAction *action); + void actRequestSetAnnotationDialog(QList selectedCards); + void actSetAnnotation(QList selectedCards, const QString &annotation); + void actReveal(QList selectedCards, QAction *action); void actRevealHand(int revealToPlayerId); void actRevealRandomHandCard(int revealToPlayerId); void actRevealLibrary(int revealToPlayerId); void actSortHand(); - void cardMenuAction(QList selectedCards, CardMenuActionType type); + void cardMenuAction(QList selectedCards, CardMenuActionType type); private: PlayerLogic *player; @@ -242,12 +242,12 @@ private: CardRelationType attach = CardRelationType::DoesNotAttach, bool persistent = false); - void playSelectedCards(QList selectedCards, bool faceDown = false); + void playSelectedCards(QList selectedCards, bool faceDown = false); void cmdSetTopCard(Command_MoveCard &cmd); void cmdSetBottomCard(Command_MoveCard &cmd); - void offsetCardCounter(QList selectedCards, int counterId, int offset); + void offsetCardCounter(QList selectedCards, int counterId, int offset); }; #endif // COCKATRICE_PLAYER_ACTIONS_H diff --git a/cockatrice/src/game/player/player_event_handler.cpp b/cockatrice/src/game/player/player_event_handler.cpp index bc48298f7..965bdd607 100644 --- a/cockatrice/src/game/player/player_event_handler.cpp +++ b/cockatrice/src/game/player/player_event_handler.cpp @@ -137,7 +137,7 @@ void PlayerEventHandler::eventCreateToken(const Event_CreateToken &event) } CardRef cardRef = {QString::fromStdString(event.card_name()), QString::fromStdString(event.card_provider_id())}; - CardItem *card = new CardItem(player, nullptr, cardRef, event.card_id()); + CardState *card = new CardState(player, cardRef, event.card_id(), zone); // use db PT if not provided in event and not face-down if (!QString::fromStdString(event.pt()).isEmpty()) { card->setPT(QString::fromStdString(event.pt())); @@ -175,7 +175,7 @@ void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event, emit logSetTapped(player, nullptr, event.attr_value() == "1"); } } else { - CardItem *card = zone->getCard(event.card_id()); + CardState *card = zone->getCard(event.card_id()); if (!card) { qWarning() << "PlayerEventHandler::eventSetCardAttr: card id=" << event.card_id() << "not found"; return; @@ -185,7 +185,7 @@ void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event, } void PlayerEventHandler::setCardAttrHelper(const GameEventContext &context, - CardItem *card, + CardState *card, CardAttribute attribute, const QString &avalue, bool allCards, @@ -246,7 +246,7 @@ void PlayerEventHandler::eventSetCardCounter(const Event_SetCardCounter &event) return; } - CardItem *card = zone->getCard(event.card_id()); + CardState *card = zone->getCard(event.card_id()); if (!card) { return; } @@ -322,12 +322,12 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv if (x == -1) { x = 0; } - CardItem *card = startZone->takeCard(position, event.card_id(), startZone != targetZone); + CardState *card = startZone->takeCard(position, event.card_id(), startZone != targetZone); if (card == nullptr) { return; } if (startZone != targetZone) { - card->deleteCardInfoPopup(); + // TODO card->deleteCardInfoPopup(); } if (event.has_card_name()) { QString name = QString::fromStdString(event.card_name()); @@ -337,22 +337,22 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv } if (card->getAttachedTo() && (startZone != targetZone)) { - CardItem *parentCard = card->getAttachedTo(); + CardState *parentCard = card->getAttachedTo(); card->setAttachedTo(nullptr); parentCard->getZone()->reorganizeCards(); } - card->deleteDragItem(); + // TODO: card->deleteDragItem(); card->setId(event.new_card_id()); card->setFaceDown(event.face_down()); if (startZone != targetZone) { - card->setBeingPointedAt(false); - card->setHovered(false); + /* TODO card->setBeingPointedAt(false); + card->setHovered(false);*/ - const QList &attachedCards = card->getAttachedCards(); + const QList &attachedCards = card->getAttachedCards(); for (auto attachedCard : attachedCards) { - emit targetZone->cardAdded(attachedCard); + emit targetZone->cardAdded(attachedCard, 0, 0); } if (startZone->getPlayer() != targetZone->getPlayer()) { @@ -385,7 +385,7 @@ void PlayerEventHandler::eventFlipCard(const Event_FlipCard &event) if (!zone) { return; } - CardItem *card = zone->getCard(event.card_id()); + CardState *card = zone->getCard(event.card_id()); if (!card) { return; } @@ -408,12 +408,12 @@ void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event) return; } - CardItem *card = zone->getCard(event.card_id()); + CardState *card = zone->getCard(event.card_id()); if (!card) { return; } - QList attachedCards = card->getAttachedCards(); + QList attachedCards = card->getAttachedCards(); // This list is always empty except for buggy server implementations. for (auto &attachedCard : attachedCards) { attachedCard->setAttachedTo(nullptr); @@ -429,7 +429,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event) const QMap &playerList = player->getGame()->getPlayerManager()->getPlayers(); PlayerLogic *targetPlayer = nullptr; CardZoneLogic *targetZone = nullptr; - CardItem *targetCard = nullptr; + CardState *targetCard = nullptr; if (event.has_target_player_id()) { targetPlayer = playerList.value(event.target_player_id(), 0); if (targetPlayer) { @@ -445,12 +445,12 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event) return; } - CardItem *startCard = startZone->getCard(event.card_id()); + CardState *startCard = startZone->getCard(event.card_id()); if (!startCard) { return; } - CardItem *oldParent = startCard->getAttachedTo(); + CardState *oldParent = startCard->getAttachedTo(); startCard->setAttachedTo(targetCard); @@ -479,7 +479,7 @@ void PlayerEventHandler::eventDrawCards(const Event_DrawCards &event) if (listSize) { for (int i = 0; i < listSize; ++i) { const ServerInfo_Card &cardInfo = event.cards(i); - CardItem *card = _deck->takeCard(0, cardInfo.id()); + CardState *card = _deck->takeCard(0, cardInfo.id()); QString cardName = QString::fromStdString(cardInfo.name()); QString providerId = QString::fromStdString(cardInfo.provider_id()); card->setCardRef({cardName, providerId}); @@ -527,7 +527,7 @@ void PlayerEventHandler::eventRevealCards(const Event_RevealCards &event, EventP for (const auto &card : cardList) { QString cardName = QString::fromStdString(card->name()); QString providerId = QString::fromStdString(card->provider_id()); - CardItem *cardItem = zone->getCard(card->id()); + CardState *cardItem = zone->getCard(card->id()); if (!cardItem) { continue; } diff --git a/cockatrice/src/game/player/player_event_handler.h b/cockatrice/src/game/player/player_event_handler.h index cfd82933f..ce0255f0b 100644 --- a/cockatrice/src/game/player/player_event_handler.h +++ b/cockatrice/src/game/player/player_event_handler.h @@ -13,7 +13,7 @@ #include #include -class CardItem; +class CardState; class CardZoneLogic; class PlayerLogic; class Event_AttachCard; @@ -56,7 +56,7 @@ signals: void logUndoDraw(PlayerLogic *player, QString cardName); void logUndoDrawFailed(PlayerLogic *player); void logMoveCard(PlayerLogic *player, - CardItem *card, + CardState *card, CardZoneLogic *startZone, int oldX, CardZoneLogic *targetZone, @@ -66,11 +66,11 @@ signals: void logAttachCard(PlayerLogic *player, QString cardName, PlayerLogic *targetPlayer, QString targetCardName); void logUnattachCard(PlayerLogic *player, QString cardName); void logSetCardCounter(PlayerLogic *player, QString cardName, int counterId, int value, int oldValue); - void logSetTapped(PlayerLogic *player, CardItem *card, bool tapped); + void logSetTapped(PlayerLogic *player, CardState *card, bool tapped); void logSetCounter(PlayerLogic *player, QString counterName, int value, int oldValue); - void logSetDoesntUntap(PlayerLogic *player, CardItem *card, bool doesntUntap); - void logSetPT(PlayerLogic *player, CardItem *card, QString newPT); - void logSetAnnotation(PlayerLogic *player, CardItem *card, QString newAnnotation); + void logSetDoesntUntap(PlayerLogic *player, CardState *card, bool doesntUntap); + void logSetPT(PlayerLogic *player, CardState *card, QString newPT); + void logSetAnnotation(PlayerLogic *player, CardState *card, QString newAnnotation); void logDumpZone(PlayerLogic *player, CardZoneLogic *zone, int numberCards, bool isReversed = false); void logRevealCards(PlayerLogic *player, CardZoneLogic *zone, @@ -82,8 +82,8 @@ signals: bool isLentToAnotherPlayer = false); void logAlwaysRevealTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal); void logAlwaysLookAtTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal); - void cardZoneChanged(CardItem *card, bool sameZone); - void requestCardMenuUpdate(const CardItem *card); + void cardZoneChanged(CardState *card, bool sameZone); + void requestCardMenuUpdate(const CardState *card); public: PlayerEventHandler(PlayerLogic *player); @@ -119,7 +119,7 @@ private: PlayerLogic *player; void setCardAttrHelper(const GameEventContext &context, - CardItem *card, + CardState *card, CardAttribute attribute, const QString &avalue, bool allCards, diff --git a/cockatrice/src/game/player/player_logic.cpp b/cockatrice/src/game/player/player_logic.cpp index 485e2fc5c..025f57d15 100644 --- a/cockatrice/src/game/player/player_logic.cpp +++ b/cockatrice/src/game/player/player_logic.cpp @@ -168,12 +168,12 @@ void PlayerLogic::processPlayerInfo(const ServerInfo_Player &info) const int cardListSize = zoneInfo.card_list_size(); if (!cardListSize) { for (int j = 0; j < zoneInfo.card_count(); ++j) { - zone->addCard(new CardItem(this), false, -1); + zone->addCard(new CardState(this), false, -1); } } else { for (int j = 0; j < cardListSize; ++j) { const ServerInfo_Card &cardInfo = zoneInfo.card_list(j); - auto *card = new CardItem(this); + auto *card = new CardState(this); card->processCardInfo(cardInfo); zone->addCard(card, false, cardInfo.x(), cardInfo.y()); } @@ -207,8 +207,8 @@ void PlayerLogic::processCardAttachment(const ServerInfo_Player &info) for (int j = 0; j < cardListSize; ++j) { const ServerInfo_Card &cardInfo = zoneInfo.card_list(j); if (cardInfo.has_attach_player_id()) { - CardItem *startCard = zone->getCard(cardInfo.id()); - CardItem *targetCard = + CardState *startCard = zone->getCard(cardInfo.id()); + CardState *targetCard = game->getCard(cardInfo.attach_player_id(), QString::fromStdString(cardInfo.attach_zone()), cardInfo.attach_card_id()); if (!targetCard) { @@ -227,12 +227,12 @@ void PlayerLogic::processCardAttachment(const ServerInfo_Player &info) } } -void PlayerLogic::addCard(CardItem *card) +void PlayerLogic::addCard(CardState *card) { emit newCardAdded(card); } -void PlayerLogic::deleteCard(CardItem *card) +void PlayerLogic::deleteCard(CardState *card) { if (card == nullptr) { return; diff --git a/cockatrice/src/game/player/player_logic.h b/cockatrice/src/game/player/player_logic.h index a89cb6eed..0afa5b198 100644 --- a/cockatrice/src/game/player/player_logic.h +++ b/cockatrice/src/game/player/player_logic.h @@ -41,14 +41,12 @@ class AbstractGame; class ArrowItem; class ArrowTarget; class CardDatabase; -class CardZone; class CommandContainer; class GameCommand; class GameEvent; class PlayerInfo; class PlayerEventHandler; class PlayerActions; -class PlayerMenu; class QAction; class QMenu; class ServerInfo_Arrow; @@ -72,8 +70,8 @@ signals: const QList &cardList, bool withWritePermission); void deckChanged(); - void newCardAdded(AbstractCardItem *card); - void requestCardMenuUpdate(const CardItem *card); + void newCardAdded(AbstractCardState *card); + void requestCardMenuUpdate(const CardState *card); void counterAdded(CounterState *state); void counterRemoved(int counterId); void rearrangeCounters(); @@ -103,8 +101,8 @@ public: void processPlayerInfo(const ServerInfo_Player &info); void processCardAttachment(const ServerInfo_Player &info); - void addCard(CardItem *c); - void deleteCard(CardItem *c); + void addCard(CardState *c); + void deleteCard(CardState *c); bool clearCardsToDelete(); @@ -242,7 +240,7 @@ private: QMap counters; bool dialogSemaphore; - QList cardsToDelete; + QList cardsToDelete; }; class AnnotationDialog : public QInputDialog diff --git a/cockatrice/src/game/zones/card_zone_logic.cpp b/cockatrice/src/game/zones/card_zone_logic.cpp index 7e0585f4e..6a24f842f 100644 --- a/cockatrice/src/game/zones/card_zone_logic.cpp +++ b/cockatrice/src/game/zones/card_zone_logic.cpp @@ -35,7 +35,7 @@ CardZoneLogic::CardZoneLogic(PlayerLogic *_player, &CardZoneLogic::refreshCardInfos); } -void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x, const int y) +void CardZoneLogic::addCard(CardState *card, const bool reorganize, const int x, const int y) { if (!card) { qCWarning(CardZoneLog) << "CardZoneLogic::addCard() card is null; this shouldn't normally happen"; @@ -44,7 +44,8 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x, for (auto *view : views) { if (qobject_cast(view->getLogic())->prepareAddCard(x)) { - auto copy = new CardItem(player, nullptr, card->getCardRef(), card->getId()); + + auto copy = new CardState(player, card->getCardRef(), card->getId()); copy->setFaceDown(card->getFaceDown()); view->getLogic()->addCard(copy, reorganize, x, y); @@ -52,7 +53,7 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x, } card->setZone(this); - emit cardAdded(card); + emit cardAdded(card, x, y); addCardImpl(card, x, y); if (reorganize) { @@ -62,7 +63,7 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x, emit cardCountChanged(); } -CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone) +CardState *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone) { if (position == -1) { // position == -1 means either that the zone is indexed by card id @@ -85,18 +86,20 @@ CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone) qobject_cast(view->getLogic())->removeCard(position, toNewZone); } - CardItem *c = cards.takeAt(position); + CardState *c = cards.takeAt(position); c->setId(cardId); + emit cardRemoved(c, c->getGridPos().x(), c->getGridPos().y()); + emit reorganizeCards(); emit cardCountChanged(); return c; } -CardItem *CardZoneLogic::getCard(int cardId) +CardState *CardZoneLogic::getCard(int cardId) { - CardItem *c = cards.findCard(cardId); + CardState *c = cards.findCard(cardId); if (!c) { qCWarning(CardZoneLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found"; return nullptr; @@ -110,7 +113,7 @@ CardItem *CardZoneLogic::getCard(int cardId) return c; } -void CardZoneLogic::removeCard(CardItem *card) +void CardZoneLogic::removeCard(CardState *card) { if (!card) { qCWarning(CardZoneLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen"; @@ -119,6 +122,8 @@ void CardZoneLogic::removeCard(CardItem *card) cards.removeOne(card); + emit cardRemoved(card, card->getGridPos().x(), card->getGridPos().y()); + emit reorganizeCards(); emit cardCountChanged(); player->deleteCard(card); @@ -159,17 +164,17 @@ void CardZoneLogic::clearContents() const CardList toClear = cards; // Detach and notify attached cards and zones *before* deleting anything. - for (CardItem *card : toClear) { + for (CardState *card : toClear) { // If an incorrectly implemented server doesn't return attached cards to whom they belong before dropping a // player, we have to return them to avoid a crash. - const QList &attachedCards = card->getAttachedCards(); - for (CardItem *attachedCard : attachedCards) { - emit attachedCard->getZone()->cardAdded(attachedCard); + const QList &attachedCards = card->getAttachedCards(); + for (CardState *attachedCard : attachedCards) { + emit attachedCard->getZone()->cardAdded(attachedCard, 0, 0); } } // Now request deletions after all manipulations are done. - for (CardItem *card : toClear) { + for (CardState *card : toClear) { player->deleteCard(card); } diff --git a/cockatrice/src/game/zones/card_zone_logic.h b/cockatrice/src/game/zones/card_zone_logic.h index ae97719a9..ca378a3e6 100644 --- a/cockatrice/src/game/zones/card_zone_logic.h +++ b/cockatrice/src/game/zones/card_zone_logic.h @@ -9,6 +9,7 @@ #include "../../client/translation.h" #include "../board/card_list.h" +#include "../board/card_state.h" #include #include @@ -27,7 +28,8 @@ class CardZoneLogic : public QObject Q_OBJECT signals: - void cardAdded(CardItem *addedCard); + void cardAdded(CardState *addedCard, int x, int y); + void cardRemoved(CardState *removedCard, int x, int y); void cardCountChanged(); void reorganizeCards(); void updateGraphics(); @@ -42,14 +44,14 @@ public: bool _contentsKnown, QObject *parent = nullptr); - void addCard(CardItem *card, bool reorganize, int x, int y = -1); + void addCard(CardState *card, bool reorganize, int x, int y = -1); // getCard() finds a card by id. - CardItem *getCard(int cardId); - void removeCard(CardItem *card); + CardState *getCard(int cardId); + void removeCard(CardState *card); // takeCard() finds a card by position and removes it from the zone and from all of its views. - virtual CardItem *takeCard(int position, int cardId, bool canResize = true); + virtual CardState *takeCard(int position, int cardId, bool canResize = true); - void rawInsertCard(CardItem *card, int index) + void rawInsertCard(CardState *card, int index) { cards.insert(index, card); } @@ -113,7 +115,7 @@ protected: bool isShufflable; bool alwaysRevealTopCard; - virtual void addCardImpl(CardItem *card, int x, int y) = 0; + virtual void addCardImpl(CardState *card, int x, int y) = 0; }; #endif // COCKATRICE_CARD_ZONE_LOGIC_H diff --git a/cockatrice/src/game/zones/hand_zone_logic.cpp b/cockatrice/src/game/zones/hand_zone_logic.cpp index 3bdd15902..b336876ff 100644 --- a/cockatrice/src/game/zones/hand_zone_logic.cpp +++ b/cockatrice/src/game/zones/hand_zone_logic.cpp @@ -13,7 +13,7 @@ HandZoneLogic::HandZoneLogic(PlayerLogic *_player, { } -void HandZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) +void HandZoneLogic::addCardImpl(CardState *card, int x, int /*y*/) { CardZoneAlgorithms::addCardToList(cards, card, x, false); } diff --git a/cockatrice/src/game/zones/hand_zone_logic.h b/cockatrice/src/game/zones/hand_zone_logic.h index 400506248..b04da0e5c 100644 --- a/cockatrice/src/game/zones/hand_zone_logic.h +++ b/cockatrice/src/game/zones/hand_zone_logic.h @@ -20,7 +20,7 @@ public: QObject *parent = nullptr); protected: - void addCardImpl(CardItem *card, int x, int y) override; + void addCardImpl(CardState *card, int x, int y) override; }; #endif // COCKATRICE_HAND_ZONE_LOGIC_H diff --git a/cockatrice/src/game/zones/pile_zone_logic.cpp b/cockatrice/src/game/zones/pile_zone_logic.cpp index 0f374fb84..e9f72f865 100644 --- a/cockatrice/src/game/zones/pile_zone_logic.cpp +++ b/cockatrice/src/game/zones/pile_zone_logic.cpp @@ -12,15 +12,13 @@ PileZoneLogic::PileZoneLogic(PlayerLogic *_player, { } -void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) +void PileZoneLogic::addCardImpl(CardState *card, int x, int /*y*/) { - connect(card, &CardItem::sigPixmapUpdated, this, &PileZoneLogic::callUpdate); // if x is negative set it to add at end if (x < 0 || x >= cards.size()) { x = cards.size(); } cards.insert(x, card); - card->setPos(0, 0); if (!contentsKnown()) { card->setCardRef({}); card->setId(-1); @@ -30,5 +28,5 @@ void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) } } card->setVisible(false); - card->resetState(); + card->resetState(false); } \ No newline at end of file diff --git a/cockatrice/src/game/zones/pile_zone_logic.h b/cockatrice/src/game/zones/pile_zone_logic.h index 522d99b89..daee00cd2 100644 --- a/cockatrice/src/game/zones/pile_zone_logic.h +++ b/cockatrice/src/game/zones/pile_zone_logic.h @@ -13,9 +13,6 @@ class PileZoneLogic : public CardZoneLogic Q_OBJECT -signals: - void callUpdate(); - public: PileZoneLogic(PlayerLogic *_player, const QString &_name, @@ -25,7 +22,7 @@ public: QObject *parent = nullptr); protected: - void addCardImpl(CardItem *card, int x, int y) override; + void addCardImpl(CardState *card, int x, int y) override; }; #endif // COCKATRICE_PILE_ZONE_LOGIC_H diff --git a/cockatrice/src/game/zones/stack_zone_logic.cpp b/cockatrice/src/game/zones/stack_zone_logic.cpp index 341d4b0e4..4dfc315f9 100644 --- a/cockatrice/src/game/zones/stack_zone_logic.cpp +++ b/cockatrice/src/game/zones/stack_zone_logic.cpp @@ -13,7 +13,7 @@ StackZoneLogic::StackZoneLogic(PlayerLogic *_player, { } -void StackZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) +void StackZoneLogic::addCardImpl(CardState *card, int x, int /*y*/) { CardZoneAlgorithms::addCardToList(cards, card, x, true); } diff --git a/cockatrice/src/game/zones/stack_zone_logic.h b/cockatrice/src/game/zones/stack_zone_logic.h index cce4bd0fa..1d3c3375a 100644 --- a/cockatrice/src/game/zones/stack_zone_logic.h +++ b/cockatrice/src/game/zones/stack_zone_logic.h @@ -20,7 +20,7 @@ public: QObject *parent = nullptr); protected: - void addCardImpl(CardItem *card, int x, int y) override; + void addCardImpl(CardState *card, int x, int y) override; }; #endif // COCKATRICE_STACK_ZONE_LOGIC_H diff --git a/cockatrice/src/game/zones/table_zone_logic.cpp b/cockatrice/src/game/zones/table_zone_logic.cpp index a4f033819..1200db4a3 100644 --- a/cockatrice/src/game/zones/table_zone_logic.cpp +++ b/cockatrice/src/game/zones/table_zone_logic.cpp @@ -12,7 +12,7 @@ TableZoneLogic::TableZoneLogic(PlayerLogic *_player, { } -void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _y) +void TableZoneLogic::addCardImpl(CardState *card, int _x, int _y) { cards.append(card); if (!card->getFaceDown() && card->getPT().isEmpty()) { @@ -21,13 +21,14 @@ void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _y) if (card->getCardInfo().getUiAttributes().cipt && card->getCardInfo().getUiAttributes().landscapeOrientation) { card->setDoesntUntap(true); } + card->setGridPoint(QPoint(_x, _y)); card->setVisible(true); } -CardItem *TableZoneLogic::takeCard(int position, int cardId, bool toNewZone) +CardState *TableZoneLogic::takeCard(int position, int cardId, bool toNewZone) { - CardItem *result = CardZoneLogic::takeCard(position, cardId); + CardState *result = CardZoneLogic::takeCard(position, cardId); if (toNewZone) { emit contentSizeChanged(); diff --git a/cockatrice/src/game/zones/table_zone_logic.h b/cockatrice/src/game/zones/table_zone_logic.h index 6d8d64a20..f46bc37ed 100644 --- a/cockatrice/src/game/zones/table_zone_logic.h +++ b/cockatrice/src/game/zones/table_zone_logic.h @@ -24,7 +24,7 @@ public: QObject *parent = nullptr); protected: - void addCardImpl(CardItem *card, int x, int y) override; + void addCardImpl(CardState *card, int x, int y) override; /** * @brief Removes a card from view. @@ -34,7 +34,7 @@ protected: * @param toNewZone Whether the destination of the card is not the same as the starting zone. Defaults to true * @return CardItem that has been removed */ - CardItem *takeCard(int position, int cardId, bool toNewZone = true) override; + CardState *takeCard(int position, int cardId, bool toNewZone = true) override; }; #endif // COCKATRICE_TABLE_ZONE_LOGIC_H diff --git a/cockatrice/src/game/zones/view_zone_logic.cpp b/cockatrice/src/game/zones/view_zone_logic.cpp index 8782a1762..03c37b66a 100644 --- a/cockatrice/src/game/zones/view_zone_logic.cpp +++ b/cockatrice/src/game/zones/view_zone_logic.cpp @@ -68,7 +68,7 @@ bool ZoneViewZoneLogic::prepareAddCard(int x) * Make sure prepareAddCard() was called before calling addCard(). * This method assumes we already checked that the card is being inserted into the visible portion */ -void ZoneViewZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) +void ZoneViewZoneLogic::addCardImpl(CardState *card, int x, int /*y*/) { if (!isReversed) { // if x is negative set it to add at end @@ -137,7 +137,7 @@ void ZoneViewZoneLogic::removeCard(int position, bool toNewZone) return; } - CardItem *card = cards.takeAt(position); + CardState *card = cards.takeAt(position); card->deleteLater(); // The toNewZone check is to prevent the view from auto-closing if the view contains only a single card and that diff --git a/cockatrice/src/game/zones/view_zone_logic.h b/cockatrice/src/game/zones/view_zone_logic.h index 04ed20e45..b7dee7242 100644 --- a/cockatrice/src/game/zones/view_zone_logic.h +++ b/cockatrice/src/game/zones/view_zone_logic.h @@ -65,7 +65,7 @@ public: } protected: - void addCardImpl(CardItem *card, int x, int y) override; + void addCardImpl(CardState *card, int x, int y) override; }; #endif // COCKATRICE_VIEW_ZONE_LOGIC_H diff --git a/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp b/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp index 026efd60d..37bb5403a 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp +++ b/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp @@ -25,7 +25,7 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item, setCursor(Qt::ClosedHandCursor); setZValue(ZValues::DRAG_ITEM); } - if (item->getTapped()) { + if (item->getState()->getTapped()) { setTransform(QTransform() .translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F) .rotate(90) diff --git a/cockatrice/src/game_graphics/board/abstract_card_item.cpp b/cockatrice/src/game_graphics/board/abstract_card_item.cpp index 86b3e27c8..294ca3f31 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_item.cpp +++ b/cockatrice/src/game_graphics/board/abstract_card_item.cpp @@ -13,16 +13,19 @@ #include #include -AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id) - : ArrowTarget(_owner, parent), id(_id), cardRef(cardRef), tapped(false), facedown(false), tapAngle(0), - bgColor(Qt::transparent), isHovered(false), realZValue(0) +AbstractCardItem::AbstractCardItem(AbstractCardState *_state, QGraphicsItem *parent) + : ArrowTarget(_state->getOwner(), parent), cardState(_state), tapAngle(0), bgColor(Qt::transparent), + isHovered(false), realZValue(0) { setCursor(Qt::OpenHandCursor); setFlag(ItemIsSelectable); setCacheMode(DeviceCoordinateCache); + connect(_state, &AbstractCardState::cardInfoRefreshed, this, &AbstractCardItem::onCardInfoRefreshed); + connect(_state, &AbstractCardState::colorChanged, this, &AbstractCardItem::onCardColorChanged); + connect(_state, &AbstractCardState::faceDownChanged, this, [this]() { update(); }); + connect(&SettingsCache::instance(), &SettingsCache::displayCardNamesChanged, this, [this] { update(); }); - refreshCardInfo(); connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) { Q_UNUSED(_roundCardCorners); @@ -34,7 +37,7 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef AbstractCardItem::~AbstractCardItem() { - emit deleteCardInfoPopup(cardRef.name); + // TODO emit deleteCardInfoPopup(cardRef.name); } QRectF AbstractCardItem::boundingRect() const @@ -56,32 +59,6 @@ void AbstractCardItem::pixmapUpdated() emit sigPixmapUpdated(); } -void AbstractCardItem::refreshCardInfo() -{ - exactCard = CardDatabaseManager::query()->getCard(cardRef); - - if (!exactCard && !cardRef.name.isEmpty()) { - CardInfo::UiAttributes attributes = {.tableRow = -1}; - auto info = CardInfo::newInstance(cardRef.name, "", true, {}, {}, {}, {}, attributes); - exactCard = ExactCard(info); - } - if (exactCard) { - connect(exactCard.getCardPtr().data(), &CardInfo::pixmapUpdated, this, &AbstractCardItem::pixmapUpdated); - } - - cacheBgColor(); - update(); -} - -/** - * Convenience method to get the CardInfo of the exactCard - * @return A const reference to the CardInfo, or an empty CardInfo if card was null - */ -const CardInfo &AbstractCardItem::getCardInfo() const -{ - return exactCard.getInfo(); -} - void AbstractCardItem::setRealZValue(qreal _zValue) { realZValue = _zValue; @@ -124,13 +101,13 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS QPixmap translatedPixmap; bool paintImage = true; - if (facedown || cardRef.name.isEmpty()) { + if (getState()->getFaceDown() || getState()->getName().isEmpty()) { // never reveal card color, always paint the card back CardPictureLoader::getCardBackPixmap(translatedPixmap, translatedSize.toSize()); } else { // don't even spend time trying to load the picture if our size is too small if (translatedSize.width() > 10) { - CardPictureLoader::getPixmap(translatedPixmap, exactCard, translatedSize.toSize()); + CardPictureLoader::getPixmap(translatedPixmap, getState()->getCard(), translatedSize.toSize()); if (translatedPixmap.isNull()) { paintImage = false; } @@ -151,21 +128,21 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS painter->drawPath(shape()); } - if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) { + if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || getState()->getFaceDown()) { painter->save(); transformPainter(painter, translatedSize, angle); painter->setPen(Qt::white); painter->setBackground(Qt::black); painter->setBackgroundMode(Qt::OpaqueMode); QString nameStr; - if (facedown) { - nameStr = "# " + QString::number(id); + if (getState()->getFaceDown()) { + nameStr = "# " + QString::number(getState()->getId()); } else { QString prefix = ""; if (SettingsCache::instance().debug().getShowCardId()) { - prefix = "#" + QString::number(id) + " "; + prefix = "#" + QString::number(getState()->getId()) + " "; } - nameStr = prefix + cardRef.name; + nameStr = prefix + getState()->getName(); } painter->drawText(QRectF(3 * scaleFactor, 3 * scaleFactor, translatedSize.width() - 6 * scaleFactor, translatedSize.height() - 6 * scaleFactor), @@ -201,21 +178,6 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * painter->restore(); } -void AbstractCardItem::setCardRef(const CardRef &_cardRef) -{ - if (cardRef == _cardRef) { - return; - } - - emit deleteCardInfoPopup(cardRef.name); - if (exactCard) { - disconnect(exactCard.getCardPtr().data(), nullptr, this, nullptr); - } - cardRef = _cardRef; - - refreshCardInfo(); -} - void AbstractCardItem::setHovered(bool _hovered) { if (isHovered == _hovered) { @@ -239,9 +201,18 @@ void AbstractCardItem::setHovered(bool _hovered) update(); } -void AbstractCardItem::setColor(const QString &_color) +void AbstractCardItem::onCardInfoRefreshed() +{ + if (getState()->getCard()) { + connect(getState()->getCard().getCardPtr().data(), &CardInfo::pixmapUpdated, this, + &AbstractCardItem::pixmapUpdated); + } + + onCardColorChanged(); +} + +void AbstractCardItem::onCardColorChanged() { - color = _color; cacheBgColor(); update(); } @@ -249,10 +220,10 @@ void AbstractCardItem::setColor(const QString &_color) void AbstractCardItem::cacheBgColor() { QChar colorChar; - if (color.isEmpty()) { - colorChar = exactCard.getInfo().getColorChar(); + if (getState()->getColor().isEmpty()) { + colorChar = getState()->getCard().getInfo().getColorChar(); } else { - colorChar = color.at(0); + colorChar = getState()->getColor().at(0); } switch (colorChar.toLower().toLatin1()) { @@ -280,35 +251,10 @@ void AbstractCardItem::cacheBgColor() } } -void AbstractCardItem::setTapped(bool _tapped, bool canAnimate) -{ - if (tapped == _tapped) { - return; - } - - tapped = _tapped; - if (SettingsCache::instance().getTapAnimation() && canAnimate) { - static_cast(scene())->registerAnimationItem(this); - } else { - tapAngle = tapped ? 90 : 0; - setTransform(QTransform() - .translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F) - .rotate(tapAngle) - .translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F)); - update(); - } -} - -void AbstractCardItem::setFaceDown(bool _facedown) -{ - facedown = _facedown; - update(); -} - void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if ((event->modifiers() & Qt::AltModifier) && event->button() == Qt::LeftButton) { - emit cardShiftClicked(cardRef.name); + emit cardShiftClicked(getState()->getName()); } else if ((event->modifiers() & Qt::ControlModifier)) { setSelected(!isSelected()); } else if (!isSelected()) { @@ -318,7 +264,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event) if (event->button() == Qt::LeftButton) { setCursor(Qt::ClosedHandCursor); } else if (event->button() == Qt::MiddleButton) { - emit showCardInfoPopup(event->screenPos(), cardRef); + emit showCardInfoPopup(event->screenPos(), getState()->getCardRef()); } event->accept(); } @@ -326,7 +272,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event) void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::MiddleButton) { - emit deleteCardInfoPopup(cardRef.name); + emit deleteCardInfoPopup(getState()->getName()); } // This function ensures the parent function doesn't mess around with our selection. diff --git a/cockatrice/src/game_graphics/board/abstract_card_item.h b/cockatrice/src/game_graphics/board/abstract_card_item.h index bdb5f7cf1..34005a538 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_item.h +++ b/cockatrice/src/game_graphics/board/abstract_card_item.h @@ -7,6 +7,7 @@ #ifndef ABSTRACTCARDITEM_H #define ABSTRACTCARDITEM_H +#include "../../game/board/abstract_card_state.h" #include "../card_dimensions.h" #include "arrow_target.h" #include "graphics_item_type.h" @@ -20,13 +21,8 @@ class AbstractCardItem : public ArrowTarget { Q_OBJECT protected: - ExactCard exactCard; - int id; - CardRef cardRef; - bool tapped; - bool facedown; + AbstractCardState *cardState; int tapAngle; - QString color; QColor bgColor; private: @@ -35,9 +31,6 @@ private: private slots: void pixmapUpdated(); -public slots: - void refreshCardInfo(); - signals: void hovered(AbstractCardItem *card); void showCardInfoPopup(const QPoint &pos, const CardRef &cardRef); @@ -59,71 +52,33 @@ public: { return Type; } - explicit AbstractCardItem(QGraphicsItem *parent = nullptr, - const CardRef &cardRef = {}, - PlayerLogic *_owner = nullptr, - int _id = -1); + explicit AbstractCardItem(AbstractCardState *_state, QGraphicsItem *parent = nullptr); ~AbstractCardItem() override; QRectF boundingRect() const override; QPainterPath shape() const override; QSizeF getTranslatedSize(QPainter *painter) const; void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; - ExactCard getCard() const - { - return exactCard; - } - const CardInfo &getCardInfo() const; - int getId() const - { - return id; - } - void setId(int _id) - { - id = _id; - } - QString getName() const - { - return cardRef.name; - } - QString getProviderId() const - { - return cardRef.providerId; - } - void setCardRef(const CardRef &_cardRef); - CardRef getCardRef() const - { - return cardRef; - } qreal getRealZValue() const { return realZValue; } void setRealZValue(qreal _zValue); void setHovered(bool _hovered); + void onCardInfoRefreshed(); + void onCardColorChanged(); bool getIsHovered() const { return isHovered; } - QString getColor() const - { - return color; - } - void setColor(const QString &_color); - bool getTapped() const - { - return tapped; - } - void setTapped(bool _tapped, bool canAnimate = false); - bool getFaceDown() const - { - return facedown; - } - void setFaceDown(bool _facedown); void processHoverEvent(); void deleteCardInfoPopup() { - emit deleteCardInfoPopup(cardRef.name); + // emit deleteCardInfoPopup(cardRef.name); + } + AbstractCardState *getState() const + { + return cardState; } protected: diff --git a/cockatrice/src/game_graphics/board/arrow_item.cpp b/cockatrice/src/game_graphics/board/arrow_item.cpp index af6a6bf36..94412e6ba 100644 --- a/cockatrice/src/game_graphics/board/arrow_item.cpp +++ b/cockatrice/src/game_graphics/board/arrow_item.cpp @@ -237,19 +237,19 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) return; } - CardZoneLogic *startZone = startCard->getZone(); + CardZoneLogic *startZone = startCard->getState()->getZone(); Command_CreateArrow cmd; cmd.mutable_arrow_color()->CopyFrom(convertQColorToColor(data->color)); cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId()); cmd.set_start_zone(startZone->getName().toStdString()); - cmd.set_start_card_id(startCard->getId()); + cmd.set_start_card_id(startCard->getState()->getId()); if (auto *targetCard = qgraphicsitem_cast(targetItem)) { - CardZoneLogic *targetZone = targetCard->getZone(); + CardZoneLogic *targetZone = targetCard->getState()->getZone(); cmd.set_target_player_id(targetZone->getPlayer()->getPlayerInfo()->getId()); cmd.set_target_zone(targetZone->getName().toStdString()); - cmd.set_target_card_id(targetCard->getId()); + cmd.set_target_card_id(targetCard->getState()->getId()); } else if (auto *targetPlayer = qgraphicsitem_cast(targetItem)) { cmd.set_target_player_id(targetPlayer->getOwner()->getPlayerInfo()->getId()); } else { @@ -260,11 +260,11 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) // if the card is in hand then we will move the card to stack or table as part of drawing the arrow if (startZone->getName() == ZoneNames::HAND) { startCard->playCard(false); - CardInfoPtr ci = startCard->getCard().getCardPtr(); + CardInfoPtr ci = startCard->getState()->getCard().getCardPtr(); bool playToStack = SettingsCache::instance().getPlayToStack(); if (ci && ((!playToStack && ci->getUiAttributes().tableRow == 3) || (playToStack && ci->getUiAttributes().tableRow != 0 && - startCard->getZone()->getName() != ZoneNames::STACK))) { + startCard->getState()->getZone()->getName() != ZoneNames::STACK))) { cmd.set_start_zone(ZoneNames::STACK); } else { cmd.set_start_zone(playToStack ? ZoneNames::STACK : ZoneNames::TABLE); @@ -373,20 +373,20 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void ArrowAttachItem::attachCards(CardItem *startCard, const CardItem *targetCard) { - if (targetCard->getAttachedTo() || targetCard->getZone()->getName() != ZoneNames::TABLE) { + if (targetCard->getState()->getAttachedTo() || targetCard->getState()->getZone()->getName() != ZoneNames::TABLE) { return; } // move card onto table first if attaching from some other zone - if (startCard->getZone()->getName() != ZoneNames::TABLE) { + if (startCard->getState()->getZone()->getName() != ZoneNames::TABLE) { player->getPlayerActions()->playCardToTable(startCard, false); } Command_AttachCard cmd; cmd.set_start_zone(ZoneNames::TABLE); - cmd.set_card_id(startCard->getId()); - cmd.set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerInfo()->getId()); - cmd.set_target_zone(targetCard->getZone()->getName().toStdString()); - cmd.set_target_card_id(targetCard->getId()); + cmd.set_card_id(startCard->getState()->getId()); + cmd.set_target_player_id(targetCard->getState()->getZone()->getPlayer()->getPlayerInfo()->getId()); + cmd.set_target_zone(targetCard->getState()->getZone()->getName().toStdString()); + cmd.set_target_card_id(targetCard->getState()->getId()); player->getPlayerActions()->sendGameCommand(cmd); } \ No newline at end of file diff --git a/cockatrice/src/game_graphics/board/card_drag_item.cpp b/cockatrice/src/game_graphics/board/card_drag_item.cpp index 49467c5c9..662aae02b 100644 --- a/cockatrice/src/game_graphics/board/card_drag_item.cpp +++ b/cockatrice/src/game_graphics/board/card_drag_item.cpp @@ -119,8 +119,9 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) sc->removeItem(this); QList dragItemList; - CardZoneLogic *startZone = static_cast(item)->getZone(); - if (currentZone && !(static_cast(item)->getAttachedTo() && (startZone == currentZone->getLogic()))) { + CardZoneLogic *startZone = static_cast(item)->getState()->getZone(); + if (currentZone && + !(static_cast(item)->getState()->getAttachedTo() && (startZone == currentZone->getLogic()))) { if (!occupied) { dragItemList.append(this); } @@ -128,7 +129,8 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) for (int i = 0; i < childDrags.size(); i++) { CardDragItem *c = static_cast(childDrags[i]); if (!occupied && - !(static_cast(c->item)->getAttachedTo() && (startZone == currentZone->getLogic())) && + !(static_cast(c->item)->getState()->getAttachedTo() && + (startZone == currentZone->getLogic())) && !c->occupied) { dragItemList.append(c); } diff --git a/cockatrice/src/game_graphics/board/card_item.cpp b/cockatrice/src/game_graphics/board/card_item.cpp index cabe988c2..969d9daad 100644 --- a/cockatrice/src/game_graphics/board/card_item.cpp +++ b/cockatrice/src/game_graphics/board/card_item.cpp @@ -20,20 +20,16 @@ #include #include -CardItem::CardItem(PlayerLogic *_owner, - QGraphicsItem *parent, - const CardRef &cardRef, - int _cardid, - CardZoneLogic *_zone) - : AbstractCardItem(parent, cardRef, _owner, _cardid), state(new CardState(this, _zone)), dragItem(nullptr) +CardItem::CardItem(CardState *_state, CardZone *parent) + : AbstractCardItem(_state, parent), state(_state), zone(parent), dragItem(nullptr) { - owner->addCard(this); - connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) { if (state->getCounters().contains(counterId)) { update(); } }); + + connect(state, &CardState::visibleChanged, this, [this](bool visible) { setVisible(visible); }); } void CardItem::prepareDelete() @@ -45,16 +41,6 @@ void CardItem::prepareDelete() } owner = nullptr; } - - while (!attachedCards.isEmpty()) { - attachedCards.first()->setZone(nullptr); // so that it won't try to call reorganizeCards() - attachedCards.first()->setAttachedTo(nullptr); - } - - if (state->getAttachedTo() != nullptr) { - state->getAttachedTo()->removeAttachedCard(this); - state->setAttachedTo(nullptr); - } } void CardItem::deleteLater() @@ -66,11 +52,6 @@ void CardItem::deleteLater() AbstractCardItem::deleteLater(); } -void CardItem::setZone(CardZoneLogic *_zone) -{ - state->setZone(_zone); -} - void CardItem::retranslateUi() { } @@ -99,7 +80,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->save(); transformPainter(painter, translatedSize, tapAngle); - if (!getFaceDown() && state->getPT() == exactCard.getInfo().getPowTough()) { + if (!getState()->getFaceDown() && state->getPT() == getState()->getCard().getInfo().getPowTough()) { painter->setPen(Qt::white); } else { painter->setPen(QColor(255, 150, 0)); // dark orange @@ -149,107 +130,21 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->restore(); } -void CardItem::setAttacking(bool _attacking) -{ - state->setAttacking(_attacking); - update(); -} - -void CardItem::setCounter(int _id, int _value) -{ - state->setCounter(_id, _value); - update(); -} - -void CardItem::setAnnotation(const QString &_annotation) -{ - state->setAnnotation(_annotation); - update(); -} - -void CardItem::setDoesntUntap(bool _doesntUntap) -{ - state->setDoesntUntap(_doesntUntap); - update(); -} - -void CardItem::setPT(const QString &_pt) -{ - state->setPT(_pt); - update(); -} - -void CardItem::setAttachedTo(CardItem *_attachedTo) -{ - if (state->getAttachedTo() != nullptr) { - state->getAttachedTo()->removeAttachedCard(this); - } - - gridPoint.setX(-1); - state->setAttachedTo(_attachedTo); - if (state->getAttachedTo() != nullptr) { - // If the zone is being torn down, it might already be null by the time a card tries to un-attach all its - // attached cards - if (state->getAttachedTo()->getZone() == nullptr) { - deleteLater(); - } else { - emit state->getAttachedTo()->getZone()->cardAdded(this); - state->getAttachedTo()->addAttachedCard(this); - if (state->getZone() != state->getAttachedTo()->getZone()) { - state->getAttachedTo()->getZone()->reorganizeCards(); - } - } - } else { - // If the zone is being torn down, it might already be null by the time a card tries to un-attach all its - // attached cards - if (state->getZone() == nullptr) { - deleteLater(); - } else { - emit state->getZone()->cardAdded(this); - } - } - - if (state->getZone() != nullptr) { - state->getZone()->reorganizeCards(); - } -} - /** * @brief Resets the fields that should be reset after a zone transition */ void CardItem::resetState(bool keepAnnotations) { state->resetState(keepAnnotations); - attachedCards.clear(); - setTapped(false, false); - setDoesntUntap(false); + state->clearAttachedCards(); + state->setTapped(false, false); + getState()->setDoesntUntap(false); if (scene()) { static_cast(scene())->unregisterAnimationItem(this); } update(); } -void CardItem::processCardInfo(const ServerInfo_Card &_info) -{ - state->clearCounters(); - const int counterListSize = _info.counter_list_size(); - for (int i = 0; i < counterListSize; ++i) { - const ServerInfo_CardCounter &counterInfo = _info.counter_list(i); - state->insertCounter(counterInfo.id(), counterInfo.value()); - } - - setId(_info.id()); - setCardRef({QString::fromStdString(_info.name()), QString::fromStdString(_info.provider_id())}); - setAttacking(_info.attacking()); - setFaceDown(_info.face_down()); - setPT(QString::fromStdString(_info.pt())); - setAnnotation(QString::fromStdString(_info.annotation())); - setColor(QString::fromStdString(_info.color())); - setTapped(_info.tapped()); - setDestroyOnZoneChange(_info.destroy_on_zone_change()); - setDoesntUntap(_info.doesnt_untap()); -} - CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown) { deleteDragItem(); @@ -292,7 +187,7 @@ void CardItem::drawArrow(const QColor &arrowColor) if (card == nullptr || card == this) { continue; } - if (card->getZone() != state->getZone()) { + if (card->getState()->getZone() != state->getZone()) { continue; } @@ -317,7 +212,7 @@ void CardItem::drawAttachArrow() if (card == nullptr) { continue; } - if (card->getZone() != state->getZone()) { + if (card->getState()->getZone() != state->getZone()) { continue; } @@ -362,13 +257,13 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) // Use the buttonDownPos to align the hot spot with the position when // the user originally clicked - createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown); + createDragItem(getState()->getId(), event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown); dragItem->grabMouse(); int childIndex = 0; for (const auto &item : scene()->selectedItems()) { CardItem *card = static_cast(item); - if ((card == this) || (card->getZone() != state->getZone())) { + if ((card == this) || (card->getState()->getZone() != state->getZone())) { continue; } ++childIndex; @@ -378,8 +273,8 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } else { childPos = QPointF(childIndex * CardDimensions::WIDTH_HALF_F, 0); } - CardDragItem *drag = - new CardDragItem(card, card->getId(), childPos, card->getFaceDown() || forceFaceDown, dragItem); + CardDragItem *drag = new CardDragItem(card, card->getState()->getId(), childPos, + card->getState()->getFaceDown() || forceFaceDown, dragItem); drag->setPos(dragItem->pos() + childPos); scene()->addItem(drag); } @@ -405,7 +300,7 @@ void CardItem::playCard(bool faceDown) emit playSelected(this); } } else { - state->getZone()->getPlayer()->getPlayerActions()->playCard(this, faceDown); + state->getZone()->getPlayer()->getPlayerActions()->playCard(getState(), faceDown); } } } @@ -465,7 +360,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld) if (SettingsCache::instance().getClickPlaysAllSelected()) { emit hideSelected(this); } else { - state->getZone()->removeCard(this); + state->getZone()->removeCard(getState()); } } else { playCard(shiftHeld); @@ -476,7 +371,6 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::RightButton && owner != nullptr) { emit rightClicked(this, event->screenPos()); - return; } if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) && (!SettingsCache::instance().getDoubleClickToPlay())) { @@ -501,16 +395,16 @@ bool CardItem::animationEvent() { int rotation = ROTATION_DEGREES_PER_FRAME; bool animationIncomplete = true; - if (!tapped) { + if (!getState()->getTapped()) { rotation *= -1; } tapAngle += rotation; - if (tapped && (tapAngle > 90)) { + if (getState()->getTapped() && (tapAngle > 90)) { tapAngle = 90; animationIncomplete = false; } - if (!tapped && (tapAngle < 0)) { + if (!getState()->getTapped() && (tapAngle < 0)) { tapAngle = 0; animationIncomplete = false; } diff --git a/cockatrice/src/game_graphics/board/card_item.h b/cockatrice/src/game_graphics/board/card_item.h index 8efcd085d..acf7d31f2 100644 --- a/cockatrice/src/game_graphics/board/card_item.h +++ b/cockatrice/src/game_graphics/board/card_item.h @@ -29,10 +29,9 @@ class CardItem : public AbstractCardItem Q_OBJECT private: CardState *state; + CardZone *zone; - QPoint gridPoint; CardDragItem *dragItem; - QList attachedCards; void prepareDelete(); void handleClickedToPlay(bool shiftHeld); @@ -48,95 +47,20 @@ public: { return Type; } - explicit CardItem(PlayerLogic *_owner, - QGraphicsItem *parent = nullptr, - const CardRef &cardRef = {}, - int _cardid = -1, - CardZoneLogic *_zone = nullptr); + explicit CardItem(CardState *state, CardZone *parent); void retranslateUi(); + [[nodiscard]] CardZone *getZone() const + { + return zone; + } [[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 &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 &getAttachedCards() const - { - return attachedCards; - } + void resetState(bool keepAnnotations = false); - void processCardInfo(const ServerInfo_Card &_info); bool animationEvent(); CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown); diff --git a/cockatrice/src/game_graphics/deckview/deck_view.cpp b/cockatrice/src/game_graphics/deckview/deck_view.cpp index ced02c8db..ce2ac5f8b 100644 --- a/cockatrice/src/game_graphics/deckview/deck_view.cpp +++ b/cockatrice/src/game_graphics/deckview/deck_view.cpp @@ -73,7 +73,7 @@ void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } DeckViewCard::DeckViewCard(QGraphicsItem *parent, const CardRef &cardRef, const QString &_originZone) - : AbstractCardItem(parent, cardRef, 0, -1), originZone(_originZone), dragItem(0) + : AbstractCardItem(new AbstractCardState(nullptr, cardRef, -1), parent), originZone(_originZone), dragItem(0) { setAcceptHoverEvents(true); @@ -152,7 +152,7 @@ void DeckView::mouseDoubleClickEvent(QMouseEvent *event) auto *c = static_cast(sel.at(i)); auto *zone = static_cast(c->parentItem()); MoveCard_ToZone m; - m.set_card_name(c->getName().toStdString()); + m.set_card_name(c->getState()->getName().toStdString()); m.set_start_zone(zone->getName().toStdString()); if (zone->getName() == DECK_ZONE_MAIN) { @@ -228,13 +228,15 @@ void DeckViewCardContainer::paint(QPainter *painter, const QStyleOptionGraphicsI void DeckViewCardContainer::addCard(DeckViewCard *card) { cards.append(card); - cardsByType.insert(card->getCard().isEmpty() ? "" : card->getCardInfo().getMainCardType(), card); + cardsByType.insert(card->getState()->getCard().isEmpty() ? "" : card->getState()->getCardInfo().getMainCardType(), + card); } void DeckViewCardContainer::removeCard(DeckViewCard *card) { cards.removeOne(card); - cardsByType.remove(card->getCard().isEmpty() ? "" : card->getCardInfo().getMainCardType(), card); + cardsByType.remove(card->getState()->getCard().isEmpty() ? "" : card->getState()->getCardInfo().getMainCardType(), + card); } QList> DeckViewCardContainer::getRowsAndCols() const @@ -283,7 +285,7 @@ QSizeF DeckViewCardContainer::calculateBoundingRect(const QList> bool DeckViewCardContainer::sortCardsByName(DeckViewCard *c1, DeckViewCard *c2) { if (c1 && c2) { - return c1->getName() < c2->getName(); + return c1->getState()->getName() < c2->getState()->getName(); } return false; } @@ -396,7 +398,7 @@ void DeckViewScene::applySideboardPlan(const QList &plan) DeckViewCard *card = 0; const QList &cardList = start->getCards(); for (int j = 0; j < cardList.size(); ++j) { - if (cardList[j]->getName() == QString::fromStdString(m.card_name())) { + if (cardList[j]->getState()->getName() == QString::fromStdString(m.card_name())) { card = cardList[j]; break; } @@ -498,7 +500,7 @@ QList DeckViewScene::getSideboardPlan() const for (int i = 0; i < cardList.size(); ++i) { if (cardList[i]->getOriginZone() != cont->getName()) { MoveCard_ToZone m; - m.set_card_name(cardList[i]->getName().toStdString()); + m.set_card_name(cardList[i]->getState()->getName().toStdString()); m.set_start_zone(cardList[i]->getOriginZone().toStdString()); m.set_target_zone(cont->getName().toStdString()); result.append(m); diff --git a/cockatrice/src/game_graphics/game_scene.cpp b/cockatrice/src/game_graphics/game_scene.cpp index b9816a602..7586a38e4 100644 --- a/cockatrice/src/game_graphics/game_scene.cpp +++ b/cockatrice/src/game_graphics/game_scene.cpp @@ -76,6 +76,18 @@ QList GameScene::selectedCards() const return selectedCards; } +QList GameScene::selectedCardsAsStates() const +{ + QList selectedCards; + for (auto item : selectedItems()) { + if (auto card = qgraphicsitem_cast(item)) { + selectedCards.append(card->getState()); + } + } + + return selectedCards; +} + void GameScene::onCardSelectionChanged(AbstractCardItem *abstractCard, bool selected) { CardItem *card = qobject_cast(abstractCard); @@ -86,7 +98,7 @@ void GameScene::onCardSelectionChanged(AbstractCardItem *abstractCard, bool sele auto *owner = card->getOwner(); if (selected) { - owner->requestCardMenuUpdate(card); + owner->requestCardMenuUpdate(card->getState()); return; } @@ -112,7 +124,7 @@ void GameScene::onCardRightClicked(AbstractCardItem *abstractCard, QPoint screen card->getOwner()->getGame()->setActiveCard(card); - if (auto *menu = view->getPlayerMenu()->updateCardMenu(card)) { + if (auto *menu = view->getPlayerMenu()->updateCardMenu(card->getState())) { menu->popup(screenPos); } } @@ -125,7 +137,7 @@ void GameScene::playSelected(AbstractCardItem *card) if (!card->getOwner()) { return; } - card->getOwner()->getPlayerActions()->actPlay(selectedCards()); + card->getOwner()->getPlayerActions()->actPlay(selectedCardsAsStates()); } void GameScene::playSelectedFaceDown(AbstractCardItem *card) @@ -136,7 +148,7 @@ void GameScene::playSelectedFaceDown(AbstractCardItem *card) if (!card->getOwner()) { return; } - card->getOwner()->getPlayerActions()->actPlayFacedown(selectedCards()); + card->getOwner()->getPlayerActions()->actPlayFacedown(selectedCardsAsStates()); } void GameScene::hideSelected(AbstractCardItem *card) @@ -147,7 +159,7 @@ void GameScene::hideSelected(AbstractCardItem *card) if (!card->getOwner()) { return; } - card->getOwner()->getPlayerActions()->actHide(selectedCards()); + card->getOwner()->getPlayerActions()->actHide(selectedCardsAsStates()); } /** @@ -181,7 +193,8 @@ void GameScene::addPlayer(PlayerLogic *player) connect(player, &PlayerLogic::arrowsClearedLocally, this, [this, id = player->getPlayerInfo()->getId()]() { clearArrowsForPlayerLocally(id); }); - connect(player->getPlayerEventHandler(), &PlayerEventHandler::cardZoneChanged, this, &GameScene::onCardZoneChanged); + // connect(player->getPlayerEventHandler(), &PlayerEventHandler::cardZoneChanged, this, + // &GameScene::onCardZoneChanged); rearrange(); } @@ -458,13 +471,12 @@ void GameScene::addArrow(QSharedPointer data) return; } - PlayerLogic *startLogic = startView->getLogic(); - auto *startZone = startLogic->getZones().value(data->startZone); - if (!startZone) { + auto *startZoneView = startView->getZoneGraphicsItem(data->startZone); + if (!startZoneView) { return; } - CardItem *startCard = startZone->getCard(data->startCardId); + CardItem *startCard = startZoneView->getCardItemForId(data->startCardId); if (!startCard) { return; } @@ -473,9 +485,9 @@ void GameScene::addArrow(QSharedPointer data) if (data->isPlayerTargeted()) { targetItem = targetView->getPlayerTarget(); } else { - auto *zone = targetView->getLogic()->getZones().value(data->targetZone); + auto *zone = targetView->getZoneGraphicsItem(data->targetZone); if (zone) { - targetItem = zone->getCard(data->targetCardId); + targetItem = zone->getCardItemForId(data->targetCardId); } } if (!targetItem) { @@ -592,11 +604,11 @@ CardItem *GameScene::findTopmostCardInZone(const QList &items, continue; } - if (card->getAttachedTo()) { - if (card->getAttachedTo()->getZone() != zone->getLogic()) { + if (card->getState()->getAttachedTo()) { + if (card->getState()->getAttachedTo()->getZone() != zone->getLogic()) { continue; } - } else if (card->getZone() != zone->getLogic()) { + } else if (card->getZone()->getLogic() != zone->getLogic()) { continue; } diff --git a/cockatrice/src/game_graphics/game_scene.h b/cockatrice/src/game_graphics/game_scene.h index 74e979556..e27302b0d 100644 --- a/cockatrice/src/game_graphics/game_scene.h +++ b/cockatrice/src/game_graphics/game_scene.h @@ -85,6 +85,9 @@ public: /** @brief Gets all selected CardItems. */ QList selectedCards() const; + /** @brief Gets all selected Cards as states. */ + QList selectedCardsAsStates() const; + /** * @brief Adds a player to the scene and stores their graphics item. * @param player Player to add. diff --git a/cockatrice/src/game_graphics/log/message_log_widget.cpp b/cockatrice/src/game_graphics/log/message_log_widget.cpp index ccd903b04..868f33b55 100644 --- a/cockatrice/src/game_graphics/log/message_log_widget.cpp +++ b/cockatrice/src/game_graphics/log/message_log_widget.cpp @@ -256,7 +256,7 @@ void MessageLogWidget::logDestroyCard(PlayerLogic *player, QString cardName) } void MessageLogWidget::logMoveCard(PlayerLogic *player, - CardItem *card, + CardState *card, CardZoneLogic *startZone, int oldX, CardZoneLogic *targetZone, @@ -636,7 +636,7 @@ void MessageLogWidget::logSetActivePlayer(PlayerLogic *player) QString(tr("%1's turn.")).arg(player->getPlayerInfo()->getName()) + "
"); } -void MessageLogWidget::logSetAnnotation(PlayerLogic *player, CardItem *card, QString newAnnotation) +void MessageLogWidget::logSetAnnotation(PlayerLogic *player, CardState *card, QString newAnnotation) { appendHtmlServerMessage( QString(tr("%1 sets annotation of %2 to %3.")) @@ -680,7 +680,7 @@ void MessageLogWidget::logSetCounter(PlayerLogic *player, QString counterName, i .arg(value - oldValue)); } -void MessageLogWidget::logSetDoesntUntap(PlayerLogic *player, CardItem *card, bool doesntUntap) +void MessageLogWidget::logSetDoesntUntap(PlayerLogic *player, CardState *card, bool doesntUntap) { QString str; if (doesntUntap) { @@ -691,7 +691,7 @@ void MessageLogWidget::logSetDoesntUntap(PlayerLogic *player, CardItem *card, bo appendHtmlServerMessage(str.arg(sanitizeHtml(player->getPlayerInfo()->getName())).arg(cardLink(card->getName()))); } -void MessageLogWidget::logSetPT(PlayerLogic *player, CardItem *card, QString newPT) +void MessageLogWidget::logSetPT(PlayerLogic *player, CardState *card, QString newPT) { if (currentContext == MessageContext_MoveCard) { return; @@ -729,7 +729,7 @@ void MessageLogWidget::logSetSideboardLock(PlayerLogic *player, bool locked) } } -void MessageLogWidget::logSetTapped(PlayerLogic *player, CardItem *card, bool tapped) +void MessageLogWidget::logSetTapped(PlayerLogic *player, CardState *card, bool tapped) { if (currentContext == MessageContext_MoveCard) { return; diff --git a/cockatrice/src/game_graphics/log/message_log_widget.h b/cockatrice/src/game_graphics/log/message_log_widget.h index a145d358d..74ddeab3c 100644 --- a/cockatrice/src/game_graphics/log/message_log_widget.h +++ b/cockatrice/src/game_graphics/log/message_log_widget.h @@ -11,7 +11,7 @@ #include "../../interface/widgets/server/chat_view/chat_view.h" class AbstractGame; -class CardItem; +class CardState; class GameEventContext; class PlayerLogic; class PlayerEventHandler; @@ -67,7 +67,7 @@ public slots: void logLeaveSpectator(QString name, QString reason); void logNotReadyStart(PlayerLogic *player); void logMoveCard(PlayerLogic *player, - CardItem *card, + CardState *card, CardZoneLogic *startZone, int oldX, CardZoneLogic *targetZone, @@ -88,13 +88,13 @@ public slots: void logSay(PlayerLogic *player, QString message); void logSetActivePhase(int phase); void logSetActivePlayer(PlayerLogic *player); - void logSetAnnotation(PlayerLogic *player, CardItem *card, QString newAnnotation); + void logSetAnnotation(PlayerLogic *player, CardState *card, QString newAnnotation); void logSetCardCounter(PlayerLogic *player, QString cardName, int counterId, int value, int oldValue); void logSetCounter(PlayerLogic *player, QString counterName, int value, int oldValue); - void logSetDoesntUntap(PlayerLogic *player, CardItem *card, bool doesntUntap); - void logSetPT(PlayerLogic *player, CardItem *card, QString newPT); + void logSetDoesntUntap(PlayerLogic *player, CardState *card, bool doesntUntap); + void logSetPT(PlayerLogic *player, CardState *card, QString newPT); void logSetSideboardLock(PlayerLogic *player, bool locked); - void logSetTapped(PlayerLogic *player, CardItem *card, bool tapped); + void logSetTapped(PlayerLogic *player, CardState *card, bool tapped); void logShuffle(PlayerLogic *player, CardZoneLogic *zone, int start, int end); void logSpectatorSay(const ServerInfo_User &spectator, QString message); void logUnattachCard(PlayerLogic *player, QString cardName); diff --git a/cockatrice/src/game_graphics/player/menu/card_menu.cpp b/cockatrice/src/game_graphics/player/menu/card_menu.cpp index aa94c3be7..72224987c 100644 --- a/cockatrice/src/game_graphics/player/menu/card_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/card_menu.cpp @@ -44,7 +44,7 @@ static QAction *makeAction(QObject *parent, Slot &&slot, bool checkable = false, return a; } -CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _shortcutsActive) +CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardState *_card, bool _shortcutsActive) : player(_player), card(_card), shortcutsActive(_shortcutsActive) { const QList &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); @@ -63,7 +63,7 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho auto *gameScene = player->getGameScene(); // Single selection resolver used by all lambdas — called at trigger time - auto sel = [gameScene]() { return gameScene->selectedCards(); }; + auto sel = [gameScene]() { return gameScene->selectedCardsAsStates(); }; // Unified dispatcher for card menu actions auto invoke = [actions, sel](CardMenuActionType type) { @@ -314,7 +314,7 @@ void CardMenu::createHandOrCustomZoneMenu(bool canModifyCard) initContextualPlayersMenu(revealMenu, aRevealToAll); connect(revealMenu, &QMenu::triggered, this, [this](QAction *action) { - player->getLogic()->getPlayerActions()->actReveal(player->getGameScene()->selectedCards(), action); + player->getLogic()->getPlayerActions()->actReveal(player->getGameScene()->selectedCardsAsStates(), action); }); addSeparator(); diff --git a/cockatrice/src/game_graphics/player/menu/card_menu.h b/cockatrice/src/game_graphics/player/menu/card_menu.h index d67ef3876..94dd43ff8 100644 --- a/cockatrice/src/game_graphics/player/menu/card_menu.h +++ b/cockatrice/src/game_graphics/player/menu/card_menu.h @@ -7,9 +7,12 @@ #ifndef COCKATRICE_CARD_MENU_H #define COCKATRICE_CARD_MENU_H +#include "libcockatrice/utility/card_ref.h" + #include #include +class CardState; class CardItem; class PlayerGraphicsItem; class PlayerLogic; @@ -21,7 +24,7 @@ signals: void cardInfoRequested(const CardRef &cardRef); public: - explicit CardMenu(PlayerGraphicsItem *player, const CardItem *card, bool shortcutsActive); + explicit CardMenu(PlayerGraphicsItem *player, const CardState *card, bool shortcutsActive); void removePlayer(PlayerLogic *playerToRemove); void createTableMenu(bool canModifyCard); void createStackMenu(bool canModifyCard); @@ -47,7 +50,7 @@ public: private: PlayerGraphicsItem *player; - const CardItem *card; + const CardState *card; QList> playersInfo; bool shortcutsActive; diff --git a/cockatrice/src/game_graphics/player/menu/move_menu.cpp b/cockatrice/src/game_graphics/player/menu/move_menu.cpp index 5b7209a9f..adc2c6f71 100644 --- a/cockatrice/src/game_graphics/player/menu/move_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/move_menu.cpp @@ -25,7 +25,8 @@ MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to")) auto invoke = [player](CardMenuActionType type) { return [type, player]() { - player->getLogic()->getPlayerActions()->cardMenuAction(player->getGameScene()->selectedCards(), type); + player->getLogic()->getPlayerActions()->cardMenuAction(player->getGameScene()->selectedCardsAsStates(), + type); }; }; diff --git a/cockatrice/src/game_graphics/player/menu/player_menu.cpp b/cockatrice/src/game_graphics/player/menu/player_menu.cpp index 17b791222..9d7a0bdbe 100644 --- a/cockatrice/src/game_graphics/player/menu/player_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/player_menu.cpp @@ -69,7 +69,7 @@ void PlayerMenu::setMenusForGraphicItems() } } -QMenu *PlayerMenu::updateCardMenu(const CardItem *card) +QMenu *PlayerMenu::updateCardMenu(const CardState *card) { if (!card) { emit cardMenuUpdated(nullptr); @@ -78,9 +78,10 @@ QMenu *PlayerMenu::updateCardMenu(const CardItem *card) // If is spectator (as spectators don't need card menus), return // only update the menu if the card is actually selected + auto *activeCard = player->getLogic()->getGame()->getActiveCard(); if ((player->getLogic()->getGame()->getPlayerManager()->isSpectator() && !player->getLogic()->getGame()->getPlayerManager()->isJudge()) || - player->getLogic()->getGame()->getActiveCard() != card) { + !activeCard || activeCard->getState() != card) { return nullptr; } diff --git a/cockatrice/src/game_graphics/player/menu/player_menu.h b/cockatrice/src/game_graphics/player/menu/player_menu.h index 62ba66df7..1c896461c 100644 --- a/cockatrice/src/game_graphics/player/menu/player_menu.h +++ b/cockatrice/src/game_graphics/player/menu/player_menu.h @@ -21,7 +21,7 @@ #include #include -class CardItem; +class CardState; class CardMenu; class PlayerGraphicsItem; class PlayerMenu : public QObject @@ -37,7 +37,7 @@ signals: public slots: void setMenusForGraphicItems(); - QMenu *updateCardMenu(const CardItem *card); + QMenu *updateCardMenu(const CardState *card); private slots: void refreshShortcuts(); diff --git a/cockatrice/src/game_graphics/player/menu/pt_menu.cpp b/cockatrice/src/game_graphics/player/menu/pt_menu.cpp index a01be9424..7b37f7607 100644 --- a/cockatrice/src/game_graphics/player/menu/pt_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/pt_menu.cpp @@ -10,34 +10,35 @@ PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness")) aIncP = new QAction(this); connect(aIncP, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actIncP(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actIncP(player->getGameScene()->selectedCardsAsStates()); }); aDecP = new QAction(this); connect(aDecP, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actDecP(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actDecP(player->getGameScene()->selectedCardsAsStates()); }); aIncT = new QAction(this); connect(aIncT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actIncT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actIncT(player->getGameScene()->selectedCardsAsStates()); }); aDecT = new QAction(this); connect(aDecT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actDecT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actDecT(player->getGameScene()->selectedCardsAsStates()); }); aIncPT = new QAction(this); connect(aIncPT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actIncPT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actIncPT(player->getGameScene()->selectedCardsAsStates()); }); aDecPT = new QAction(this); connect(aDecPT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actDecPT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actDecPT(player->getGameScene()->selectedCardsAsStates()); }); aFlowP = new QAction(this); connect(aFlowP, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actFlowP(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actFlowP(player->getGameScene()->selectedCardsAsStates()); }); aFlowT = new QAction(this); connect(aFlowT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCardsAsStates()); }); aSetPT = new QAction(this); - connect(aSetPT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actRequestSetPTDialog(player->getGameScene()->selectedCards()); }); + connect(aSetPT, &QAction::triggered, playerActions, [player, playerActions] { + playerActions->actRequestSetPTDialog(player->getGameScene()->selectedCardsAsStates()); + }); aResetPT = new QAction(this); connect(aResetPT, &QAction::triggered, playerActions, - [player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCards()); }); + [player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCardsAsStates()); }); addAction(aIncP); addAction(aDecP); diff --git a/cockatrice/src/game_graphics/player/menu/utility_menu.cpp b/cockatrice/src/game_graphics/player/menu/utility_menu.cpp index 61a822b21..a851f036a 100644 --- a/cockatrice/src/game_graphics/player/menu/utility_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/utility_menu.cpp @@ -38,7 +38,7 @@ UtilityMenu::UtilityMenu(PlayerGraphicsItem *_player, QMenu *playerMenu) : QMenu aIncrementAllCardCounters = new QAction(this); connect(aIncrementAllCardCounters, &QAction::triggered, playerActions, [this]() { player->getLogic()->getPlayerActions()->actIncrementAllCardCounters( - player->getGameScene()->selectedCards()); + player->getGameScene()->selectedCardsAsStates()); }); createPredefinedTokenMenu = new QMenu(QString()); diff --git a/cockatrice/src/game_graphics/player/menu/utility_menu.h b/cockatrice/src/game_graphics/player/menu/utility_menu.h index bdc2a81a5..8f3b2bd5c 100644 --- a/cockatrice/src/game_graphics/player/menu/utility_menu.h +++ b/cockatrice/src/game_graphics/player/menu/utility_menu.h @@ -8,6 +8,7 @@ #define COCKATRICE_UTILITY_MENU_H #include "abstract_player_component.h" +#include "libcockatrice/card/card_info.h" #include #include diff --git a/cockatrice/src/game_graphics/player/player_dialogs.cpp b/cockatrice/src/game_graphics/player/player_dialogs.cpp index 3c26ae1fe..d0c6f8d25 100644 --- a/cockatrice/src/game_graphics/player/player_dialogs.cpp +++ b/cockatrice/src/game_graphics/player/player_dialogs.cpp @@ -241,14 +241,14 @@ void PlayerDialogs::onMoveCardXCardsFromTopDialogRequested(int defaultNumberTopC number -= 1; // indexes start at 0 if (ok) { - playerActions->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards(), number); + playerActions->actMoveCardXCardsFromTop(player->getGameScene()->selectedCardsAsStates(), number); } } void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT) { bool ok; - auto cards = player->getGameScene()->selectedCards(); + auto cards = player->getGameScene()->selectedCardsAsStates(); emit requestDialogSemaphore(true); QString pt = getTextWithMax(dialogParent(), tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, oldPT, &ok); @@ -263,7 +263,7 @@ void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT) void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation) { - auto cards = player->getGameScene()->selectedCards(); + auto cards = player->getGameScene()->selectedCardsAsStates(); emit requestDialogSemaphore(true); AnnotationDialog *dialog = new AnnotationDialog(dialogParent()); dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput); @@ -281,7 +281,7 @@ void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation) void PlayerDialogs::onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg) { - auto cards = player->getGameScene()->selectedCards(); + auto cards = player->getGameScene()->selectedCardsAsStates(); emit requestDialogSemaphore(true); auto &cardCounterSettings = SettingsCache::instance().cardCounters(); diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.cpp b/cockatrice/src/game_graphics/player/player_graphics_item.cpp index e0194abda..68ccd5a57 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.cpp +++ b/cockatrice/src/game_graphics/player/player_graphics_item.cpp @@ -126,12 +126,19 @@ void PlayerGraphicsItem::initializeZones() connect(handCounter, &HandCounter::showContextMenu, handZoneGraphicsItem, &HandZone::showContextMenu); zoneGraphicsItems.insert(player->getDeckZone()->getName(), deckZoneGraphicsItem); + connect(deckZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); zoneGraphicsItems.insert(player->getGraveZone()->getName(), graveyardZoneGraphicsItem); + connect(graveyardZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); zoneGraphicsItems.insert(player->getRfgZone()->getName(), rfgZoneGraphicsItem); + connect(rfgZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); zoneGraphicsItems.insert(player->getSideboardZone()->getName(), sideboardGraphicsItem); + connect(sideboardGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); zoneGraphicsItems.insert(player->getTableZone()->getName(), tableZoneGraphicsItem); + connect(tableZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); zoneGraphicsItems.insert(player->getStackZone()->getName(), stackZoneGraphicsItem); + connect(stackZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); zoneGraphicsItems.insert(player->getHandZone()->getName(), handZoneGraphicsItem); + connect(handZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded); } void PlayerGraphicsItem::onCustomZoneAdded(QString customZoneName) diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.h b/cockatrice/src/game_graphics/player/player_graphics_item.h index d02234ded..f7e57ad76 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.h +++ b/cockatrice/src/game_graphics/player/player_graphics_item.h @@ -126,6 +126,7 @@ signals: void playerCountChanged(); void mirroredChanged(bool isMirrored); void cardInfoRequested(const CardRef &cardRef); + void cardItemAdded(CardItem *added); private: PlayerLogic *player; diff --git a/cockatrice/src/game_graphics/zones/card_zone.cpp b/cockatrice/src/game_graphics/zones/card_zone.cpp index 3457b681e..4dc299944 100644 --- a/cockatrice/src/game_graphics/zones/card_zone.cpp +++ b/cockatrice/src/game_graphics/zones/card_zone.cpp @@ -7,26 +7,45 @@ #include CardZone::CardZone(CardZoneLogic *_logic, QGraphicsItem *parent) - : AbstractGraphicsItem(parent), menu(nullptr), doubleClickAction(0), logic(_logic) + : AbstractGraphicsItem(parent), logic(_logic), menu(nullptr), doubleClickAction(0) { connect(logic, &CardZoneLogic::retranslateUi, this, &CardZone::retranslateUi); connect(logic, &CardZoneLogic::cardAdded, this, &CardZone::onCardAdded); + connect(logic, &CardZoneLogic::cardRemoved, this, &CardZone::onCardRemoved); connect(logic, &CardZoneLogic::setGraphicsVisibility, this, [this](bool v) { this->setVisible(v); }); connect(logic, &CardZoneLogic::updateGraphics, this, [this]() { update(); }); connect(logic, &CardZoneLogic::reorganizeCards, this, &CardZone::reorganizeCards); } -void CardZone::onCardAdded(CardItem *addedCard) +void CardZone::onCardAdded(CardState *toAdd, int /*x*/, int /*y*/) { + CardItem *addedCard = new CardItem(toAdd, this); addedCard->setParentItem(this); addedCard->setVisible(true); addedCard->update(); + cards.append(addedCard); + + emit cardItemAdded(addedCard); +} + +void CardZone::onCardRemoved(CardState *toRemove, int /*x*/, int /*y*/) +{ + CardItem *removedCard = getCardItemForId(toRemove->getId()); + if (!removedCard) { + return; + } + if (cards.contains(removedCard)) { + cards.remove(cards.indexOf(removedCard)); + } + removedCard->setVisible(false); + removedCard->setParentItem(nullptr); + removedCard->deleteLater(); } void CardZone::retranslateUi() { - for (int i = 0; i < getLogic()->getCards().size(); ++i) { - getLogic()->getCards()[i]->retranslateUi(); + for (int i = 0; i < cards.size(); ++i) { + cards[i]->retranslateUi(); } } diff --git a/cockatrice/src/game_graphics/zones/card_zone.h b/cockatrice/src/game_graphics/zones/card_zone.h index 4cef6ca80..10e6c2c03 100644 --- a/cockatrice/src/game_graphics/zones/card_zone.h +++ b/cockatrice/src/game_graphics/zones/card_zone.h @@ -9,6 +9,7 @@ #include "../../game/zones/card_zone_logic.h" #include "../board/abstract_graphics_item.h" +#include "../board/card_item.h" #include "../board/graphics_item_type.h" #include @@ -26,6 +27,9 @@ class CardZone : public AbstractGraphicsItem { Q_OBJECT protected: + CardZoneLogic *logic; + QList cards; + QMenu *menu; QAction *doubleClickAction; @@ -46,7 +50,11 @@ public slots: * Virtual so subclasses (e.g. SelectZone) can override parenting behavior — the Qt signal * connection in CardZone's constructor dispatches through the vtable. */ - virtual void onCardAdded(CardItem *addedCard); + virtual void onCardAdded(CardState *addedCard, int x, int y); + void onCardRemoved(CardState *toAdd, int x, int y); + +signals: + void cardItemAdded(CardItem *added); public: enum @@ -67,14 +75,21 @@ public: return logic; } + CardItem *getCardItemForId(int id) const + { + for (CardItem *card : cards) { + if (card->getState()->getId() == id) { + return card; + } + } + return nullptr; + } + void setMenu(QMenu *_menu, QAction *_doubleClickAction = 0) { menu = _menu; doubleClickAction = _doubleClickAction; } - -private: - CardZoneLogic *logic; }; #endif diff --git a/cockatrice/src/game_graphics/zones/hand_zone.cpp b/cockatrice/src/game_graphics/zones/hand_zone.cpp index 5885e3630..67488475e 100644 --- a/cockatrice/src/game_graphics/zones/hand_zone.cpp +++ b/cockatrice/src/game_graphics/zones/hand_zone.cpp @@ -35,7 +35,7 @@ void HandZone::handleDropEvent(const QList &dragItems, int x = -1; if (SettingsCache::instance().getHorizontalHand()) { for (x = 0; x < getLogic()->getCards().size(); x++) { - if (point.x() < static_cast(getLogic()->getCards().at(x))->scenePos().x()) { + if (point.x() < getCardItemForId(getLogic()->getCards().at(x)->getId())->scenePos().x()) { break; } } @@ -75,23 +75,23 @@ void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio void HandZone::reorganizeCards() { - if (!getLogic()->getCards().isEmpty()) { - const int cardCount = getLogic()->getCards().size(); + if (!cards.isEmpty()) { + const int cardCount = cards.size(); if (SettingsCache::instance().getHorizontalHand()) { bool leftJustified = SettingsCache::instance().getLeftJustified(); - qreal cardWidth = getLogic()->getCards().at(0)->boundingRect().width(); + qreal cardWidth = cards.at(0)->boundingRect().width(); const int xPadding = leftJustified ? cardWidth * 1.4 : 5; qreal totalWidth = leftJustified ? boundingRect().width() - (1 * xPadding) - 5 : boundingRect().width() - 2 * xPadding; if (cardCount == 1) { - CardItem *c = getLogic()->getCards().at(0); + CardItem *c = cards.at(0); qreal xPosition = leftJustified ? xPadding : xPadding + (totalWidth - cardWidth) / 2; c->setPos(xPosition, 5); c->setRealZValue(0); } else { for (int i = 0; i < cardCount; i++) { - CardItem *c = getLogic()->getCards().at(i); + CardItem *c = cards.at(i); // If the total width of the cards is smaller than the available width, // the cards do not need to overlap and are displayed in the center of the area. if (cardWidth * cardCount > totalWidth) { diff --git a/cockatrice/src/game_graphics/zones/pile_zone.cpp b/cockatrice/src/game_graphics/zones/pile_zone.cpp index 7bb0e695a..9cf426ed8 100644 --- a/cockatrice/src/game_graphics/zones/pile_zone.cpp +++ b/cockatrice/src/game_graphics/zones/pile_zone.cpp @@ -31,6 +31,17 @@ PileZone::PileZone(PileZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_log }); } +void PileZone::onCardAdded(CardState *toAdd, int /*x*/, int /*y*/) +{ + CardItem *addedCard = new CardItem(toAdd, this); + addedCard->setParentItem(this); + addedCard->setVisible(false); + addedCard->setPos(0, 0); + addedCard->update(); + connect(addedCard, &CardItem::sigPixmapUpdated, this, [this]() { update(); }); + cards.append(addedCard); +} + QRectF PileZone::boundingRect() const { return QRectF(0, 0, CardDimensions::WIDTH_F, CardDimensions::HEIGHT_F); @@ -48,15 +59,15 @@ void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio { painter->drawPath(shape()); - if (!getLogic()->getCards().isEmpty()) { - getLogic()->getCards().at(0)->paintPicture(painter, getLogic()->getCards().at(0)->getTranslatedSize(painter), - 90); + if (!cards.isEmpty()) { + CardItem *cardAt = cards.at(0); + cardAt->paintPicture(painter, cardAt->getTranslatedSize(painter), 90); } painter->translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F); painter->rotate(-90); painter->translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F); - paintNumberEllipse(getLogic()->getCards().size(), 28, Qt::white, -1, -1, painter); + paintNumberEllipse(cards.size(), 28, Qt::white, -1, -1, painter); } void PileZone::handleDropEvent(const QList &dragItems, CardZoneLogic *startZone, const QPoint &) @@ -113,10 +124,11 @@ void PileZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event) bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier); bool bottomCard = event->modifiers().testFlag(Qt::ControlModifier); - CardItem *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first(); + CardState *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first(); const int cardid = getLogic()->contentsKnown() ? card->getId() : (bottomCard ? getLogic()->getCards().size() - 1 : 0); - CardDragItem *drag = card->createDragItem(cardid, event->pos(), event->scenePos(), forceFaceDown); + CardDragItem *drag = + getCardItemForId(card->getId())->createDragItem(cardid, event->pos(), event->scenePos(), forceFaceDown); drag->grabMouse(); setCursor(Qt::OpenHandCursor); } @@ -128,8 +140,8 @@ void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/) void PileZone::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { - if (!getLogic()->getCards().isEmpty()) { - getLogic()->getCards()[0]->processHoverEvent(); + if (!cards.isEmpty()) { + cards[0]->processHoverEvent(); } QGraphicsItem::hoverEnterEvent(event); } diff --git a/cockatrice/src/game_graphics/zones/pile_zone.h b/cockatrice/src/game_graphics/zones/pile_zone.h index 099bc6f60..5200f7c2f 100644 --- a/cockatrice/src/game_graphics/zones/pile_zone.h +++ b/cockatrice/src/game_graphics/zones/pile_zone.h @@ -17,11 +17,8 @@ class PileZone : public CardZone { Q_OBJECT -private slots: - void callUpdate() - { - update(); - } +public slots: + void onCardAdded(CardState *toAdd, int, int) override; public: PileZone(PileZoneLogic *_logic, QGraphicsItem *parent); diff --git a/cockatrice/src/game_graphics/zones/select_zone.cpp b/cockatrice/src/game_graphics/zones/select_zone.cpp index f2e720686..c43b71cd8 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.cpp +++ b/cockatrice/src/game_graphics/zones/select_zone.cpp @@ -85,7 +85,7 @@ SelectZone::StackLayoutParams SelectZone::buildStackParams(qreal minOffset) cons return {0, boundingRect().height(), 0.0, 0.0, minOffset}; } const auto cardCount = static_cast(cards.size()); - const qreal cardHeight = cards.at(0)->boundingRect().height(); + const qreal cardHeight = 200; // TODO cards.at(0)->boundingRect().height(); const qreal offset = stackingOffset(cardHeight); return {cardCount, boundingRect().height(), cardHeight, offset, minOffset}; } @@ -109,7 +109,7 @@ void SelectZone::restoreStaleEscapedCards() if (!cardClipContainer) { return; } - for (auto *card : getLogic()->getCards()) { + for (auto *card : cards) { // A card parented to the zone (instead of the clip container) should // only occur while it is actively hovered. If hover cleanup was // missed, reparent it back so clipping resumes. @@ -121,7 +121,6 @@ void SelectZone::restoreStaleEscapedCards() void SelectZone::layoutCardsVertically(const StackLayoutParams ¶ms) { - const auto &cards = getLogic()->getCards(); if (cards.isEmpty() || params.cardCount <= 0) { return; } @@ -158,7 +157,7 @@ SelectZone::~SelectZone() // parent-child tree is consistent for destruction. setParentItem() does // not invalidate getLogic()->getCards() (it modifies the graphics tree, // not the zone's logical card list). - for (auto *card : getLogic()->getCards()) { + for (auto *card : cards) { if (card && card->parentItem() == this) { card->setParentItem(cardClipContainer); } @@ -166,14 +165,16 @@ SelectZone::~SelectZone() } } -void SelectZone::onCardAdded(CardItem *addedCard) +void SelectZone::onCardAdded(CardState *toAdd, int x, int y) { - if (cardClipContainer && addedCard) { + if (cardClipContainer && toAdd) { + CardItem *addedCard = new CardItem(toAdd, this); addedCard->setParentItem(cardClipContainer); addedCard->setVisible(true); addedCard->update(); + emit cardItemAdded(addedCard); } else { - CardZone::onCardAdded(addedCard); + CardZone::onCardAdded(toAdd, x, y); } } @@ -241,8 +242,8 @@ void SelectZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } QRectF selectionRect = QRectF(selectionOrigin, pos).normalized(); - for (auto card : getLogic()->getCards()) { - if (card->getAttachedTo() && card->getAttachedTo()->getZone() != getLogic()) { + for (auto card : cards) { + if (card->getState()->getAttachedTo() && card->getState()->getAttachedTo()->getZone() != getLogic()) { continue; } diff --git a/cockatrice/src/game_graphics/zones/select_zone.h b/cockatrice/src/game_graphics/zones/select_zone.h index 7408f29b6..783651b95 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.h +++ b/cockatrice/src/game_graphics/zones/select_zone.h @@ -29,7 +29,7 @@ public: SelectZone(CardZoneLogic *logic, QGraphicsItem *parent = nullptr); ~SelectZone() override; - void onCardAdded(CardItem *addedCard) override; + void onCardAdded(CardState *addedCard, int x, int y) override; /** * @brief Temporarily reparents a card from the clip container to this zone so hover scaling is visible beyond clip diff --git a/cockatrice/src/game_graphics/zones/table_zone.cpp b/cockatrice/src/game_graphics/zones/table_zone.cpp index e886f62e9..c9d5dcc0b 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.cpp +++ b/cockatrice/src/game_graphics/zones/table_zone.cpp @@ -146,7 +146,7 @@ void TableZone::handleDropEventByGrid(const QList &dragItems, ctm->set_face_down(true); } if (startZone->getName() != getLogic()->getName() && !item->isForceFaceDown()) { - const auto &card = item->getItem()->getCard(); + const auto &card = item->getItem()->getState()->getCard(); if (card) { ctm->set_pt(card.getInfo().getPowTough().toStdString()); } @@ -161,8 +161,8 @@ void TableZone::reorganizeCards() // Calculate card stack widths so mapping functions work properly computeCardStackWidths(); - for (int i = 0; i < getLogic()->getCards().size(); ++i) { - QPoint gridPoint = getLogic()->getCards()[i]->getGridPos(); + for (int i = 0; i < cards.size(); ++i) { + QPoint gridPoint = cards[i]->getState()->getGridPos(); if (gridPoint.x() == -1) { continue; } @@ -171,21 +171,22 @@ void TableZone::reorganizeCards() qreal x = mapPoint.x(); qreal y = mapPoint.y(); - int numberAttachedCards = getLogic()->getCards()[i]->getAttachedCards().size(); + int numberAttachedCards = cards[i]->getState()->getAttachedCards().size(); qreal actualX = x + numberAttachedCards * STACKED_CARD_OFFSET_X; qreal actualY = y; if (numberAttachedCards) { actualY += 15; } - getLogic()->getCards()[i]->setPos(actualX, actualY); - getLogic()->getCards()[i]->setRealZValue(ZValues::tableCardZValue(actualX, actualY)); + cards[i]->setPos(actualX, actualY); + cards[i]->setRealZValue(ZValues::tableCardZValue(actualX, actualY)); - QListIterator attachedCardIterator(getLogic()->getCards()[i]->getAttachedCards()); + QListIterator attachedCardIterator(cards[i]->getState()->getAttachedCards()); int j = 0; while (attachedCardIterator.hasNext()) { ++j; - CardItem *attachedCard = attachedCardIterator.next(); + CardState *attachedState = attachedCardIterator.next(); + CardItem *attachedCard = getCardItemForId(attachedState->getId()); qreal childX = actualX - j * STACKED_CARD_OFFSET_X; qreal childY = y + 5; attachedCard->setPos(childX, childY); @@ -204,7 +205,7 @@ void TableZone::toggleTapped() auto isCardOnTable = [](const QGraphicsItem *item) { if (auto card = qgraphicsitem_cast(item)) { - return card->getZone()->getName() == ZoneNames::TABLE; + return card->getState()->getZone()->getName() == ZoneNames::TABLE; } return false; }; @@ -212,15 +213,15 @@ void TableZone::toggleTapped() std::copy_if(selectedItemsRaw.begin(), selectedItemsRaw.end(), std::back_inserter(selectedItems), isCardOnTable); bool tapAll = std::any_of(selectedItems.begin(), selectedItems.end(), [](const QGraphicsItem *item) { - return !qgraphicsitem_cast(item)->getTapped(); + return !qgraphicsitem_cast(item)->getState()->getTapped(); }); QList cmdList; for (const auto &selectedItem : selectedItems) { CardItem *temp = qgraphicsitem_cast(selectedItem); - if (temp->getTapped() != tapAll) { + if (temp->getState()->getTapped() != tapAll) { Command_SetCardAttr *cmd = new Command_SetCardAttr; cmd->set_zone(getLogic()->getName().toStdString()); - cmd->set_card_id(temp->getId()); + cmd->set_card_id(temp->getState()->getId()); cmd->set_attribute(AttrTapped); cmd->set_attr_value(tapAll ? "1" : "0"); cmdList.append(cmd); @@ -235,9 +236,9 @@ void TableZone::resizeToContents() int xMax = 0; // Find rightmost card position, which includes the left margin amount. - for (int i = 0; i < getLogic()->getCards().size(); ++i) { - if (getLogic()->getCards()[i]->pos().x() > xMax) { - xMax = (int)getLogic()->getCards()[i]->pos().x(); + for (int i = 0; i < cards.size(); ++i) { + if (cards[i]->pos().x() > xMax) { + xMax = (int)cards[i]->pos().x(); } } @@ -258,9 +259,9 @@ void TableZone::resizeToContents() CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const { - for (int i = 0; i < getLogic()->getCards().size(); i++) { - if (getLogic()->getCards().at(i)->getGridPoint() == gridPoint) { - return getLogic()->getCards().at(i); + for (int i = 0; i < cards.size(); i++) { + if (cards.at(i)->getState()->getGridPoint() == gridPoint) { + return cards.at(i); } } return 0; @@ -277,8 +278,8 @@ void TableZone::computeCardStackWidths() // Each card stack is three grid points worth of card locations. // First pass: compute the number of cards at each card stack. QMap cardStackCount; - for (int i = 0; i < getLogic()->getCards().size(); ++i) { - const QPoint &gridPoint = getLogic()->getCards()[i]->getGridPos(); + for (int i = 0; i < cards.size(); ++i) { + const QPoint &gridPoint = cards[i]->getState()->getGridPos(); if (gridPoint.x() == -1) { continue; } @@ -289,8 +290,8 @@ void TableZone::computeCardStackWidths() // Second pass: compute the width at each card stack. cardStackWidth.clear(); - for (int i = 0; i < getLogic()->getCards().size(); ++i) { - const QPoint &gridPoint = getLogic()->getCards()[i]->getGridPos(); + for (int i = 0; i < cards.size(); ++i) { + const QPoint &gridPoint = cards[i]->getState()->getGridPos(); if (gridPoint.x() == -1) { continue; } @@ -298,8 +299,8 @@ void TableZone::computeCardStackWidths() const int key = getCardStackMapKey(gridPoint.x() / 3, gridPoint.y()); const int stackCount = cardStackCount.value(key, 0); if (stackCount == 1) { - cardStackWidth.insert(key, CardDimensions::WIDTH + getLogic()->getCards()[i]->getAttachedCards().size() * - STACKED_CARD_OFFSET_X); + cardStackWidth.insert(key, CardDimensions::WIDTH + + cards[i]->getState()->getAttachedCards().size() * STACKED_CARD_OFFSET_X); } else { cardStackWidth.insert(key, CardDimensions::WIDTH + (stackCount - 1) * STACKED_CARD_OFFSET_X); } diff --git a/cockatrice/src/game_graphics/zones/view_zone.cpp b/cockatrice/src/game_graphics/zones/view_zone.cpp index baf7b8b30..f691d284d 100644 --- a/cockatrice/src/game_graphics/zones/view_zone.cpp +++ b/cockatrice/src/game_graphics/zones/view_zone.cpp @@ -68,7 +68,9 @@ void ZoneViewZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o void ZoneViewZone::initializeCards(const QList &cardList) { - int numberCards = qobject_cast(getLogic())->getNumberCards(); + // TODO + Q_UNUSED(cardList); + /*int numberCards = qobject_cast(getLogic())->getNumberCards(); if (!cardList.isEmpty()) { for (int i = 0; i < cardList.size(); ++i) { auto card = cardList[i]; @@ -100,12 +102,14 @@ void ZoneViewZone::initializeCards(const QList &cardLis getLogic()->addCard(copy, false, i); } reorganizeCards(); - } + }*/ } void ZoneViewZone::zoneDumpReceived(const Response &r) { - const Response_DumpZone &resp = r.GetExtension(Response_DumpZone::ext); + Q_UNUSED(r); + // TODO + /*const Response_DumpZone &resp = r.GetExtension(Response_DumpZone::ext); const int respCardListSize = resp.zone_info().card_list_size(); for (int i = 0; i < respCardListSize; ++i) { const ServerInfo_Card &cardInfo = resp.zone_info().card_list(i); @@ -117,7 +121,7 @@ void ZoneViewZone::zoneDumpReceived(const Response &r) } qobject_cast(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE); - reorganizeCards(); + reorganizeCards();*/ // clang-format off emit getLogic()->cardCountChanged(); // emit keyword causes spurious spacing around -> // clang-format on @@ -130,11 +134,11 @@ void ZoneViewZone::reorganizeCards() CardList cardsToDisplay = CardList(getLogic()->getCards().getContentsKnown()); for (auto card : getLogic()->getCards()) { if (filterString.check(card->getCard().getCardPtr())) { - card->show(); + // card->show(); cardsToDisplay.append(card); - } else { - card->hide(); - } + } /* else { + card->hide(); + }*/ } // sort cards @@ -199,7 +203,7 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca const auto extractor = CardList::getExtractorFor(pileOption); for (int i = 0; i < cardCount; i++) { - CardItem *c = cards.at(i); + CardState *c = cards.at(i); QString columnProp = extractor(c); if (i) { // if not the first card @@ -211,12 +215,12 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca } } - lastColumnProp = columnProp; + /* TODO lastColumnProp = columnProp; qreal x = col * CardDimensions::WIDTH_F; qreal y = row * CardDimensions::HEIGHT_F / 3; c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y); c->setRealZValue(i); - longestRow = qMax(row, longestRow); + longestRow = qMax(row, longestRow);*/ } // +1 because the row/col variables used in the calculations are 0-indexed but @@ -240,11 +244,12 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca qCDebug(ViewZoneLog) << "reorganizeCards: rows=" << rows << "cols=" << cols; for (int i = 0; i < cardCount; i++) { - CardItem *c = cards.at(i); + CardState *c = cards.at(i); qreal x = (i / rows) * CardDimensions::WIDTH_F; qreal y = (i % rows) * CardDimensions::HEIGHT_F / 3; - c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y); - c->setRealZValue(i); + CardItem *ci = getCardItemForId(c->getId()); + ci->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y); + ci->setRealZValue(i); } return GridSize{rows, qMax(cols, 1)}; diff --git a/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp index 577dafe0a..9e2f38006 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp @@ -65,7 +65,7 @@ void CardInfoDisplayWidget::setCard(const CardRef &cardRef) void CardInfoDisplayWidget::setCard(AbstractCardItem *card) { - setCard(card->getCard()); + setCard(card->getState()->getCard()); } void CardInfoDisplayWidget::clear() diff --git a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp index 2e7c62461..c69a05423 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp @@ -171,7 +171,7 @@ void CardInfoFrameWidget::setCard(const CardRef &cardRef) void CardInfoFrameWidget::setCard(AbstractCardItem *card) { if (card) { - setCard(card->getCard()); + setCard(card->getState()->getCard()); } } diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index a81161e83..d6cdd5c8f 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -658,7 +658,7 @@ PlayerLogic *TabGame::addPlayer(PlayerLogic *newPlayer) auto *view = scene->viewForPlayer(newPlayer->getPlayerInfo()->getId()); - connect(newPlayer, &PlayerLogic::newCardAdded, this, &TabGame::newCardAdded); + connect(view, &PlayerGraphicsItem::cardItemAdded, this, &TabGame::newCardAdded); connect(newPlayer, &PlayerLogic::openDeckEditor, this, &TabGame::openDeckEditor); connect(view->getPlayerMenu(), &PlayerMenu::cardMenuUpdated, this, &TabGame::setCardMenu); connect(view, &PlayerGraphicsItem::cardInfoRequested, this, &TabGame::viewCardInfo);