mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 01:23:24 -08:00
[Refactor] Retype card containers and zone logic onto CardState (#7434)
* [Refactor] Retype card containers and zone logic onto CardState * [Game] Restore attach bookkeeping via CardItem and repaint on state change * [Refactor] Give custom zones a hidden graphics owner Custom PileZoneLogic zones had no CardZone, so moving a card into one left the CardItem drawn at its old spot. Create a hidden PileZone in onCustomZoneAdded so cards are reparented and hidden. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
5d0d466930
commit
65e9f1b370
33 changed files with 232 additions and 159 deletions
|
|
@ -46,7 +46,7 @@ void AbstractGame::loadReplay(const GameReplay *replay)
|
|||
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);
|
||||
if (!player) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
class CardItem;
|
||||
class AbstractClient;
|
||||
class CardState;
|
||||
class GameEventHandler;
|
||||
class GameMetaInfo;
|
||||
class GameReplay;
|
||||
|
|
@ -57,7 +58,7 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "card_list.h"
|
||||
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
#include "libcockatrice/card/printing/exact_card.h"
|
||||
#include "card_state.h"
|
||||
|
||||
#include <QChar>
|
||||
#include <QDebug>
|
||||
|
|
@ -11,26 +10,26 @@
|
|||
#include <compare>
|
||||
#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.
|
||||
*
|
||||
* @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()) {
|
||||
return at(0);
|
||||
} else {
|
||||
for (auto *cardItem : *this) {
|
||||
if (cardItem->getId() == cardId) {
|
||||
return cardItem;
|
||||
for (auto *cardState : *this) {
|
||||
if (cardState->getId() == cardId) {
|
||||
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.
|
||||
* 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -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) {
|
||||
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();
|
||||
}
|
||||
|
|
@ -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());
|
||||
};
|
||||
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 ""; };
|
||||
}
|
||||
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
inline Q_LOGGING_CATEGORY(CardListLog, "card_list");
|
||||
|
||||
class CardItem;
|
||||
class CardState;
|
||||
|
||||
class CardList : public QList<CardItem *>
|
||||
class CardList : public QList<CardState *>
|
||||
{
|
||||
protected:
|
||||
bool contentsKnown;
|
||||
|
|
@ -43,7 +43,7 @@ public:
|
|||
SortByPrinting
|
||||
};
|
||||
explicit CardList(bool _contentsKnown);
|
||||
CardItem *findCard(const int cardId) const;
|
||||
CardState *findCard(const int cardId) const;
|
||||
bool getContentsKnown() const
|
||||
{
|
||||
return contentsKnown;
|
||||
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
void sortBy(const QList<SortOption> &options);
|
||||
|
||||
static std::function<QString(CardItem *)> getExtractorFor(SortOption option);
|
||||
static std::function<QString(CardState *)> getExtractorFor(SortOption option);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1614,7 +1614,9 @@ void PlayerActions::actIncrementAllCardCounters(QList<CardItem *> cardsToUpdate)
|
|||
{
|
||||
if (cardsToUpdate.isEmpty()) {
|
||||
// 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;
|
||||
|
|
@ -1687,7 +1689,7 @@ void PlayerActions::actHide(QList<CardItem *> selectedCards)
|
|||
for (const auto &item : selectedCards) {
|
||||
auto *card = static_cast<CardItem *>(item);
|
||||
if (card && isUnwritableRevealZone(card->getZone())) {
|
||||
card->getZone()->removeCard(card);
|
||||
card->getZone()->removeCard(card->getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@
|
|||
#include <qlogging.h>
|
||||
#include <string>
|
||||
|
||||
static CardItem *toCardItem(CardState *card)
|
||||
{
|
||||
return card == nullptr ? nullptr : qobject_cast<CardItem *>(card->parent());
|
||||
}
|
||||
|
||||
PlayerEventHandler::PlayerEventHandler(PlayerLogic *_player) : QObject(_player), player(_player)
|
||||
{
|
||||
connect(this, &PlayerEventHandler::requestCardMenuUpdate, player, &PlayerLogic::requestCardMenuUpdate);
|
||||
|
|
@ -171,7 +176,7 @@ void PlayerEventHandler::eventCreateToken(const Event_CreateToken &event)
|
|||
card->setFaceDown(event.face_down());
|
||||
|
||||
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,
|
||||
|
|
@ -193,7 +198,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;
|
||||
|
|
@ -203,7 +208,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,
|
||||
|
|
@ -264,14 +269,14 @@ 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;
|
||||
}
|
||||
|
||||
int oldValue = card->getCounters().value(event.counter_id(), 0);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -341,13 +346,13 @@ 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;
|
||||
}
|
||||
const bool zoneChanged = startZone != targetZone;
|
||||
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()) {
|
||||
QString name = QString::fromStdString(event.card_name());
|
||||
QString providerId =
|
||||
|
|
@ -357,7 +362,13 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
|
|||
|
||||
if (card->getAttachedTo() && (startZone != targetZone)) {
|
||||
CardState *parentCard = card->getAttachedTo();
|
||||
card->setAttachedTo(nullptr);
|
||||
// Route through CardItem so the old parent's attachedCards list is cleaned up: CardState::setAttachedTo
|
||||
// only repoints the pointer, leaving a dangling entry that reorganizeCards/prepareDelete would dereference.
|
||||
if (CardItem *item = toCardItem(card)) {
|
||||
item->setAttachedTo(nullptr);
|
||||
} else {
|
||||
card->setAttachedTo(nullptr);
|
||||
}
|
||||
parentCard->getZone()->reorganizeCards();
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +377,7 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
|
|||
if (startZone != targetZone) {
|
||||
const QList<CardItem *> &attachedCards = card->getAttachedCards();
|
||||
for (auto attachedCard : attachedCards) {
|
||||
emit targetZone->cardAdded(attachedCard);
|
||||
emit targetZone->cardAdded(attachedCard->getState());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -380,12 +391,12 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
|
|||
|
||||
targetZone->addCard(card, true, x, y);
|
||||
|
||||
emit cardZoneChanged(card, startZone == targetZone);
|
||||
emit requestCardMenuUpdate(card);
|
||||
emit cardZoneChanged(toCardItem(card), startZone == targetZone);
|
||||
emit requestCardMenuUpdate(toCardItem(card));
|
||||
|
||||
if (player->getPlayerActions()->isMovingCardsUntil() && startZoneString == ZoneNames::DECK &&
|
||||
targetZone->getName() == ZoneNames::STACK) {
|
||||
player->getPlayerActions()->moveOneCardUntil(card);
|
||||
player->getPlayerActions()->moveOneCardUntil(toCardItem(card));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +406,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,7 +419,7 @@ void PlayerEventHandler::eventFlipCard(const Event_FlipCard &event)
|
|||
|
||||
emit logFlipCard(player, card->getName(), event.face_down());
|
||||
card->setFaceDown(event.face_down());
|
||||
emit requestCardMenuUpdate(card);
|
||||
emit requestCardMenuUpdate(toCardItem(card));
|
||||
}
|
||||
|
||||
void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event)
|
||||
|
|
@ -418,7 +429,7 @@ 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;
|
||||
}
|
||||
|
|
@ -431,7 +442,7 @@ void PlayerEventHandler::eventDestroyCard(const Event_DestroyCard &event)
|
|||
|
||||
emit logDestroyCard(player, card->getName());
|
||||
zone->takeCard(-1, event.card_id(), true);
|
||||
card->getState()->deleteView();
|
||||
card->deleteView();
|
||||
}
|
||||
|
||||
void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
|
||||
|
|
@ -439,7 +450,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
|
|||
const QMap<int, PlayerLogic *> &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) {
|
||||
|
|
@ -455,14 +466,21 @@ 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;
|
||||
}
|
||||
|
||||
CardState *oldParent = startCard->getAttachedTo();
|
||||
|
||||
startCard->setAttachedTo(targetCard);
|
||||
// Route through CardItem::setAttachedTo to keep the attachedCards graph, grid-x reset and zone emits intact:
|
||||
// CardState::setAttachedTo alone only repoints the pointer, so the target would never list the card and the old
|
||||
// parent would keep a dangling pointer.
|
||||
if (CardItem *startItem = toCardItem(startCard)) {
|
||||
startItem->setAttachedTo(toCardItem(targetCard));
|
||||
} else {
|
||||
startCard->setAttachedTo(targetCard);
|
||||
}
|
||||
|
||||
startZone->reorganizeCards();
|
||||
if ((startZone != targetZone) && targetZone) {
|
||||
|
|
@ -477,7 +495,7 @@ void PlayerEventHandler::eventAttachCard(const Event_AttachCard &event)
|
|||
} else {
|
||||
emit logUnattachCard(player, startCard->getName());
|
||||
}
|
||||
emit requestCardMenuUpdate(startCard);
|
||||
emit requestCardMenuUpdate(toCardItem(startCard));
|
||||
}
|
||||
|
||||
void PlayerEventHandler::eventDrawCards(const Event_DrawCards &event)
|
||||
|
|
@ -489,7 +507,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});
|
||||
|
|
@ -537,7 +555,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,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,
|
||||
|
|
@ -249,11 +249,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,
|
||||
|
|
@ -283,7 +283,7 @@ private:
|
|||
PlayerLogic *player;
|
||||
|
||||
void setCardAttrHelper(const GameEventContext &context,
|
||||
CardItem *card,
|
||||
CardState *card,
|
||||
CardAttribute attribute,
|
||||
const QString &avalue,
|
||||
bool allCards,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@
|
|||
#include <qalgorithms.h>
|
||||
#include <string>
|
||||
|
||||
static CardItem *toCardItem(CardState *card)
|
||||
{
|
||||
return card == nullptr ? nullptr : qobject_cast<CardItem *>(card->parent());
|
||||
}
|
||||
|
||||
PlayerLogic::PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent)
|
||||
: QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)),
|
||||
playerEventHandler(new PlayerEventHandler(this)), playerActions(new PlayerActions(this)), active(false),
|
||||
|
|
@ -172,7 +177,7 @@ 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 CardItem(this))->getState(), false, -1);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < cardListSize; ++j) {
|
||||
|
|
@ -184,9 +189,9 @@ void PlayerLogic::processPlayerInfo(const ServerInfo_Player &info)
|
|||
// The x coordinate of such cards is always 0, so inserting at it
|
||||
// would reverse the list on reconnect. Append instead.
|
||||
if (zoneInfo.with_coords()) {
|
||||
zone->addCard(card, false, cardInfo.x(), cardInfo.y());
|
||||
zone->addCard(card->getState(), false, cardInfo.x(), cardInfo.y());
|
||||
} else {
|
||||
zone->addCard(card, false, -1);
|
||||
zone->addCard(card->getState(), false, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -219,15 +224,21 @@ 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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
startCard->setAttachedTo(targetCard);
|
||||
// Route through CardItem::setAttachedTo to maintain the attachedCards graph and reparenting;
|
||||
// CardState::setAttachedTo alone only repoints the pointer.
|
||||
if (CardItem *startItem = toCardItem(startCard)) {
|
||||
startItem->setAttachedTo(toCardItem(targetCard));
|
||||
} else {
|
||||
startCard->setAttachedTo(targetCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -244,14 +255,14 @@ void PlayerLogic::addCard(CardItem *card)
|
|||
emit newCardAdded(card);
|
||||
}
|
||||
|
||||
void PlayerLogic::deleteCard(CardItem *card)
|
||||
void PlayerLogic::deleteCard(CardState *card)
|
||||
{
|
||||
if (card == nullptr) {
|
||||
return;
|
||||
} else if (dialogSemaphore) {
|
||||
cardsToDelete.append(card);
|
||||
} else {
|
||||
card->getState()->deleteView();
|
||||
card->deleteView();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +343,7 @@ bool PlayerLogic::clearCardsToDelete()
|
|||
|
||||
for (auto &i : cardsToDelete) {
|
||||
if (i != nullptr) {
|
||||
i->getState()->deleteView();
|
||||
i->deleteView();
|
||||
}
|
||||
}
|
||||
cardsToDelete.clear();
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public:
|
|||
void processCardAttachment(const ServerInfo_Player &info);
|
||||
|
||||
void addCard(CardItem *c);
|
||||
void deleteCard(CardItem *c);
|
||||
void deleteCard(CardState *c);
|
||||
|
||||
bool clearCardsToDelete();
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ private:
|
|||
QMap<int, CounterState *> counters;
|
||||
|
||||
bool dialogSemaphore;
|
||||
QList<CardItem *> cardsToDelete;
|
||||
QList<CardState *> cardsToDelete;
|
||||
|
||||
// Playmat from player properties (for opponent display)
|
||||
CardRef remotePlaymatCard;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,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(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());
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -91,7 +91,7 @@ CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
|
|||
viewLogic->removeCard(position, toNewZone);
|
||||
}
|
||||
|
||||
CardItem *c = cards.takeAt(position);
|
||||
CardState *c = cards.takeAt(position);
|
||||
|
||||
c->setId(cardId);
|
||||
|
||||
|
|
@ -100,9 +100,9 @@ CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
|
|||
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(CardZoneLogicLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found";
|
||||
return nullptr;
|
||||
|
|
@ -116,7 +116,7 @@ CardItem *CardZoneLogic::getCard(int cardId)
|
|||
return c;
|
||||
}
|
||||
|
||||
void CardZoneLogic::removeCard(CardItem *card)
|
||||
void CardZoneLogic::removeCard(CardState *card)
|
||||
{
|
||||
if (!card) {
|
||||
qCWarning(CardZoneLogicLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen";
|
||||
|
|
@ -132,8 +132,8 @@ void CardZoneLogic::removeCard(CardItem *card)
|
|||
|
||||
void CardZoneLogic::refreshCardInfos()
|
||||
{
|
||||
for (const auto &cardItem : cards) {
|
||||
cardItem->refreshCardInfo();
|
||||
for (const auto &cardState : cards) {
|
||||
cardState->refreshCardInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,17 +165,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<CardItem *> &attachedCards = card->getAttachedCards();
|
||||
for (CardItem *attachedCard : attachedCards) {
|
||||
emit attachedCard->getZone()->cardAdded(attachedCard);
|
||||
emit attachedCard->getZone()->cardAdded(attachedCard->getState());
|
||||
}
|
||||
}
|
||||
|
||||
// Now request deletions after all manipulations are done.
|
||||
for (CardItem *card : toClear) {
|
||||
for (CardState *card : toClear) {
|
||||
player->deleteCard(card);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class CardZoneLogic : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void cardAdded(CardItem *addedCard);
|
||||
void cardAdded(CardState *addedCard);
|
||||
void cardCountChanged();
|
||||
void reorganizeCards();
|
||||
void updateGraphics();
|
||||
|
|
@ -47,14 +47,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);
|
||||
emit cardCountChanged();
|
||||
|
|
@ -120,7 +120,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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "hand_zone_logic.h"
|
||||
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
#include "../board/card_state.h"
|
||||
#include "card_zone_algorithms.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "pile_zone_logic.h"
|
||||
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
#include "../board/card_list.h"
|
||||
#include "../board/card_state.h"
|
||||
|
||||
class PlayerLogic;
|
||||
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 < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
|
|
@ -32,5 +32,5 @@ void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
|
|||
cards.at(x + 1)->setCardRef({});
|
||||
}
|
||||
}
|
||||
card->resetState();
|
||||
card->resetState(false);
|
||||
}
|
||||
|
|
@ -31,7 +31,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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "stack_zone_logic.h"
|
||||
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
#include "../board/card_state.h"
|
||||
#include "card_zone_algorithms.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "table_zone_logic.h"
|
||||
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
#include "../board/card_list.h"
|
||||
#include "../board/card_state.h"
|
||||
#include "libcockatrice/card/card_info.h"
|
||||
|
||||
#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);
|
||||
if (!card->getFaceDown() && card->getPT().isEmpty()) {
|
||||
|
|
@ -31,9 +31,9 @@ void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _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) {
|
||||
emit contentSizeChanged();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
static int tableRowToGridY(int tableRow);
|
||||
|
||||
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.
|
||||
|
|
@ -53,9 +53,9 @@ protected:
|
|||
* @param position card position
|
||||
* @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
|
||||
* @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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "view_zone_logic.h"
|
||||
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
#include "../../game_graphics/board/card_item.h"
|
||||
#include "../board/card_list.h"
|
||||
#include "../board/card_state.h"
|
||||
#include "../player/player_actions.h"
|
||||
#include "../player/player_logic.h"
|
||||
|
||||
|
|
@ -77,7 +77,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
|
||||
|
|
@ -146,8 +146,8 @@ void ZoneViewZoneLogic::removeCard(int position, bool toNewZone)
|
|||
return;
|
||||
}
|
||||
|
||||
CardItem *card = cards.takeAt(position);
|
||||
card->getState()->deleteView();
|
||||
CardState *card = cards.takeAt(position);
|
||||
card->deleteView();
|
||||
|
||||
// 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.
|
||||
|
|
@ -170,7 +170,7 @@ void ZoneViewZoneLogic::requestClose()
|
|||
void ZoneViewZoneLogic::clearCards()
|
||||
{
|
||||
for (auto card : cards) {
|
||||
card->getState()->deleteView();
|
||||
card->deleteView();
|
||||
}
|
||||
cards.clear();
|
||||
emit cardCountChanged();
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public:
|
|||
PendingCommand *requestZoneDump();
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ CardItem::CardItem(PlayerLogic *_owner,
|
|||
update();
|
||||
});
|
||||
|
||||
// The retyped logic layer drives CardState setters directly (bypassing the CardItem wrappers that called
|
||||
// update()), so repaint on every state change: attacking, annotation, doesntUntap, P/T and counters.
|
||||
connect(state, &CardState::stateChanged, this, [this] { update(); });
|
||||
|
||||
connect(state, &CardState::viewDeleteRequested, this, &CardItem::deleteLater);
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +237,7 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
|
|||
if (state->getAttachedTo()->getZone() == nullptr) {
|
||||
deleteLater();
|
||||
} else {
|
||||
emit state->getAttachedTo()->getZone()->cardAdded(this);
|
||||
emit state->getAttachedTo()->getZone()->cardAdded(state);
|
||||
state->getAttachedTo()->addAttachedCard(this);
|
||||
if (state->getZone() != state->getAttachedTo()->getZone()) {
|
||||
state->getAttachedTo()->getZone()->reorganizeCards();
|
||||
|
|
@ -245,7 +249,7 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
|
|||
if (state->getZone() == nullptr) {
|
||||
deleteLater();
|
||||
} else {
|
||||
emit state->getZone()->cardAdded(this);
|
||||
emit state->getZone()->cardAdded(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -467,7 +471,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld)
|
|||
if (SettingsCache::instance().userInterface().getClickPlaysAllSelected()) {
|
||||
emit hideSelected(this);
|
||||
} else {
|
||||
state->getZone()->removeCard(this);
|
||||
state->getZone()->removeCard(state);
|
||||
}
|
||||
} else {
|
||||
playCard(shiftHeld);
|
||||
|
|
|
|||
|
|
@ -137,7 +137,8 @@ static void selectCardsInZone(
|
|||
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)) {
|
||||
cardItem->setSelected(true);
|
||||
}
|
||||
|
|
@ -596,7 +597,11 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
|
|||
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) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -607,7 +612,8 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
|
|||
} else {
|
||||
auto *zone = targetView->getLogic()->getZones().value(data->targetZone);
|
||||
if (zone) {
|
||||
targetItem = zone->getCard(data->targetCardId);
|
||||
CardState *targetCardState = zone->getCard(data->targetCardId);
|
||||
targetItem = targetCardState == nullptr ? nullptr : qobject_cast<CardItem *>(targetCardState->parent());
|
||||
}
|
||||
}
|
||||
if (!targetItem) {
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ void MessageLogWidget::logDestroyCard(PlayerLogic *player, QString cardName)
|
|||
}
|
||||
|
||||
void MessageLogWidget::logMoveCard(PlayerLogic *player,
|
||||
CardItem *card,
|
||||
CardState *card,
|
||||
CardZoneLogic *startZone,
|
||||
int oldX,
|
||||
CardZoneLogic *targetZone,
|
||||
|
|
@ -662,7 +662,7 @@ void MessageLogWidget::logSetActivePlayer(PlayerLogic *player)
|
|||
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(
|
||||
QString(tr("%1 sets annotation of %2 to %3."))
|
||||
|
|
@ -706,7 +706,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) {
|
||||
|
|
@ -717,7 +717,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;
|
||||
|
|
@ -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) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <qtmetamacros.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
class CardState;
|
||||
class AbstractGame;
|
||||
class CardItem;
|
||||
class GameEventContext;
|
||||
|
|
@ -76,7 +77,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,
|
||||
|
|
@ -97,13 +98,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);
|
||||
|
|
|
|||
|
|
@ -177,6 +177,22 @@ void PlayerGraphicsItem::initializeZones()
|
|||
|
||||
void PlayerGraphicsItem::onCustomZoneAdded(QString customZoneName)
|
||||
{
|
||||
// Custom zones have no board view, but their cards still need a graphics owner.
|
||||
// Without one, PileZone::onCardAdded never runs and cards moved from the table
|
||||
// or hand into a custom zone stay drawn at their old spot. Give them a hidden
|
||||
// pile zone so added cards are reparented to (0, 0) and hidden.
|
||||
CardZoneLogic *logic = player->getZone(customZoneName);
|
||||
if (auto *pileLogic = qobject_cast<PileZoneLogic *>(logic)) {
|
||||
auto *hiddenZone = new PileZone(pileLogic, this);
|
||||
hiddenZone->setVisible(false);
|
||||
hiddenZone->setPos(0, 0);
|
||||
zoneGraphicsItems.insert(customZoneName, hiddenZone);
|
||||
// Hide any cards that arrived before the graphics item existed.
|
||||
for (CardState *state : pileLogic->getCards()) {
|
||||
hiddenZone->onCardAdded(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
zoneGraphicsItems.insert(customZoneName, nullptr); // Custom zone view goes here, if we ever implement it.
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,17 +37,26 @@ void CardZone::invalidateItems()
|
|||
const QList<CardItem *> &CardZone::cardItems() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
void CardZone::onCardAdded(CardItem *addedCard)
|
||||
void CardZone::onCardAdded(CardState *addedCard)
|
||||
{
|
||||
addedCard->setParentItem(this);
|
||||
addedCard->setVisible(true);
|
||||
addedCard->update();
|
||||
auto *addedItem = addedCard == nullptr ? nullptr : qobject_cast<CardItem *>(addedCard->parent());
|
||||
if (addedItem == nullptr) {
|
||||
return;
|
||||
}
|
||||
addedItem->setParentItem(this);
|
||||
addedItem->setVisible(true);
|
||||
addedItem->update();
|
||||
}
|
||||
|
||||
void CardZone::retranslateUi()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
class CardDragItem;
|
||||
class CardItem;
|
||||
class CardState;
|
||||
class CardZoneLogic;
|
||||
class QAction;
|
||||
class QGraphicsItem;
|
||||
|
|
@ -23,6 +24,8 @@ class QMenu;
|
|||
class QPoint;
|
||||
template <typename T> class QList;
|
||||
|
||||
class CardItem;
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CardZoneLog, "card_zone");
|
||||
|
||||
/**
|
||||
|
|
@ -55,7 +58,7 @@ 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);
|
||||
|
||||
public:
|
||||
enum
|
||||
|
|
|
|||
|
|
@ -87,12 +87,13 @@ void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneL
|
|||
getLogic()->getPlayer()->getPlayerActions()->moveCards(startZone, getLogic(), 0, 0, cards);
|
||||
}
|
||||
|
||||
void PileZone::onCardAdded(CardItem *addedCard)
|
||||
void PileZone::onCardAdded(CardState *addedCard)
|
||||
{
|
||||
CardZone::onCardAdded(addedCard);
|
||||
if (addedCard) {
|
||||
addedCard->setPos(0, 0);
|
||||
addedCard->setVisible(false);
|
||||
auto *addedItem = addedCard == nullptr ? nullptr : qobject_cast<CardItem *>(addedCard->parent());
|
||||
if (addedItem) {
|
||||
addedItem->setPos(0, 0);
|
||||
addedItem->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public:
|
|||
[[nodiscard]] QPainterPath shape() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void reorganizeCards() override;
|
||||
void onCardAdded(CardItem *addedCard) override;
|
||||
void onCardAdded(CardState *addedCard) override;
|
||||
void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -172,12 +172,13 @@ SelectZone::~SelectZone()
|
|||
}
|
||||
}
|
||||
|
||||
void SelectZone::onCardAdded(CardItem *addedCard)
|
||||
void SelectZone::onCardAdded(CardState *addedCard)
|
||||
{
|
||||
if (cardClipContainer && addedCard) {
|
||||
addedCard->setParentItem(cardClipContainer);
|
||||
addedCard->setVisible(true);
|
||||
addedCard->update();
|
||||
auto *addedItem = addedCard == nullptr ? nullptr : qobject_cast<CardItem *>(addedCard->parent());
|
||||
if (cardClipContainer && addedItem) {
|
||||
addedItem->setParentItem(cardClipContainer);
|
||||
addedItem->setVisible(true);
|
||||
addedItem->update();
|
||||
} else {
|
||||
CardZone::onCardAdded(addedCard);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public:
|
|||
|
||||
SelectZone(CardZoneLogic *logic, QGraphicsItem *parent = nullptr);
|
||||
~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
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
|
|||
auto copy = new CardItem(getLogic()->getPlayer(), this, cardRef, card->id());
|
||||
copy->setFaceDown(card->face_down());
|
||||
|
||||
getLogic()->addCard(copy, false, i);
|
||||
getLogic()->addCard(copy->getState(), false, i);
|
||||
}
|
||||
reorganizeCards();
|
||||
} 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();
|
||||
int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size());
|
||||
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());
|
||||
copy->setFaceDown(card->getFaceDown());
|
||||
|
||||
getLogic()->addCard(copy, false, i);
|
||||
getLogic()->addCard(copy->getState(), false, i);
|
||||
}
|
||||
reorganizeCards();
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ void ZoneViewZone::zoneDumpReceived(const Response &r)
|
|||
auto cardProviderId = QString::fromStdString(cardInfo.provider_id());
|
||||
auto card = new CardItem(getLogic()->getPlayer(), this, {cardName, cardProviderId}, cardInfo.id(), getLogic());
|
||||
card->setFaceDown(cardInfo.face_down());
|
||||
getLogic()->rawInsertCard(card, i);
|
||||
getLogic()->rawInsertCard(card->getState(), i);
|
||||
}
|
||||
|
||||
qobject_cast<ZoneViewZoneLogic *>(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE);
|
||||
|
|
@ -145,7 +145,7 @@ void ZoneViewZone::reorganizeCards()
|
|||
for (auto card : cardItems()) {
|
||||
if (filterString.check(card->getCard().getCardPtr())) {
|
||||
card->show();
|
||||
cardsToDisplay.append(card);
|
||||
cardsToDisplay.append(card->getState());
|
||||
} else {
|
||||
card->hide();
|
||||
}
|
||||
|
|
@ -213,7 +213,8 @@ 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);
|
||||
CardItem *cItem = qobject_cast<CardItem *>(c->parent());
|
||||
QString columnProp = extractor(c);
|
||||
|
||||
if (i) { // if not the first card
|
||||
|
|
@ -228,8 +229,8 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
|
|||
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);
|
||||
cItem->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
|
||||
cItem->setRealZValue(i);
|
||||
longestRow = qMax(row, longestRow);
|
||||
}
|
||||
|
||||
|
|
@ -254,11 +255,11 @@ 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);
|
||||
auto *cItem = qobject_cast<CardItem *>(cards.at(i)->parent());
|
||||
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);
|
||||
cItem->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
|
||||
cItem->setRealZValue(i);
|
||||
}
|
||||
|
||||
return GridSize{rows, qMax(cols, 1)};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue