[Refactor] Retype card containers and zone logic onto CardState

This commit is contained in:
Lukas Brübach 2026-10-07 09:27:34 +02:00 • committed by GitHub
parent 893aeb7bae
commit f321132cce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 184 additions and 158 deletions

View file

@ -46,7 +46,7 @@ void AbstractGame::loadReplay(const GameReplay *replay)
gameMetaInfo->setSpectatorsOmniscient(true); gameMetaInfo->setSpectatorsOmniscient(true);
} }
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); PlayerLogic *player = playerManager->getPlayer(playerId);
if (!player) { if (!player) {

View file

@ -13,6 +13,7 @@
class CardItem; class CardItem;
class AbstractClient; class AbstractClient;
class CardState;
class GameEventHandler; class GameEventHandler;
class GameMetaInfo; class GameMetaInfo;
class GameReplay; class GameReplay;
@ -57,7 +58,7 @@ public:
void loadReplay(const GameReplay *replay); void loadReplay(const GameReplay *replay);
CardItem *getCard(int playerId, const QString &zoneName, int cardId) const; CardState *getCard(int playerId, const QString &zoneName, int cardId) const;
}; };
#endif // COCKATRICE_ABSTRACT_GAME_H #endif // COCKATRICE_ABSTRACT_GAME_H

View file

@ -1,7 +1,6 @@
#include "card_list.h" #include "card_list.h"
#include "../../game_graphics/board/card_item.h" #include "card_state.h"
#include "libcockatrice/card/printing/exact_card.h"
#include <QChar> #include <QChar>
#include <QDebug> #include <QDebug>
@ -11,26 +10,26 @@
#include <compare> #include <compare>
#include <libcockatrice/card/card_info.h> #include <libcockatrice/card/card_info.h>
CardList::CardList(bool _contentsKnown) : QList<CardItem *>(), contentsKnown(_contentsKnown) CardList::CardList(bool _contentsKnown) : QList<CardState *>(), contentsKnown(_contentsKnown)
{ {
} }
/** /**
* @brief Finds the CardItem with the given id in the list. * @brief Finds the CardState with the given id in the list.
* If contentsKnown is false, then this just returns the first element of the list. * If contentsKnown is false, then this just returns the first element of the list.
* *
* @param cardId The id of the card to find. * @param cardId The id of the card to find.
* *
* @returns A pointer to the CardItem, or a nullptr if not found. * @returns A pointer to the CardState, or a nullptr if not found.
*/ */
CardItem *CardList::findCard(const int cardId) const CardState *CardList::findCard(const int cardId) const
{ {
if (!contentsKnown && !empty()) { if (!contentsKnown && !empty()) {
return at(0); return at(0);
} else { } else {
for (auto *cardItem : *this) { for (auto *cardState : *this) {
if (cardItem->getId() == cardId) { if (cardState->getId() == cardId) {
return cardItem; return cardState;
} }
} }
} }
@ -38,7 +37,7 @@ CardItem *CardList::findCard(const int cardId) const
} }
/** /**
* @brief sorts the list by using string comparison on properties extracted from the CardItem * @brief sorts the list by using string comparison on properties extracted from the CardState
* The cards are compared using each property in order. * The cards are compared using each property in order.
* If two cards have the same value for a property, then the next property in the list is used. * If two cards have the same value for a property, then the next property in the list is used.
* *
@ -51,7 +50,7 @@ void CardList::sortBy(const QList<SortOption> &option)
return; return;
} }
auto comparator = [&option](CardItem *a, CardItem *b) { auto comparator = [&option](CardState *a, CardState *b) {
for (auto prop : option) { for (auto prop : option) {
auto extractor = getExtractorFor(prop); auto extractor = getExtractorFor(prop);
QString t1 = extractor(a); QString t1 = extractor(a);
@ -116,26 +115,26 @@ static QString getColorSortString(const CardInfo &c, bool appendAtEnd)
} }
/** /**
* @brief returns the function that extracts the given property from the CardItem. * @brief returns the function that extracts the given property from the CardState.
*/ */
std::function<QString(CardItem *)> CardList::getExtractorFor(SortOption option) std::function<QString(CardState *)> CardList::getExtractorFor(SortOption option)
{ {
switch (option) { switch (option) {
case NoSort: case NoSort:
return [](CardItem *) { return ""; }; return [](CardState *) { return ""; };
case SortByMainType: case SortByMainType:
return [](CardItem *c) { return c->getCardInfo().getMainCardType(); }; return [](CardState *c) { return c->getCardInfo().getMainCardType(); };
case SortByManaValue: case SortByManaValue:
// getCmc returns the int as a string. We pad with 0's so that string comp also works on it // 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: case SortByColorGrouping:
return [](CardItem *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), false) : ""; }; return [](CardState *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), false) : ""; };
case SortByName: case SortByName:
return [](CardItem *c) { return c->getName(); }; return [](CardState *c) { return c->getName(); };
case SortByType: case SortByType:
return [](CardItem *c) { return c->getCardInfo().getCardType(); }; return [](CardState *c) { return c->getCardInfo().getCardType(); };
case SortByManaCost: case SortByManaCost:
return [](CardItem *c) { return [](CardState *c) {
if (!c->getCard()) { if (!c->getCard()) {
return QString(); return QString();
} }
@ -147,18 +146,18 @@ std::function<QString(CardItem *)> CardList::getExtractorFor(SortOption option)
return QString("%1%2").arg(info.getCmc(), 4, QChar('0')).arg(info.getManaCost()); return QString("%1%2").arg(info.getCmc(), 4, QChar('0')).arg(info.getManaCost());
}; };
case SortByColors: case SortByColors:
return [](CardItem *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), true) : ""; }; return [](CardState *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), true) : ""; };
case SortByPt: case SortByPt:
// do the same padding trick as above // do the same padding trick as above
return 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: case SortBySet:
return [](CardItem *c) { return c->getCardInfo().getSetsNames(); }; return [](CardState *c) { return c->getCardInfo().getSetsNames(); };
case SortByPrinting: case SortByPrinting:
return [](CardItem *c) { return c->getProviderId(); }; return [](CardState *c) { return c->getProviderId(); };
} }
// this line should never be reached // this line should never be reached
qCWarning(CardListLog) << "cardlist.cpp: Could not find extractor for SortOption" << option; qCWarning(CardListLog) << "cardlist.cpp: Could not find extractor for SortOption" << option;
return [](CardItem *) { return ""; }; return [](CardState *) { return ""; };
} }

View file

@ -14,9 +14,9 @@
inline Q_LOGGING_CATEGORY(CardListLog, "card_list"); inline Q_LOGGING_CATEGORY(CardListLog, "card_list");
class CardItem; class CardState;
class CardList : public QList<CardItem *> class CardList : public QList<CardState *>
{ {
protected: protected:
bool contentsKnown; bool contentsKnown;
@ -43,7 +43,7 @@ public:
SortByPrinting SortByPrinting
}; };
explicit CardList(bool _contentsKnown); explicit CardList(bool _contentsKnown);
CardItem *findCard(const int cardId) const; CardState *findCard(const int cardId) const;
bool getContentsKnown() const bool getContentsKnown() const
{ {
return contentsKnown; return contentsKnown;
@ -51,7 +51,7 @@ public:
void sortBy(const QList<SortOption> &options); void sortBy(const QList<SortOption> &options);
static std::function<QString(CardItem *)> getExtractorFor(SortOption option); static std::function<QString(CardState *)> getExtractorFor(SortOption option);
}; };
#endif #endif

View file

@ -1614,7 +1614,9 @@ void PlayerActions::actIncrementAllCardCounters(QList<CardItem *> cardsToUpdate)
{ {
if (cardsToUpdate.isEmpty()) { if (cardsToUpdate.isEmpty()) {
// If no cards selected, update all cards on table // If no cards selected, update all cards on table
cardsToUpdate = static_cast<QList<CardItem *>>(player->getTableZone()->getCards()); for (auto *state : player->getTableZone()->getCards()) {
cardsToUpdate.append(qobject_cast<CardItem *>(state->parent()));
}
} }
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
@ -1687,7 +1689,7 @@ void PlayerActions::actHide(QList<CardItem *> selectedCards)
for (const auto &item : selectedCards) { for (const auto &item : selectedCards) {
auto *card = static_cast<CardItem *>(item); auto *card = static_cast<CardItem *>(item);
if (card && isUnwritableRevealZone(card->getZone())) { if (card && isUnwritableRevealZone(card->getZone())) {
card->getZone()->removeCard(card); card->getZone()->removeCard(card->getState());
} }
} }
} }

View file

@ -53,6 +53,11 @@
#include <qlogging.h> #include <qlogging.h>
#include <string> #include <string>
static CardItem *toCardItem(CardState *card)
{
return card == nullptr ? nullptr : qobject_cast<CardItem *>(card->parent());
}
PlayerEventHandler::PlayerEventHandler(PlayerLogic *_player) : QObject(_player), player(_player) PlayerEventHandler::PlayerEventHandler(PlayerLogic *_player) : QObject(_player), player(_player)
{ {
connect(this, &PlayerEventHandler::requestCardMenuUpdate, player, &PlayerLogic::requestCardMenuUpdate); connect(this, &PlayerEventHandler::requestCardMenuUpdate, player, &PlayerLogic::requestCardMenuUpdate);
@ -171,7 +176,7 @@ void PlayerEventHandler::eventCreateToken(const Event_CreateToken &event)
card->setFaceDown(event.face_down()); card->setFaceDown(event.face_down());
emit logCreateToken(player, card->getName(), card->getPT(), card->getFaceDown()); emit logCreateToken(player, card->getName(), card->getPT(), card->getFaceDown());
zone->addCard(card, true, event.x(), event.y()); zone->addCard(card->getState(), true, event.x(), event.y());
} }
void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event, void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event,
@ -193,7 +198,7 @@ void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event,
emit logSetTapped(player, nullptr, event.attr_value() == "1"); emit logSetTapped(player, nullptr, event.attr_value() == "1");
} }
} else { } else {
CardItem *card = zone->getCard(event.card_id()); CardState *card = zone->getCard(event.card_id());
if (!card) { if (!card) {
qWarning() << "PlayerEventHandler::eventSetCardAttr: card id=" << event.card_id() << "not found"; qWarning() << "PlayerEventHandler::eventSetCardAttr: card id=" << event.card_id() << "not found";
return; return;
@ -203,7 +208,7 @@ void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event,
} }
void PlayerEventHandler::setCardAttrHelper(const GameEventContext &context, void PlayerEventHandler::setCardAttrHelper(const GameEventContext &context,
CardItem *card, CardState *card,
CardAttribute attribute, CardAttribute attribute,
const QString &avalue, const QString &avalue,
bool allCards, bool allCards,
@ -264,14 +269,14 @@ void PlayerEventHandler::eventSetCardCounter(const Event_SetCardCounter &event)
return; return;
} }
CardItem *card = zone->getCard(event.card_id()); CardState *card = zone->getCard(event.card_id());
if (!card) { if (!card) {
return; return;
} }
int oldValue = card->getCounters().value(event.counter_id(), 0); int oldValue = card->getCounters().value(event.counter_id(), 0);
card->setCounter(event.counter_id(), event.counter_value()); card->setCounter(event.counter_id(), event.counter_value());
emit requestCardMenuUpdate(card); emit requestCardMenuUpdate(toCardItem(card));
emit logSetCardCounter(player, card->getName(), event.counter_id(), event.counter_value(), oldValue); emit logSetCardCounter(player, card->getName(), event.counter_id(), event.counter_value(), oldValue);
} }
@ -341,13 +346,13 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
if (x == -1) { if (x == -1) {
x = 0; 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) { if (card == nullptr) {
return; return;
} }
const bool zoneChanged = startZone != targetZone; const bool zoneChanged = startZone != targetZone;
const bool ownerChanged = zoneChanged && startZone->getPlayer() != targetZone->getPlayer(); const bool ownerChanged = zoneChanged && startZone->getPlayer() != targetZone->getPlayer();
emit cardViewRefreshRequested(card->getState(), zoneChanged, ownerChanged ? targetZone->getPlayer() : nullptr); emit cardViewRefreshRequested(card, zoneChanged, ownerChanged ? targetZone->getPlayer() : nullptr);
if (event.has_card_name()) { if (event.has_card_name()) {
QString name = QString::fromStdString(event.card_name()); QString name = QString::fromStdString(event.card_name());
QString providerId = QString providerId =
@ -366,7 +371,7 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
if (startZone != targetZone) { if (startZone != targetZone) {
const QList<CardItem *> &attachedCards = card->getAttachedCards(); const QList<CardItem *> &attachedCards = card->getAttachedCards();
for (auto attachedCard : attachedCards) { for (auto attachedCard : attachedCards) {
emit targetZone->cardAdded(attachedCard); emit targetZone->cardAdded(attachedCard->getState());
} }
} }
@ -380,12 +385,12 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
targetZone->addCard(card, true, x, y); targetZone->addCard(card, true, x, y);
emit cardZoneChanged(card, startZone == targetZone); emit cardZoneChanged(toCardItem(card), startZone == targetZone);
emit requestCardMenuUpdate(card); emit requestCardMenuUpdate(toCardItem(card));
if (player->getPlayerActions()->isMovingCardsUntil() && startZoneString == ZoneNames::DECK && if (player->getPlayerActions()->isMovingCardsUntil() && startZoneString == ZoneNames::DECK &&
targetZone->getName() == ZoneNames::STACK) { targetZone->getName() == ZoneNames::STACK) {
player->getPlayerActions()->moveOneCardUntil(card); player->getPlayerActions()->moveOneCardUntil(toCardItem(card));
} }
} }
@ -395,7 +400,7 @@ void PlayerEventHandler::eventFlipCard(const Event_FlipCard &event)
if (!zone) { if (!zone) {
return; return;
} }
CardItem *card = zone->getCard(event.card_id()); CardState *card = zone->getCard(event.card_id());
if (!card) { if (!card) {
return; return;
} }
@ -408,7 +413,7 @@ void PlayerEventHandler::eventFlipCard(const Event_FlipCard &event)
emit logFlipCard(player, card->getName(), event.face_down()); emit logFlipCard(player, card->getName(), event.face_down());
card->setFaceDown(event.face_down()); card->setFaceDown(event.face_down());
emit requestCardMenuUpdate(card); emit requestCardMenuUpdate(toCardItem(card));
} }
void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event) void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event)
@ -418,7 +423,7 @@ void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event)
return; return;
} }
CardItem *card = zone->getCard(event.card_id()); CardState *card = zone->getCard(event.card_id());
if (!card) { if (!card) {
return; return;
} }
@ -431,7 +436,7 @@ void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event)
emit logDestroyCard(player, card->getName()); emit logDestroyCard(player, card->getName());
zone->takeCard(-1, event.card_id(), true); zone->takeCard(-1, event.card_id(), true);
card->getState()->deleteView(); card->deleteView();
} }
void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event) void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
@ -439,7 +444,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
const QMap<int, PlayerLogic *> &playerList = player->getGame()->getPlayerManager()->getPlayers(); const QMap<int, PlayerLogic *> &playerList = player->getGame()->getPlayerManager()->getPlayers();
PlayerLogic *targetPlayer = nullptr; PlayerLogic *targetPlayer = nullptr;
CardZoneLogic *targetZone = nullptr; CardZoneLogic *targetZone = nullptr;
CardItem *targetCard = nullptr; CardState *targetCard = nullptr;
if (event.has_target_player_id()) { if (event.has_target_player_id()) {
targetPlayer = playerList.value(event.target_player_id(), 0); targetPlayer = playerList.value(event.target_player_id(), 0);
if (targetPlayer) { if (targetPlayer) {
@ -455,7 +460,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
return; return;
} }
CardItem *startCard = startZone->getCard(event.card_id()); CardState *startCard = startZone->getCard(event.card_id());
if (!startCard) { if (!startCard) {
return; return;
} }
@ -477,7 +482,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
} else { } else {
emit logUnattachCard(player, startCard->getName()); emit logUnattachCard(player, startCard->getName());
} }
emit requestCardMenuUpdate(startCard); emit requestCardMenuUpdate(toCardItem(startCard));
} }
void PlayerEventHandler::eventDrawCards(const Event_DrawCards &event) void PlayerEventHandler::eventDrawCards(const Event_DrawCards &event)
@ -489,7 +494,7 @@ void PlayerEventHandler::eventDrawCards(const Event_DrawCards &event)
if (listSize) { if (listSize) {
for (int i = 0; i < listSize; ++i) { for (int i = 0; i < listSize; ++i) {
const ServerInfo_Card &cardInfo = event.cards(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 cardName = QString::fromStdString(cardInfo.name());
QString providerId = QString::fromStdString(cardInfo.provider_id()); QString providerId = QString::fromStdString(cardInfo.provider_id());
card->setCardRef({cardName, providerId}); card->setCardRef({cardName, providerId});
@ -537,7 +542,7 @@ void PlayerEventHandler::eventRevealCards(const Event_RevealCards &event, EventP
for (const auto &card : cardList) { for (const auto &card : cardList) {
QString cardName = QString::fromStdString(card->name()); QString cardName = QString::fromStdString(card->name());
QString providerId = QString::fromStdString(card->provider_id()); QString providerId = QString::fromStdString(card->provider_id());
CardItem *cardItem = zone->getCard(card->id()); CardState *cardItem = zone->getCard(card->id());
if (!cardItem) { if (!cardItem) {
continue; continue;
} }

View file

@ -239,7 +239,7 @@ signals:
void logUndoDraw(PlayerLogic *player, QString cardName); void logUndoDraw(PlayerLogic *player, QString cardName);
void logUndoDrawFailed(PlayerLogic *player); void logUndoDrawFailed(PlayerLogic *player);
void logMoveCard(PlayerLogic *player, void logMoveCard(PlayerLogic *player,
CardItem *card, CardState *card,
CardZoneLogic *startZone, CardZoneLogic *startZone,
int oldX, int oldX,
CardZoneLogic *targetZone, CardZoneLogic *targetZone,
@ -249,11 +249,11 @@ signals:
void logAttachCard(PlayerLogic *player, QString cardName, PlayerLogic *targetPlayer, QString targetCardName); void logAttachCard(PlayerLogic *player, QString cardName, PlayerLogic *targetPlayer, QString targetCardName);
void logUnattachCard(PlayerLogic *player, QString cardName); void logUnattachCard(PlayerLogic *player, QString cardName);
void logSetCardCounter(PlayerLogic *player, QString cardName, int counterId, int value, int oldValue); 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 logSetCounter(PlayerLogic *player, QString counterName, int value, int oldValue);
void logSetDoesntUntap(PlayerLogic *player, CardItem *card, bool doesntUntap); void logSetDoesntUntap(PlayerLogic *player, CardState *card, bool doesntUntap);
void logSetPT(PlayerLogic *player, CardItem *card, QString newPT); void logSetPT(PlayerLogic *player, CardState *card, QString newPT);
void logSetAnnotation(PlayerLogic *player, CardItem *card, QString newAnnotation); void logSetAnnotation(PlayerLogic *player, CardState *card, QString newAnnotation);
void logDumpZone(PlayerLogic *player, CardZoneLogic *zone, int numberCards, bool isReversed = false); void logDumpZone(PlayerLogic *player, CardZoneLogic *zone, int numberCards, bool isReversed = false);
void logRevealCards(PlayerLogic *player, void logRevealCards(PlayerLogic *player,
CardZoneLogic *zone, CardZoneLogic *zone,
@ -283,7 +283,7 @@ private:
PlayerLogic *player; PlayerLogic *player;
void setCardAttrHelper(const GameEventContext &context, void setCardAttrHelper(const GameEventContext &context,
CardItem *card, CardState *card,
CardAttribute attribute, CardAttribute attribute,
const QString &avalue, const QString &avalue,
bool allCards, bool allCards,

View file

@ -172,7 +172,7 @@ void PlayerLogic::processPlayerInfo(const ServerInfo_Player &info)
const int cardListSize = zoneInfo.card_list_size(); const int cardListSize = zoneInfo.card_list_size();
if (!cardListSize) { if (!cardListSize) {
for (int j = 0; j < zoneInfo.card_count(); ++j) { for (int j = 0; j < zoneInfo.card_count(); ++j) {
zone->addCard(new CardItem(this), false, -1); zone->addCard((new CardItem(this))->getState(), false, -1);
} }
} else { } else {
for (int j = 0; j < cardListSize; ++j) { for (int j = 0; j < cardListSize; ++j) {
@ -184,9 +184,9 @@ void PlayerLogic::processPlayerInfo(const ServerInfo_Player &info)
// The x coordinate of such cards is always 0, so inserting at it // The x coordinate of such cards is always 0, so inserting at it
// would reverse the list on reconnect. Append instead. // would reverse the list on reconnect. Append instead.
if (zoneInfo.with_coords()) { if (zoneInfo.with_coords()) {
zone->addCard(card, false, cardInfo.x(), cardInfo.y()); zone->addCard(card->getState(), false, cardInfo.x(), cardInfo.y());
} else { } else {
zone->addCard(card, false, -1); zone->addCard(card->getState(), false, -1);
} }
} }
} }
@ -219,8 +219,8 @@ void PlayerLogic::processCardAttachment(const ServerInfo_Player &info)
for (int j = 0; j < cardListSize; ++j) { for (int j = 0; j < cardListSize; ++j) {
const ServerInfo_Card &cardInfo = zoneInfo.card_list(j); const ServerInfo_Card &cardInfo = zoneInfo.card_list(j);
if (cardInfo.has_attach_player_id()) { if (cardInfo.has_attach_player_id()) {
CardItem *startCard = zone->getCard(cardInfo.id()); CardState *startCard = zone->getCard(cardInfo.id());
CardItem *targetCard = CardState *targetCard =
game->getCard(cardInfo.attach_player_id(), QString::fromStdString(cardInfo.attach_zone()), game->getCard(cardInfo.attach_player_id(), QString::fromStdString(cardInfo.attach_zone()),
cardInfo.attach_card_id()); cardInfo.attach_card_id());
if (!targetCard) { if (!targetCard) {
@ -244,14 +244,14 @@ void PlayerLogic::addCard(CardItem *card)
emit newCardAdded(card); emit newCardAdded(card);
} }
void PlayerLogic::deleteCard(CardItem *card) void PlayerLogic::deleteCard(CardState *card)
{ {
if (card == nullptr) { if (card == nullptr) {
return; return;
} else if (dialogSemaphore) { } else if (dialogSemaphore) {
cardsToDelete.append(card); cardsToDelete.append(card);
} else { } else {
card->getState()->deleteView(); card->deleteView();
} }
} }
@ -332,7 +332,7 @@ bool PlayerLogic::clearCardsToDelete()
for (auto &i : cardsToDelete) { for (auto &i : cardsToDelete) {
if (i != nullptr) { if (i != nullptr) {
i->getState()->deleteView(); i->deleteView();
} }
} }
cardsToDelete.clear(); cardsToDelete.clear();

View file

@ -104,7 +104,7 @@ public:
void processCardAttachment(const ServerInfo_Player &info); void processCardAttachment(const ServerInfo_Player &info);
void addCard(CardItem *c); void addCard(CardItem *c);
void deleteCard(CardItem *c); void deleteCard(CardState *c);
bool clearCardsToDelete(); bool clearCardsToDelete();
@ -256,7 +256,7 @@ private:
QMap<int, CounterState *> counters; QMap<int, CounterState *> counters;
bool dialogSemaphore; bool dialogSemaphore;
QList<CardItem *> cardsToDelete; QList<CardState *> cardsToDelete;
// Playmat from player properties (for opponent display) // Playmat from player properties (for opponent display)
CardRef remotePlaymatCard; CardRef remotePlaymatCard;

View file

@ -41,7 +41,7 @@ CardZoneLogic::CardZoneLogic(PlayerLogic *_player,
&CardZoneLogic::refreshCardInfos); &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) { if (!card) {
qCWarning(CardZoneLogicLog) << "CardZoneLogic::addCard() card is null; this shouldn't normally happen"; qCWarning(CardZoneLogicLog) << "CardZoneLogic::addCard() card is null; this shouldn't normally happen";
@ -53,7 +53,7 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x,
auto copy = new CardItem(player, nullptr, card->getCardRef(), card->getId()); auto copy = new CardItem(player, nullptr, card->getCardRef(), card->getId());
copy->setFaceDown(card->getFaceDown()); copy->setFaceDown(card->getFaceDown());
viewLogic->addCard(copy, reorganize, x, y); viewLogic->addCard(copy->getState(), reorganize, x, y);
} }
} }
@ -68,7 +68,7 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x,
emit cardCountChanged(); emit cardCountChanged();
} }
CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone) CardState *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
{ {
if (position == -1) { if (position == -1) {
// position == -1 means either that the zone is indexed by card id // position == -1 means either that the zone is indexed by card id
@ -91,7 +91,7 @@ CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
viewLogic->removeCard(position, toNewZone); viewLogic->removeCard(position, toNewZone);
} }
CardItem *c = cards.takeAt(position); CardState *c = cards.takeAt(position);
c->setId(cardId); c->setId(cardId);
@ -100,9 +100,9 @@ CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
return c; return c;
} }
CardItem *CardZoneLogic::getCard(int cardId) CardState *CardZoneLogic::getCard(int cardId)
{ {
CardItem *c = cards.findCard(cardId); CardState *c = cards.findCard(cardId);
if (!c) { if (!c) {
qCWarning(CardZoneLogicLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found"; qCWarning(CardZoneLogicLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found";
return nullptr; return nullptr;
@ -116,7 +116,7 @@ CardItem *CardZoneLogic::getCard(int cardId)
return c; return c;
} }
void CardZoneLogic::removeCard(CardItem *card) void CardZoneLogic::removeCard(CardState *card)
{ {
if (!card) { if (!card) {
qCWarning(CardZoneLogicLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen"; qCWarning(CardZoneLogicLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen";
@ -132,8 +132,8 @@ void CardZoneLogic::removeCard(CardItem *card)
void CardZoneLogic::refreshCardInfos() void CardZoneLogic::refreshCardInfos()
{ {
for (const auto &cardItem : cards) { for (const auto &cardState : cards) {
cardItem->refreshCardInfo(); cardState->refreshCardInfo();
} }
} }
@ -165,17 +165,17 @@ void CardZoneLogic::clearContents()
const CardList toClear = cards; const CardList toClear = cards;
// Detach and notify attached cards and zones *before* deleting anything. // 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 // 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. // player, we have to return them to avoid a crash.
const QList<CardItem *> &attachedCards = card->getAttachedCards(); const QList<CardItem *> &attachedCards = card->getAttachedCards();
for (CardItem *attachedCard : attachedCards) { for (CardItem *attachedCard : attachedCards) {
emit attachedCard->getZone()->cardAdded(attachedCard); emit attachedCard->getZone()->cardAdded(attachedCard->getState());
} }
} }
// Now request deletions after all manipulations are done. // Now request deletions after all manipulations are done.
for (CardItem *card : toClear) { for (CardState *card : toClear) {
player->deleteCard(card); player->deleteCard(card);
} }

View file

@ -32,7 +32,7 @@ class CardZoneLogic : public QObject
Q_OBJECT Q_OBJECT
signals: signals:
void cardAdded(CardItem *addedCard); void cardAdded(CardState *addedCard);
void cardCountChanged(); void cardCountChanged();
void reorganizeCards(); void reorganizeCards();
void updateGraphics(); void updateGraphics();
@ -47,14 +47,14 @@ public:
bool _contentsKnown, bool _contentsKnown,
QObject *parent = nullptr); 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. // getCard() finds a card by id.
CardItem *getCard(int cardId); CardState *getCard(int cardId);
void removeCard(CardItem *card); void removeCard(CardState *card);
// takeCard() finds a card by position and removes it from the zone and from all of its views. // 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); cards.insert(index, card);
emit cardCountChanged(); emit cardCountChanged();
@ -120,7 +120,7 @@ protected:
bool isShufflable; bool isShufflable;
bool alwaysRevealTopCard; 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 #endif // COCKATRICE_CARD_ZONE_LOGIC_H

View file

@ -1,6 +1,6 @@
#include "hand_zone_logic.h" #include "hand_zone_logic.h"
#include "../../game_graphics/board/card_item.h" #include "../board/card_state.h"
#include "card_zone_algorithms.h" #include "card_zone_algorithms.h"
class PlayerLogic; class PlayerLogic;
@ -16,7 +16,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); CardZoneAlgorithms::addCardToList(cards, card, x, false);
} }

View file

@ -26,7 +26,7 @@ public:
QObject *parent = nullptr); QObject *parent = nullptr);
protected: 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 #endif // COCKATRICE_HAND_ZONE_LOGIC_H

View file

@ -1,7 +1,7 @@
#include "pile_zone_logic.h" #include "pile_zone_logic.h"
#include "../../game_graphics/board/card_item.h"
#include "../board/card_list.h" #include "../board/card_list.h"
#include "../board/card_state.h"
class PlayerLogic; class PlayerLogic;
class QObject; class QObject;
@ -16,9 +16,9 @@ PileZoneLogic::PileZoneLogic(PlayerLogic *_player,
{ {
} }
void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) void PileZoneLogic::addCardImpl(CardState *card, int x, int /*y*/)
{ {
connect(card->getState(), &CardState::cardPixmapUpdated, this, &PileZoneLogic::callUpdate); connect(card, &CardState::cardPixmapUpdated, this, &PileZoneLogic::callUpdate);
// if x is negative set it to add at end // if x is negative set it to add at end
if (x < 0 || x >= cards.size()) { if (x < 0 || x >= cards.size()) {
x = cards.size(); x = cards.size();
@ -32,5 +32,5 @@ void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
cards.at(x + 1)->setCardRef({}); cards.at(x + 1)->setCardRef({});
} }
} }
card->resetState(); card->resetState(false);
} }

View file

@ -31,7 +31,7 @@ public:
QObject *parent = nullptr); QObject *parent = nullptr);
protected: 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 #endif // COCKATRICE_PILE_ZONE_LOGIC_H

View file

@ -1,6 +1,6 @@
#include "stack_zone_logic.h" #include "stack_zone_logic.h"
#include "../../game_graphics/board/card_item.h" #include "../board/card_state.h"
#include "card_zone_algorithms.h" #include "card_zone_algorithms.h"
class PlayerLogic; class PlayerLogic;
@ -16,7 +16,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); CardZoneAlgorithms::addCardToList(cards, card, x, true);
} }

View file

@ -26,7 +26,7 @@ public:
QObject *parent = nullptr); QObject *parent = nullptr);
protected: 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 #endif // COCKATRICE_STACK_ZONE_LOGIC_H

View file

@ -1,7 +1,7 @@
#include "table_zone_logic.h" #include "table_zone_logic.h"
#include "../../game_graphics/board/card_item.h"
#include "../board/card_list.h" #include "../board/card_list.h"
#include "../board/card_state.h"
#include "libcockatrice/card/card_info.h" #include "libcockatrice/card/card_info.h"
#include <QPoint> #include <QPoint>
@ -19,7 +19,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); cards.append(card);
if (!card->getFaceDown() && card->getPT().isEmpty()) { if (!card->getFaceDown() && card->getPT().isEmpty()) {
@ -31,9 +31,9 @@ void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _y)
card->setGridPoint(QPoint(_x, _y)); card->setGridPoint(QPoint(_x, _y));
} }
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) { if (toNewZone) {
emit contentSizeChanged(); emit contentSizeChanged();

View file

@ -45,7 +45,7 @@ public:
static int tableRowToGridY(int tableRow); static int tableRowToGridY(int tableRow);
protected: 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. * @brief Removes a card from view.
@ -53,9 +53,9 @@ protected:
* @param position card position * @param position card position
* @param cardId id of card to take * @param cardId id of card to take
* @param toNewZone Whether the destination of the card is not the same as the starting zone. Defaults to true * @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 * @return CardState 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 #endif // COCKATRICE_TABLE_ZONE_LOGIC_H

View file

@ -1,10 +1,8 @@
#include "view_zone_logic.h" #include "view_zone_logic.h"
#include "../../client/settings/cache_settings.h" #include "../../client/settings/cache_settings.h"
#include "../../game_graphics/board/card_item.h"
#include "../board/card_list.h" #include "../board/card_list.h"
#include "../player/player_actions.h" #include "../board/card_state.h"
#include "../player/player_logic.h"
#include <QtGlobal> #include <QtGlobal>
#include <libcockatrice/settings/interface_settings.h> #include <libcockatrice/settings/interface_settings.h>
@ -77,7 +75,7 @@ bool ZoneViewZoneLogic::prepareAddCard(int x)
* Make sure prepareAddCard() was called before calling addCard(). * Make sure prepareAddCard() was called before calling addCard().
* This method assumes we already checked that the card is being inserted into the visible portion * 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 (!isReversed) {
// if x is negative set it to add at end // if x is negative set it to add at end
@ -146,8 +144,8 @@ void ZoneViewZoneLogic::removeCard(int position, bool toNewZone)
return; return;
} }
CardItem *card = cards.takeAt(position); CardState *card = cards.takeAt(position);
card->getState()->deleteView(); card->deleteView();
// The toNewZone check is to prevent the view from auto-closing if the view contains only a single card and that // The toNewZone check is to prevent the view from auto-closing if the view contains only a single card and that
// card gets dragged within the view. // card gets dragged within the view.
@ -170,7 +168,7 @@ void ZoneViewZoneLogic::requestClose()
void ZoneViewZoneLogic::clearCards() void ZoneViewZoneLogic::clearCards()
{ {
for (auto card : cards) { for (auto card : cards) {
card->getState()->deleteView(); card->deleteView();
} }
cards.clear(); cards.clear();
emit cardCountChanged(); emit cardCountChanged();

View file

@ -92,7 +92,7 @@ public:
PendingCommand *requestZoneDump(); PendingCommand *requestZoneDump();
protected: 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 #endif // COCKATRICE_VIEW_ZONE_LOGIC_H

View file

@ -233,7 +233,7 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
if (state->getAttachedTo()->getZone() == nullptr) { if (state->getAttachedTo()->getZone() == nullptr) {
deleteLater(); deleteLater();
} else { } else {
emit state->getAttachedTo()->getZone()->cardAdded(this); emit state->getAttachedTo()->getZone()->cardAdded(state);
state->getAttachedTo()->addAttachedCard(this); state->getAttachedTo()->addAttachedCard(this);
if (state->getZone() != state->getAttachedTo()->getZone()) { if (state->getZone() != state->getAttachedTo()->getZone()) {
state->getAttachedTo()->getZone()->reorganizeCards(); state->getAttachedTo()->getZone()->reorganizeCards();
@ -245,7 +245,7 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
if (state->getZone() == nullptr) { if (state->getZone() == nullptr) {
deleteLater(); deleteLater();
} else { } else {
emit state->getZone()->cardAdded(this); emit state->getZone()->cardAdded(state);
} }
} }
@ -467,7 +467,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld)
if (SettingsCache::instance().userInterface().getClickPlaysAllSelected()) { if (SettingsCache::instance().userInterface().getClickPlaysAllSelected()) {
emit hideSelected(this); emit hideSelected(this);
} else { } else {
state->getZone()->removeCard(this); state->getZone()->removeCard(state);
} }
} else { } else {
playCard(shiftHeld); playCard(shiftHeld);

View file

@ -137,7 +137,8 @@ static void selectCardsInZone(
return; return;
} }
for (auto &cardItem : zone->getCards()) { for (auto *cardState : zone->getCards()) {
auto *cardItem = cardState == nullptr ? nullptr : qobject_cast<CardItem *>(cardState->parent());
if (cardItem && filter(cardItem)) { if (cardItem && filter(cardItem)) {
cardItem->setSelected(true); cardItem->setSelected(true);
} }
@ -596,7 +597,11 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
return; return;
} }
CardItem *startCard = startZone->getCard(data->startCardId); CardState *startCardState = startZone->getCard(data->startCardId);
if (!startCardState) {
return;
}
CardItem *startCard = qobject_cast<CardItem *>(startCardState->parent());
if (!startCard) { if (!startCard) {
return; return;
} }
@ -607,7 +612,8 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
} else { } else {
auto *zone = targetView->getLogic()->getZones().value(data->targetZone); auto *zone = targetView->getLogic()->getZones().value(data->targetZone);
if (zone) { if (zone) {
targetItem = zone->getCard(data->targetCardId); CardState *targetCardState = zone->getCard(data->targetCardId);
targetItem = targetCardState == nullptr ? nullptr : qobject_cast<CardItem *>(targetCardState->parent());
} }
} }
if (!targetItem) { if (!targetItem) {

View file

@ -283,7 +283,7 @@ void MessageLogWidget::logDestroyCard(PlayerLogic *player, QString cardName)
} }
void MessageLogWidget::logMoveCard(PlayerLogic *player, void MessageLogWidget::logMoveCard(PlayerLogic *player,
CardItem *card, CardState *card,
CardZoneLogic *startZone, CardZoneLogic *startZone,
int oldX, int oldX,
CardZoneLogic *targetZone, CardZoneLogic *targetZone,
@ -662,7 +662,7 @@ void MessageLogWidget::logSetActivePlayer(PlayerLogic *player)
QString(tr("%1's turn.")).arg(player->getPlayerInfo()->getName()) + "</b></font><br>"); QString(tr("%1's turn.")).arg(player->getPlayerInfo()->getName()) + "</b></font><br>");
} }
void MessageLogWidget::logSetAnnotation(PlayerLogic *player, CardItem *card, QString newAnnotation) void MessageLogWidget::logSetAnnotation(PlayerLogic *player, CardState *card, QString newAnnotation)
{ {
appendHtmlServerMessage( appendHtmlServerMessage(
QString(tr("%1 sets annotation of %2 to %3.")) QString(tr("%1 sets annotation of %2 to %3."))
@ -706,7 +706,7 @@ void MessageLogWidget::logSetCounter(PlayerLogic *player, QString counterName, i
.arg(value - oldValue)); .arg(value - oldValue));
} }
void MessageLogWidget::logSetDoesntUntap(PlayerLogic *player, CardItem *card, bool doesntUntap) void MessageLogWidget::logSetDoesntUntap(PlayerLogic *player, CardState *card, bool doesntUntap)
{ {
QString str; QString str;
if (doesntUntap) { if (doesntUntap) {
@ -717,7 +717,7 @@ void MessageLogWidget::logSetDoesntUntap(PlayerLogic *player, CardItem *card, bo
appendHtmlServerMessage(str.arg(sanitizeHtml(player->getPlayerInfo()->getName())).arg(cardLink(card->getName()))); 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) { if (currentContext == MessageContext_MoveCard) {
return; return;
@ -755,7 +755,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) { if (currentContext == MessageContext_MoveCard) {
return; return;

View file

@ -14,6 +14,7 @@
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <sys/types.h> #include <sys/types.h>
class CardState;
class AbstractGame; class AbstractGame;
class CardItem; class CardItem;
class GameEventContext; class GameEventContext;
@ -76,7 +77,7 @@ public slots:
void logLeaveSpectator(QString name, QString reason); void logLeaveSpectator(QString name, QString reason);
void logNotReadyStart(PlayerLogic *player); void logNotReadyStart(PlayerLogic *player);
void logMoveCard(PlayerLogic *player, void logMoveCard(PlayerLogic *player,
CardItem *card, CardState *card,
CardZoneLogic *startZone, CardZoneLogic *startZone,
int oldX, int oldX,
CardZoneLogic *targetZone, CardZoneLogic *targetZone,
@ -97,13 +98,13 @@ public slots:
void logSay(PlayerLogic *player, QString message); void logSay(PlayerLogic *player, QString message);
void logSetActivePhase(int phase); void logSetActivePhase(int phase);
void logSetActivePlayer(PlayerLogic *player); 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 logSetCardCounter(PlayerLogic *player, QString cardName, int counterId, int value, int oldValue);
void logSetCounter(PlayerLogic *player, QString counterName, int value, int oldValue); void logSetCounter(PlayerLogic *player, QString counterName, int value, int oldValue);
void logSetDoesntUntap(PlayerLogic *player, CardItem *card, bool doesntUntap); void logSetDoesntUntap(PlayerLogic *player, CardState *card, bool doesntUntap);
void logSetPT(PlayerLogic *player, CardItem *card, QString newPT); void logSetPT(PlayerLogic *player, CardState *card, QString newPT);
void logSetSideboardLock(PlayerLogic *player, bool locked); 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 logShuffle(PlayerLogic *player, CardZoneLogic *zone, int start, int end);
void logSpectatorSay(const ServerInfo_User &spectator, QString message); void logSpectatorSay(const ServerInfo_User &spectator, QString message);
void logUnattachCard(PlayerLogic *player, QString cardName); void logUnattachCard(PlayerLogic *player, QString cardName);

View file

@ -37,17 +37,26 @@ void CardZone::invalidateItems()
const QList<CardItem *> &CardZone::cardItems() const const QList<CardItem *> &CardZone::cardItems() const
{ {
if (itemsDirty) { if (itemsDirty) {
items = getLogic()->getCards(); items.clear();
for (auto *cardState : getLogic()->getCards()) {
if (auto *cardItem = qobject_cast<CardItem *>(cardState->parent())) {
items.append(cardItem);
}
}
itemsDirty = false; itemsDirty = false;
} }
return items; return items;
} }
void CardZone::onCardAdded(CardItem *addedCard) void CardZone::onCardAdded(CardState *addedCard)
{ {
addedCard->setParentItem(this); auto *addedItem = addedCard == nullptr ? nullptr : qobject_cast<CardItem *>(addedCard->parent());
addedCard->setVisible(true); if (addedItem == nullptr) {
addedCard->update(); return;
}
addedItem->setParentItem(this);
addedItem->setVisible(true);
addedItem->update();
} }
void CardZone::retranslateUi() void CardZone::retranslateUi()

View file

@ -23,6 +23,8 @@ class QMenu;
class QPoint; class QPoint;
template <typename T> class QList; template <typename T> class QList;
class CardItem;
inline Q_LOGGING_CATEGORY(CardZoneLog, "card_zone"); inline Q_LOGGING_CATEGORY(CardZoneLog, "card_zone");
/** /**
@ -55,7 +57,7 @@ public slots:
* Virtual so subclasses (e.g. SelectZone) can override parenting behavior — the Qt signal * Virtual so subclasses (e.g. SelectZone) can override parenting behavior — the Qt signal
* connection in CardZone's constructor dispatches through the vtable. * connection in CardZone's constructor dispatches through the vtable.
*/ */
virtual void onCardAdded(CardItem *addedCard); virtual void onCardAdded(CardState *addedCard);
public: public:
enum enum

View file

@ -87,12 +87,13 @@ void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneL
getLogic()->getPlayer()->getPlayerActions()->moveCards(startZone, getLogic(), 0, 0, cards); getLogic()->getPlayer()->getPlayerActions()->moveCards(startZone, getLogic(), 0, 0, cards);
} }
void PileZone::onCardAdded(CardItem *addedCard) void PileZone::onCardAdded(CardState *addedCard)
{ {
CardZone::onCardAdded(addedCard); CardZone::onCardAdded(addedCard);
if (addedCard) { auto *addedItem = addedCard == nullptr ? nullptr : qobject_cast<CardItem *>(addedCard->parent());
addedCard->setPos(0, 0); if (addedItem) {
addedCard->setVisible(false); addedItem->setPos(0, 0);
addedItem->setVisible(false);
} }
} }

View file

@ -33,7 +33,7 @@ public:
[[nodiscard]] QPainterPath shape() const override; [[nodiscard]] QPainterPath shape() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void reorganizeCards() override; void reorganizeCards() override;
void onCardAdded(CardItem *addedCard) override; void onCardAdded(CardState *addedCard) override;
void void
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override; handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;

View file

@ -172,12 +172,13 @@ SelectZone::~SelectZone()
} }
} }
void SelectZone::onCardAdded(CardItem *addedCard) void SelectZone::onCardAdded(CardState *addedCard)
{ {
if (cardClipContainer && addedCard) { auto *addedItem = addedCard == nullptr ? nullptr : qobject_cast<CardItem *>(addedCard->parent());
addedCard->setParentItem(cardClipContainer); if (cardClipContainer && addedItem) {
addedCard->setVisible(true); addedItem->setParentItem(cardClipContainer);
addedCard->update(); addedItem->setVisible(true);
addedItem->update();
} else { } else {
CardZone::onCardAdded(addedCard); CardZone::onCardAdded(addedCard);
} }

View file

@ -35,7 +35,7 @@ public:
SelectZone(CardZoneLogic *logic, QGraphicsItem *parent = nullptr); SelectZone(CardZoneLogic *logic, QGraphicsItem *parent = nullptr);
~SelectZone() override; ~SelectZone() override;
void onCardAdded(CardItem *addedCard) override; void onCardAdded(CardState *addedCard) override;
/** /**
* @brief Temporarily reparents a card from the clip container to this zone so hover scaling is visible beyond clip * @brief Temporarily reparents a card from the clip container to this zone so hover scaling is visible beyond clip

View file

@ -95,7 +95,7 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
auto copy = new CardItem(getLogic()->getPlayer(), this, cardRef, card->id()); auto copy = new CardItem(getLogic()->getPlayer(), this, cardRef, card->id());
copy->setFaceDown(card->face_down()); copy->setFaceDown(card->face_down());
getLogic()->addCard(copy, false, i); getLogic()->addCard(copy->getState(), false, i);
} }
reorganizeCards(); reorganizeCards();
} else if (!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->contentsKnown()) { } else if (!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->contentsKnown()) {
@ -107,11 +107,11 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
const CardList &c = qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getCards(); const CardList &c = qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getCards();
int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size()); int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size());
for (int i = 0; i < number; i++) { for (int i = 0; i < number; i++) {
CardItem *card = c.at(i); CardState *card = c.at(i);
auto copy = new CardItem(getLogic()->getPlayer(), this, card->getCardRef(), card->getId()); auto copy = new CardItem(getLogic()->getPlayer(), this, card->getCardRef(), card->getId());
copy->setFaceDown(card->getFaceDown()); copy->setFaceDown(card->getFaceDown());
getLogic()->addCard(copy, false, i); getLogic()->addCard(copy->getState(), false, i);
} }
reorganizeCards(); reorganizeCards();
} }
@ -127,7 +127,7 @@ void ZoneViewZone::zoneDumpReceived(const Response &r)
auto cardProviderId = QString::fromStdString(cardInfo.provider_id()); auto cardProviderId = QString::fromStdString(cardInfo.provider_id());
auto card = new CardItem(getLogic()->getPlayer(), this, {cardName, cardProviderId}, cardInfo.id(), getLogic()); auto card = new CardItem(getLogic()->getPlayer(), this, {cardName, cardProviderId}, cardInfo.id(), getLogic());
card->setFaceDown(cardInfo.face_down()); card->setFaceDown(cardInfo.face_down());
getLogic()->rawInsertCard(card, i); getLogic()->rawInsertCard(card->getState(), i);
} }
qobject_cast<ZoneViewZoneLogic *>(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE); qobject_cast<ZoneViewZoneLogic *>(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE);
@ -145,7 +145,7 @@ void ZoneViewZone::reorganizeCards()
for (auto card : cardItems()) { for (auto card : cardItems()) {
if (filterString.check(card->getCard().getCardPtr())) { if (filterString.check(card->getCard().getCardPtr())) {
card->show(); card->show();
cardsToDisplay.append(card); cardsToDisplay.append(card->getState());
} else { } else {
card->hide(); card->hide();
} }
@ -213,7 +213,8 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
const auto extractor = CardList::getExtractorFor(pileOption); const auto extractor = CardList::getExtractorFor(pileOption);
for (int i = 0; i < cardCount; i++) { for (int i = 0; i < cardCount; i++) {
CardItem *c = cards.at(i); CardState *c = cards.at(i);
CardItem *cItem = qobject_cast<CardItem *>(c->parent());
QString columnProp = extractor(c); QString columnProp = extractor(c);
if (i) { // if not the first card if (i) { // if not the first card
@ -228,8 +229,8 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
lastColumnProp = columnProp; lastColumnProp = columnProp;
qreal x = col * CardDimensions::WIDTH_F; qreal x = col * CardDimensions::WIDTH_F;
qreal y = row * CardDimensions::HEIGHT_F / 3; qreal y = row * CardDimensions::HEIGHT_F / 3;
c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y); cItem->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
c->setRealZValue(i); cItem->setRealZValue(i);
longestRow = qMax(row, longestRow); longestRow = qMax(row, longestRow);
} }
@ -254,11 +255,11 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
qCDebug(ViewZoneLog) << "reorganizeCards: rows=" << rows << "cols=" << cols; qCDebug(ViewZoneLog) << "reorganizeCards: rows=" << rows << "cols=" << cols;
for (int i = 0; i < cardCount; i++) { for (int i = 0; i < cardCount; i++) {
CardItem *c = cards.at(i); auto *cItem = qobject_cast<CardItem *>(cards.at(i)->parent());
qreal x = (i / rows) * CardDimensions::WIDTH_F; qreal x = (i / rows) * CardDimensions::WIDTH_F;
qreal y = (i % rows) * CardDimensions::HEIGHT_F / 3; qreal y = (i % rows) * CardDimensions::HEIGHT_F / 3;
c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y); cItem->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
c->setRealZValue(i); cItem->setRealZValue(i);
} }
return GridSize{rows, qMax(cols, 1)}; return GridSize{rows, qMax(cols, 1)};