This commit is contained in:
BruebachL 2026-06-15 00:52:39 +02:00 committed by GitHub
commit 5ecb00f470
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
62 changed files with 823 additions and 704 deletions

View file

@ -349,6 +349,8 @@ set(cockatrice_SOURCES
src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h
src/interface/widgets/utility/compact_push_button.cpp src/interface/widgets/utility/compact_push_button.cpp
src/interface/widgets/utility/compact_push_button.h src/interface/widgets/utility/compact_push_button.h
src/game/board/abstract_card_state.cpp
src/game/board/abstract_card_state.h
) )
add_subdirectory(sounds) add_subdirectory(sounds)

View file

@ -42,7 +42,7 @@ void AbstractGame::setActiveCard(CardItem *card)
activeCard = card; activeCard = card;
} }
CardItem *AbstractGame::getCard(int playerId, const QString &zoneName, int cardId) const CardState *AbstractGame::getCard(int playerId, const QString &zoneName, int cardId) const
{ {
PlayerLogic *player = playerManager->getPlayer(playerId); PlayerLogic *player = playerManager->getPlayer(playerId);
if (!player) { if (!player) {

View file

@ -7,6 +7,7 @@
#ifndef COCKATRICE_ABSTRACT_GAME_H #ifndef COCKATRICE_ABSTRACT_GAME_H
#define COCKATRICE_ABSTRACT_GAME_H #define COCKATRICE_ABSTRACT_GAME_H
#include "board/card_state.h"
#include "game_event_handler.h" #include "game_event_handler.h"
#include "game_meta_info.h" #include "game_meta_info.h"
#include "game_state.h" #include "game_state.h"
@ -55,7 +56,7 @@ public:
void loadReplay(GameReplay *replay); void loadReplay(GameReplay *replay);
CardItem *getCard(int playerId, const QString &zoneName, int cardId) const; CardState *getCard(int playerId, const QString &zoneName, int cardId) const;
void setActiveCard(CardItem *card); void setActiveCard(CardItem *card);
CardItem *getActiveCard() const CardItem *getActiveCard() const

View file

@ -0,0 +1,81 @@
#include "abstract_card_state.h"
#include "libcockatrice/card/database/card_database_manager.h"
AbstractCardState::AbstractCardState(PlayerLogic *_owner, const CardRef &_cardRef, int _id)
: owner(_owner), cardRef(_cardRef), id(_id), tapped(false), facedown(false)
{
refreshCardInfo();
}
/**
* Convenience method to get the CardInfo of the exactCard
* @return A const reference to the CardInfo, or an empty CardInfo if card was null
*/
const CardInfo &AbstractCardState::getCardInfo() const
{
return exactCard.getInfo();
}
void AbstractCardState::refreshCardInfo()
{
exactCard = CardDatabaseManager::query()->getCard(cardRef);
if (!exactCard && !cardRef.name.isEmpty()) {
CardInfo::UiAttributes attributes = {.tableRow = -1};
auto info = CardInfo::newInstance(cardRef.name, "", true, {}, {}, {}, {}, attributes);
exactCard = ExactCard(info);
}
emit cardInfoRefreshed(exactCard);
emit colorChanged();
}
void AbstractCardState::setCardRef(const CardRef &_cardRef)
{
if (cardRef == _cardRef) {
return;
}
// TODO emit deleteCardInfoPopup(cardRef.name);
if (exactCard) {
disconnect(exactCard.getCardPtr().data(), nullptr, this, nullptr);
}
cardRef = _cardRef;
refreshCardInfo();
}
void AbstractCardState::setTapped(bool _tapped, bool canAnimate)
{
if (tapped == _tapped) {
return;
}
tapped = _tapped;
Q_UNUSED(canAnimate);
// TODO
/*if (SettingsCache::instance().getTapAnimation() && canAnimate) {
static_cast<GameScene *>(scene())->registerAnimationItem(this);
} else {
tapAngle = tapped ? 90 : 0;
setTransform(QTransform()
.translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F)
.rotate(tapAngle)
.translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F));
update();
}*/
}
void AbstractCardState::setFaceDown(bool _facedown)
{
facedown = _facedown;
emit faceDownChanged(facedown);
}
void AbstractCardState::setColor(const QString &_color)
{
color = _color;
emit colorChanged();
}

View file

@ -0,0 +1,86 @@
#ifndef COCKATRICE_ABSTRACT_CARD_STATE_H
#define COCKATRICE_ABSTRACT_CARD_STATE_H
#include <QObject>
#include <libcockatrice/card/printing/exact_card.h>
#include <libcockatrice/utility/card_ref.h>
class PlayerLogic;
class AbstractCardState : public QObject
{
Q_OBJECT
signals:
void cardChanged(ExactCard *card);
void cardRefChanged(CardRef *cardRef);
void tappedChanged(bool tapped);
void faceDownChanged(bool faceDown);
void cardInfoRefreshed(ExactCard card);
void colorChanged();
protected:
PlayerLogic *owner;
CardRef cardRef;
ExactCard exactCard;
int id;
bool tapped;
bool facedown;
QString color;
public slots:
void refreshCardInfo();
public:
AbstractCardState(PlayerLogic *_owner = nullptr, const CardRef &cardRef = {}, int _id = -1);
PlayerLogic *getOwner() const
{
return owner;
}
void setOwner(PlayerLogic *_owner)
{
owner = _owner;
}
ExactCard getCard() const
{
return exactCard;
}
const CardInfo &getCardInfo() const;
int getId() const
{
return id;
}
void setId(int _id)
{
id = _id;
}
QString getName() const
{
return cardRef.name;
}
QString getProviderId() const
{
return cardRef.providerId;
}
void setCardRef(const CardRef &_cardRef);
CardRef getCardRef() const
{
return cardRef;
}
bool getTapped() const
{
return tapped;
}
void setTapped(bool _tapped, bool canAnimate = false);
bool getFaceDown() const
{
return facedown;
}
void setFaceDown(bool _facedown);
QString getColor() const
{
return color;
}
void setColor(const QString &_color);
};
#endif // COCKATRICE_ABSTRACT_CARD_STATE_H

View file

@ -6,7 +6,7 @@
#include <algorithm> #include <algorithm>
#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)
{ {
} }
@ -18,7 +18,7 @@ CardList::CardList(bool _contentsKnown) : QList<CardItem *>(), contentsKnown(_co
* *
* @returns A pointer to the CardItem, or a nullptr if not found. * @returns A pointer to the CardItem, or a nullptr if not found.
*/ */
CardItem *CardList::findCard(const int cardId) const CardState *CardList::findCard(const int cardId) const
{ {
if (!contentsKnown && !empty()) { if (!contentsKnown && !empty()) {
return at(0); return at(0);
@ -46,7 +46,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);
@ -113,24 +113,24 @@ 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 CardItem.
*/ */
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();
} }
@ -142,18 +142,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

@ -12,9 +12,8 @@
inline Q_LOGGING_CATEGORY(CardListLog, "card_list"); inline Q_LOGGING_CATEGORY(CardListLog, "card_list");
class CardItem; class CardState;
class CardList : public QList<CardState *>
class CardList : public QList<CardItem *>
{ {
protected: protected:
bool contentsKnown; bool contentsKnown;
@ -41,7 +40,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;
@ -49,7 +48,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

@ -1,5 +1,54 @@
#include "card_state.h" #include "card_state.h"
#include "../player/player_logic.h"
#include "../zones/card_zone_logic.h"
CardState::CardState(PlayerLogic *_owner, const CardRef &cardRef, int _id, CardZoneLogic *_zone)
: AbstractCardState(_owner, cardRef, _id), zone(_zone)
{
owner->addCard(this);
}
void CardState::prepareDelete()
{
while (!attachedCards.isEmpty()) {
attachedCards.first()->setZone(nullptr); // so that it won't try to call reorganizeCards()
attachedCards.first()->setAttachedTo(nullptr);
}
if (getAttachedTo() != nullptr) {
getAttachedTo()->removeAttachedCard(this);
setAttachedTo(nullptr);
}
}
void CardState::deleteLater()
{
prepareDelete();
QObject::deleteLater();
}
void CardState::processCardInfo(const ServerInfo_Card &_info)
{
clearCounters();
const int counterListSize = _info.counter_list_size();
for (int i = 0; i < counterListSize; ++i) {
const ServerInfo_CardCounter &counterInfo = _info.counter_list(i);
insertCounter(counterInfo.id(), counterInfo.value());
}
setId(_info.id());
setCardRef({QString::fromStdString(_info.name()), QString::fromStdString(_info.provider_id())});
setAttacking(_info.attacking());
setFaceDown(_info.face_down());
setPT(QString::fromStdString(_info.pt()));
setAnnotation(QString::fromStdString(_info.annotation()));
setColor(QString::fromStdString(_info.color()));
setTapped(_info.tapped());
setDestroyOnZoneChange(_info.destroy_on_zone_change());
setDoesntUntap(_info.doesnt_untap());
}
void CardState::resetState(bool keepAnnotations) void CardState::resetState(bool keepAnnotations)
{ {
attacking = false; attacking = false;
@ -11,6 +60,11 @@ void CardState::resetState(bool keepAnnotations)
attachedTo = nullptr; attachedTo = nullptr;
} }
void CardState::clearAttachedCards()
{
attachedCards.clear();
}
void CardState::setZone(CardZoneLogic *_zone) void CardState::setZone(CardZoneLogic *_zone)
{ {
if (zone == _zone) { if (zone == _zone) {
@ -100,7 +154,7 @@ void CardState::setDestroyOnZoneChange(bool _destroyOnZoneChange)
emit stateChanged(); emit stateChanged();
} }
void CardState::setAttachedTo(CardItem *_attachedTo) void CardState::setAttachedTo(CardState *_attachedTo)
{ {
if (attachedTo == _attachedTo) { if (attachedTo == _attachedTo) {
return; return;
@ -108,4 +162,40 @@ void CardState::setAttachedTo(CardItem *_attachedTo)
attachedTo = _attachedTo; attachedTo = _attachedTo;
emit attachedToChanged(_attachedTo); emit attachedToChanged(_attachedTo);
emit stateChanged(); emit stateChanged();
} }
/*
void CardItem::setAttachedTo(CardItem *_attachedTo)
{
if (state->getAttachedTo() != nullptr) {
state->getAttachedTo()->removeAttachedCard(this);
}
gridPoint.setX(-1);
state->setAttachedTo(_attachedTo);
if (state->getAttachedTo() != nullptr) {
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its
// attached cards
if (state->getAttachedTo()->getState()->getZone() == nullptr) {
deleteLater();
} else {
emit state->getAttachedTo()->getState()->getZone()->cardAdded(this);
state->getAttachedTo()->addAttachedCard(this);
if (state->getZone() != state->getAttachedTo()->getState()->getZone()) {
state->getAttachedTo()->getState()->getZone()->reorganizeCards();
}
}
} else {
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its
// attached cards
if (state->getZone() == nullptr) {
deleteLater();
} else {
emit state->getZone()->cardAdded(this);
}
}
if (state->getZone() != nullptr) {
state->getZone()->reorganizeCards();
}
}*/

View file

@ -1,12 +1,15 @@
#ifndef COCKATRICE_CARD_STATE_H #ifndef COCKATRICE_CARD_STATE_H
#define COCKATRICE_CARD_STATE_H #define COCKATRICE_CARD_STATE_H
#include "abstract_card_state.h"
#include <QMap> #include <QMap>
#include <QObject> #include <QObject>
#include <QPoint>
#include <libcockatrice/protocol/pb/serverinfo_card.pb.h>
class CardZoneLogic; class CardZoneLogic;
class CardItem; class CardState : public AbstractCardState
class CardState : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -17,8 +20,12 @@ private:
QString pt; QString pt;
bool doesntUntap = false; bool doesntUntap = false;
bool destroyOnZoneChange = false; bool destroyOnZoneChange = false;
bool visible = false;
CardItem *attachedTo = nullptr; QPoint gridPoint;
CardState *attachedTo = nullptr;
QList<CardState *> attachedCards;
CardZoneLogic *zone = nullptr; CardZoneLogic *zone = nullptr;
signals: signals:
@ -30,15 +37,20 @@ signals:
void ptChanged(const QString &newPt); void ptChanged(const QString &newPt);
void doesntUntapChanged(bool newValue); void doesntUntapChanged(bool newValue);
void destroyOnZoneChangeChanged(bool newValue); void destroyOnZoneChangeChanged(bool newValue);
void attachedToChanged(CardItem *newAttachedTo); void attachedToChanged(CardState *newAttachedTo);
void zoneChanged(CardState *changedCard, CardZoneLogic *newZone); void zoneChanged(CardState *changedCard, CardZoneLogic *newZone);
void visibleChanged(bool visible);
public slots:
void deleteLater();
public: public:
explicit CardState(QObject *parent, CardZoneLogic *_zone) : QObject(parent), zone(_zone) explicit CardState(PlayerLogic *_owner, const CardRef &cardRef = {}, int _id = -1, CardZoneLogic *_zone = nullptr);
{
}
void prepareDelete();
void processCardInfo(const ServerInfo_Card &_info);
void resetState(bool keepAnnotations); void resetState(bool keepAnnotations);
void clearAttachedCards();
CardZoneLogic *getZone() const CardZoneLogic *getZone() const
{ {
@ -92,12 +104,51 @@ public:
void setDestroyOnZoneChange(bool _destroyOnZoneChange); void setDestroyOnZoneChange(bool _destroyOnZoneChange);
CardItem *getAttachedTo() const CardState *getAttachedTo() const
{ {
return attachedTo; return attachedTo;
} }
void setAttachedTo(CardItem *_attachedTo); [[nodiscard]] QPoint getGridPoint() const
{
return gridPoint;
}
void setGridPoint(const QPoint &_gridPoint)
{
gridPoint = _gridPoint;
}
[[nodiscard]] QPoint getGridPos() const
{
return gridPoint;
}
bool getVisible() const
{
return visible;
}
void setVisible(bool _visible)
{
if (_visible == visible) {
return;
}
visible = _visible;
emit visibleChanged(visible);
}
void setAttachedTo(CardState *_attachedTo);
void addAttachedCard(CardState *card)
{
attachedCards.append(card);
}
void removeAttachedCard(CardState *card)
{
attachedCards.removeOne(card);
}
[[nodiscard]] const QList<CardState *> &getAttachedCards() const
{
return attachedCards;
}
}; };
#endif // COCKATRICE_CARD_STATE_H #endif // COCKATRICE_CARD_STATE_H

View file

@ -45,7 +45,7 @@ PlayerActions::PlayerActions(PlayerLogic *_player)
connect(moveTopCardTimer, &QTimer::timeout, [this]() { actMoveTopCardToPlay(); }); connect(moveTopCardTimer, &QTimer::timeout, [this]() { actMoveTopCardToPlay(); });
} }
void PlayerActions::playCard(CardItem *card, bool faceDown) void PlayerActions::playCard(CardState *card, bool faceDown)
{ {
if (card == nullptr) { if (card == nullptr) {
return; return;
@ -105,13 +105,13 @@ void PlayerActions::playCardToTable(const CardItem *card, bool faceDown)
} }
Command_MoveCard cmd; Command_MoveCard cmd;
cmd.set_start_player_id(card->getZone()->getPlayer()->getPlayerInfo()->getId()); cmd.set_start_player_id(card->getState()->getZone()->getPlayer()->getPlayerInfo()->getId());
cmd.set_start_zone(card->getZone()->getName().toStdString()); cmd.set_start_zone(card->getState()->getZone()->getName().toStdString());
cmd.set_target_player_id(player->getPlayerInfo()->getId()); cmd.set_target_player_id(player->getPlayerInfo()->getId());
CardToMove *cardToMove = cmd.mutable_cards_to_move()->add_card(); CardToMove *cardToMove = cmd.mutable_cards_to_move()->add_card();
cardToMove->set_card_id(card->getId()); cardToMove->set_card_id(card->getState()->getId());
ExactCard exactCard = card->getCard(); ExactCard exactCard = card->getState()->getCard();
if (!exactCard) { if (!exactCard) {
return; return;
} }
@ -503,7 +503,7 @@ void PlayerActions::moveTopCardsUntil(const QString &expr, MoveTopCardsUntilOpti
} }
} }
void PlayerActions::moveOneCardUntil(CardItem *card) void PlayerActions::moveOneCardUntil(CardState *card)
{ {
moveTopCardTimer->stop(); moveTopCardTimer->stop();
@ -695,6 +695,8 @@ void PlayerActions::actMoveBottomCardToTop()
sendGameCommand(cmd); sendGameCommand(cmd);
} }
// TODO: None of these should know about CardItems and instead get the correct states passed in. PlayerActions is not
// the place to do this.
/** /**
* Selects all cards in the given zone. * Selects all cards in the given zone.
* *
@ -709,11 +711,13 @@ static void selectCardsInZone(
return; return;
} }
for (auto &cardItem : zone->getCards()) { Q_UNUSED(filter);
// TODO Fix this
/*for (auto &cardItem : zone->getCards()) {
if (cardItem && filter(cardItem)) { if (cardItem && filter(cardItem)) {
cardItem->setSelected(true); cardItem->setSelected(true);
} }
} }*/
} }
void PlayerActions::actSelectAll() void PlayerActions::actSelectAll()
@ -723,7 +727,7 @@ void PlayerActions::actSelectAll()
return; return;
} }
selectCardsInZone(card->getZone()); selectCardsInZone(card->getState()->getZone());
} }
void PlayerActions::actSelectRow() void PlayerActions::actSelectRow()
@ -736,7 +740,7 @@ void PlayerActions::actSelectRow()
auto isSameRow = [card](const CardItem *cardItem) { auto isSameRow = [card](const CardItem *cardItem) {
return qAbs(card->scenePos().y() - cardItem->scenePos().y()) < 50; return qAbs(card->scenePos().y() - cardItem->scenePos().y()) < 50;
}; };
selectCardsInZone(card->getZone(), isSameRow); selectCardsInZone(card->getState()->getZone(), isSameRow);
} }
void PlayerActions::actSelectColumn() void PlayerActions::actSelectColumn()
@ -747,7 +751,7 @@ void PlayerActions::actSelectColumn()
} }
auto isSameColumn = [card](const CardItem *cardItem) { return cardItem->x() == card->x(); }; auto isSameColumn = [card](const CardItem *cardItem) { return cardItem->x() == card->x(); };
selectCardsInZone(card->getZone(), isSameColumn); selectCardsInZone(card->getState()->getZone(), isSameColumn);
} }
void PlayerActions::actDrawBottomCard() void PlayerActions::actDrawBottomCard()
@ -965,7 +969,7 @@ void PlayerActions::actCreateRelatedCard()
auto *action = static_cast<QAction *>(sender()); auto *action = static_cast<QAction *>(sender());
// If there is a better way of passing a CardRelation through a QAction, please add it here. // If there is a better way of passing a CardRelation through a QAction, please add it here.
auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards(); auto relatedCards = sourceCard->getState()->getCardInfo().getAllRelatedCards();
CardRelation *cardRelation = relatedCards.at(action->data().toInt()); CardRelation *cardRelation = relatedCards.at(action->data().toInt());
actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation); actRequestCreateRelatedFromRelationDialog(sourceCard, cardRelation);
@ -978,7 +982,7 @@ void PlayerActions::actCreateAllRelatedCards()
return; return;
} }
auto relatedCards = sourceCard->getCardInfo().getAllRelatedCards(); auto relatedCards = sourceCard->getState()->getCardInfo().getAllRelatedCards();
if (relatedCards.isEmpty()) { if (relatedCards.isEmpty()) {
return; return;
} }
@ -1106,7 +1110,7 @@ bool PlayerActions::createRelatedFromRelation(const CardItem *sourceCard,
// move card onto table first if attaching from some other zone // move card onto table first if attaching from some other zone
// we only do this for AttachTo because cross-zone TransformInto is already handled server-side // we only do this for AttachTo because cross-zone TransformInto is already handled server-side
if (attachType == CardRelationType::AttachTo && sourceCard->getZone()->getName() != ZoneNames::TABLE) { if (attachType == CardRelationType::AttachTo && sourceCard->getZone()->getLogic()->getName() != ZoneNames::TABLE) {
playCardToTable(sourceCard, false); playCardToTable(sourceCard, false);
} }
@ -1128,8 +1132,8 @@ void PlayerActions::onRelatedCardCreated(const CardItem *sourceCard, const CardR
return; return;
} }
ExactCard relatedCard = ExactCard relatedCard = CardDatabaseManager::query()->getCardFromSameSet(
CardDatabaseManager::query()->getCardFromSameSet(cardRelation->getName(), sourceCard->getCard().getPrinting()); cardRelation->getName(), sourceCard->getState()->getCard().getPrinting());
setLastToken(relatedCard.getCardPtr()); setLastToken(relatedCard.getCardPtr());
} }
@ -1173,8 +1177,8 @@ void PlayerActions::createCard(const CardItem *sourceCard,
cmd.set_x(gridPoint.x()); cmd.set_x(gridPoint.x());
cmd.set_y(gridPoint.y()); cmd.set_y(gridPoint.y());
ExactCard relatedCard = ExactCard relatedCard = CardDatabaseManager::query()->getCardFromSameSet(
CardDatabaseManager::query()->getCardFromSameSet(cardInfo->getName(), sourceCard->getCard().getPrinting()); cardInfo->getName(), sourceCard->getState()->getCard().getPrinting());
switch (attachType) { switch (attachType) {
case CardRelationType::DoesNotAttach: case CardRelationType::DoesNotAttach:
@ -1185,18 +1189,19 @@ void PlayerActions::createCard(const CardItem *sourceCard,
case CardRelationType::AttachTo: case CardRelationType::AttachTo:
cmd.set_target_zone(ZoneNames::TABLE); // We currently only support creating tokens on the table cmd.set_target_zone(ZoneNames::TABLE); // We currently only support creating tokens on the table
cmd.set_card_provider_id(relatedCard.getPrinting().getUuid().toStdString()); cmd.set_card_provider_id(relatedCard.getPrinting().getUuid().toStdString());
cmd.set_target_card_id(sourceCard->getId()); cmd.set_target_card_id(sourceCard->getState()->getId());
cmd.set_target_mode(Command_CreateToken::ATTACH_TO); cmd.set_target_mode(Command_CreateToken::ATTACH_TO);
break; break;
case CardRelationType::TransformInto: case CardRelationType::TransformInto:
// allow cards to directly transform on stack // allow cards to directly transform on stack
cmd.set_zone(sourceCard->getZone()->getName() == ZoneNames::STACK ? ZoneNames::STACK : ZoneNames::TABLE); cmd.set_zone(sourceCard->getZone()->getLogic()->getName() == ZoneNames::STACK ? ZoneNames::STACK
: ZoneNames::TABLE);
// Transform card zone changes are handled server-side // Transform card zone changes are handled server-side
cmd.set_target_zone(sourceCard->getZone()->getName().toStdString()); cmd.set_target_zone(sourceCard->getZone()->getLogic()->getName().toStdString());
cmd.set_target_card_id(sourceCard->getId()); cmd.set_target_card_id(sourceCard->getState()->getId());
cmd.set_target_mode(Command_CreateToken::TRANSFORM_INTO); cmd.set_target_mode(Command_CreateToken::TRANSFORM_INTO);
cmd.set_card_provider_id(sourceCard->getProviderId().toStdString()); cmd.set_card_provider_id(sourceCard->getState()->getProviderId().toStdString());
break; break;
} }
@ -1218,7 +1223,7 @@ void PlayerActions::actRequestMoveCardXCardsFromTopDialog()
emit requestMoveCardXCardsFromTopDialog(defaultNumberTopCardsToPlaceBelow, deckSize); emit requestMoveCardXCardsFromTopDialog(defaultNumberTopCardsToPlaceBelow, deckSize);
} }
void PlayerActions::actMoveCardXCardsFromTop(QList<CardItem *> selectedCards, int number) void PlayerActions::actMoveCardXCardsFromTop(QList<CardState *> selectedCards, int number)
{ {
defaultNumberTopCardsToPlaceBelow = number; defaultNumberTopCardsToPlaceBelow = number;
@ -1252,7 +1257,7 @@ void PlayerActions::actMoveCardXCardsFromTop(QList<CardItem *> selectedCards, in
} }
} }
void PlayerActions::actIncPT(QList<CardItem *> selectedCards, int deltaP, int deltaT) void PlayerActions::actIncPT(QList<CardState *> selectedCards, int deltaP, int deltaT)
{ {
int playerid = player->getPlayerInfo()->getId(); int playerid = player->getPlayerInfo()->getId();
@ -1285,7 +1290,7 @@ void PlayerActions::actIncPT(QList<CardItem *> selectedCards, int deltaP, int de
player->getGame()->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid); player->getGame()->getGameEventHandler()->sendGameCommand(prepareGameCommand(commandList), playerid);
} }
void PlayerActions::actResetPT(QList<CardItem *> selectedCards) void PlayerActions::actResetPT(QList<CardState *> selectedCards)
{ {
int playerid = player->getPlayerInfo()->getId(); int playerid = player->getPlayerInfo()->getId();
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
@ -1318,7 +1323,7 @@ void PlayerActions::actResetPT(QList<CardItem *> selectedCards)
} }
} }
void PlayerActions::actRequestSetPTDialog(QList<CardItem *> selectedCards) void PlayerActions::actRequestSetPTDialog(QList<CardState *> selectedCards)
{ {
QString oldPT; QString oldPT;
@ -1331,7 +1336,7 @@ void PlayerActions::actRequestSetPTDialog(QList<CardItem *> selectedCards)
emit requestSetPTDialog(oldPT); emit requestSetPTDialog(oldPT);
} }
void PlayerActions::actSetPT(QList<CardItem *> selectedCards, const QString &pt) void PlayerActions::actSetPT(QList<CardState *> selectedCards, const QString &pt)
{ {
int playerid = player->getPlayerInfo()->getId(); int playerid = player->getPlayerInfo()->getId();
@ -1383,47 +1388,47 @@ void PlayerActions::actDrawArrow()
} }
} }
void PlayerActions::actIncP(QList<CardItem *> selectedCards) void PlayerActions::actIncP(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, 1, 0); actIncPT(selectedCards, 1, 0);
} }
void PlayerActions::actDecP(QList<CardItem *> selectedCards) void PlayerActions::actDecP(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, -1, 0); actIncPT(selectedCards, -1, 0);
} }
void PlayerActions::actIncT(QList<CardItem *> selectedCards) void PlayerActions::actIncT(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, 0, 1); actIncPT(selectedCards, 0, 1);
} }
void PlayerActions::actDecT(QList<CardItem *> selectedCards) void PlayerActions::actDecT(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, 0, -1); actIncPT(selectedCards, 0, -1);
} }
void PlayerActions::actIncPT(QList<CardItem *> selectedCards) void PlayerActions::actIncPT(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, 1, 1); actIncPT(selectedCards, 1, 1);
} }
void PlayerActions::actDecPT(QList<CardItem *> selectedCards) void PlayerActions::actDecPT(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, -1, -1); actIncPT(selectedCards, -1, -1);
} }
void PlayerActions::actFlowP(QList<CardItem *> selectedCards) void PlayerActions::actFlowP(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, 1, -1); actIncPT(selectedCards, 1, -1);
} }
void PlayerActions::actFlowT(QList<CardItem *> selectedCards) void PlayerActions::actFlowT(QList<CardState *> selectedCards)
{ {
actIncPT(selectedCards, -1, 1); actIncPT(selectedCards, -1, 1);
} }
void PlayerActions::actReduceLifeByPower(QList<CardItem *> selectedCards) void PlayerActions::actReduceLifeByPower(QList<CardState *> selectedCards)
{ {
// find life counter // find life counter
auto lifeCounter = player->getLifeCounter(); auto lifeCounter = player->getLifeCounter();
@ -1458,7 +1463,7 @@ void AnnotationDialog::keyPressEvent(QKeyEvent *event)
QInputDialog::keyPressEvent(event); QInputDialog::keyPressEvent(event);
} }
void PlayerActions::actRequestSetAnnotationDialog(QList<CardItem *> selectedCards) void PlayerActions::actRequestSetAnnotationDialog(QList<CardState *> selectedCards)
{ {
QString oldAnnotation; QString oldAnnotation;
for (auto card : selectedCards) { for (auto card : selectedCards) {
@ -1470,7 +1475,7 @@ void PlayerActions::actRequestSetAnnotationDialog(QList<CardItem *> selectedCard
emit requestSetAnnotationDialog(oldAnnotation); emit requestSetAnnotationDialog(oldAnnotation);
} }
void PlayerActions::actSetAnnotation(QList<CardItem *> selectedCards, const QString &annotation) void PlayerActions::actSetAnnotation(QList<CardState *> selectedCards, const QString &annotation)
{ {
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
for (auto card : selectedCards) { for (auto card : selectedCards) {
@ -1494,7 +1499,7 @@ void PlayerActions::actAttach()
card->drawAttachArrow(); card->drawAttachArrow();
} }
void PlayerActions::actUnattach(QList<CardItem *> selectedCards) void PlayerActions::actUnattach(QList<CardState *> selectedCards)
{ {
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
for (auto card : selectedCards) { for (auto card : selectedCards) {
@ -1510,17 +1515,17 @@ void PlayerActions::actUnattach(QList<CardItem *> selectedCards)
sendGameCommand(prepareGameCommand(commandList)); sendGameCommand(prepareGameCommand(commandList));
} }
void PlayerActions::actAddCardCounter(QList<CardItem *> selectedCards, int counterId) void PlayerActions::actAddCardCounter(QList<CardState *> selectedCards, int counterId)
{ {
offsetCardCounter(selectedCards, counterId, 1); offsetCardCounter(selectedCards, counterId, 1);
} }
void PlayerActions::actRemoveCardCounter(QList<CardItem *> selectedCards, int counterId) void PlayerActions::actRemoveCardCounter(QList<CardState *> selectedCards, int counterId)
{ {
offsetCardCounter(selectedCards, counterId, -1); offsetCardCounter(selectedCards, counterId, -1);
} }
void PlayerActions::offsetCardCounter(QList<CardItem *> selectedCards, int counterId, int offset) void PlayerActions::offsetCardCounter(QList<CardState *> selectedCards, int counterId, int offset)
{ {
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
for (auto card : selectedCards) { for (auto card : selectedCards) {
@ -1543,7 +1548,7 @@ void PlayerActions::offsetCardCounter(QList<CardItem *> selectedCards, int count
sendGameCommand(prepareGameCommand(commandList)); sendGameCommand(prepareGameCommand(commandList));
} }
void PlayerActions::actRequestSetCardCounterDialog(QList<CardItem *> selectedCards, int counterId) void PlayerActions::actRequestSetCardCounterDialog(QList<CardState *> selectedCards, int counterId)
{ {
// If a single card is selected, we show the old value in the dialog. Otherwise, we show "x" // If a single card is selected, we show the old value in the dialog. Otherwise, we show "x"
QString oldValueForDlg = "x"; QString oldValueForDlg = "x";
@ -1555,7 +1560,7 @@ void PlayerActions::actRequestSetCardCounterDialog(QList<CardItem *> selectedCar
emit requestSetCardCounterDialog(counterId, oldValueForDlg); emit requestSetCardCounterDialog(counterId, oldValueForDlg);
} }
void PlayerActions::actSetCardCounter(QList<CardItem *> selectedCards, int counterId, const QString &counterValue) void PlayerActions::actSetCardCounter(QList<CardState *> selectedCards, int counterId, const QString &counterValue)
{ {
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
for (auto card : selectedCards) { for (auto card : selectedCards) {
@ -1576,11 +1581,11 @@ void PlayerActions::actSetCardCounter(QList<CardItem *> selectedCards, int count
sendGameCommand(prepareGameCommand(commandList)); sendGameCommand(prepareGameCommand(commandList));
} }
void PlayerActions::actIncrementAllCardCounters(QList<CardItem *> cardsToUpdate) void PlayerActions::actIncrementAllCardCounters(QList<CardState *> 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()); cardsToUpdate = static_cast<QList<CardState *>>(player->getTableZone()->getCards());
} }
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
@ -1623,7 +1628,7 @@ static bool isUnwritableRevealZone(CardZoneLogic *zone)
return false; return false;
} }
void PlayerActions::playSelectedCards(QList<CardItem *> selectedCards, const bool faceDown) void PlayerActions::playSelectedCards(QList<CardState *> selectedCards, const bool faceDown)
{ {
// CardIds will get shuffled downwards when cards leave the deck. // CardIds will get shuffled downwards when cards leave the deck.
// We need to iterate through the cards in reverse order so cardIds don't get changed out from under us as we play // We need to iterate through the cards in reverse order so cardIds don't get changed out from under us as we play
@ -1638,27 +1643,27 @@ void PlayerActions::playSelectedCards(QList<CardItem *> selectedCards, const boo
} }
} }
void PlayerActions::actPlay(QList<CardItem *> selectedCards) void PlayerActions::actPlay(QList<CardState *> selectedCards)
{ {
playSelectedCards(selectedCards, false); playSelectedCards(selectedCards, false);
} }
void PlayerActions::actPlayFacedown(QList<CardItem *> selectedCards) void PlayerActions::actPlayFacedown(QList<CardState *> selectedCards)
{ {
playSelectedCards(selectedCards, true); playSelectedCards(selectedCards, true);
} }
void PlayerActions::actHide(QList<CardItem *> selectedCards) void PlayerActions::actHide(QList<CardState *> selectedCards)
{ {
for (const auto &item : selectedCards) { for (const auto &item : selectedCards) {
auto *card = static_cast<CardItem *>(item); auto *card = static_cast<CardState *>(item);
if (card && isUnwritableRevealZone(card->getZone())) { if (card && isUnwritableRevealZone(card->getZone())) {
card->getZone()->removeCard(card); card->getZone()->removeCard(card);
} }
} }
} }
void PlayerActions::actReveal(QList<CardItem *> selectedCards, QAction *action) void PlayerActions::actReveal(QList<CardState *> selectedCards, QAction *action)
{ {
const int otherPlayerId = action->data().toInt(); const int otherPlayerId = action->data().toInt();
@ -1749,9 +1754,9 @@ void PlayerActions::actRevealRandomGraveyardCard(int revealToPlayerId)
sendGameCommand(cmd); sendGameCommand(cmd);
} }
void PlayerActions::cardMenuAction(QList<CardItem *> selectedCards, CardMenuActionType type) void PlayerActions::cardMenuAction(QList<CardState *> selectedCards, CardMenuActionType type)
{ {
QList<CardItem *> cardList = selectedCards; QList<CardState *> cardList = selectedCards;
QList<const ::google::protobuf::Message *> commandList; QList<const ::google::protobuf::Message *> commandList;
if (type <= cmClone) { if (type <= cmClone) {

View file

@ -50,7 +50,7 @@ public:
PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd); PendingCommand *prepareGameCommand(const ::google::protobuf::Message &cmd);
PendingCommand *prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList); PendingCommand *prepareGameCommand(const QList<const ::google::protobuf::Message *> &cmdList);
void moveOneCardUntil(CardItem *card); void moveOneCardUntil(CardState *card);
void stopMoveTopCardsUntil(); void stopMoveTopCardsUntil();
[[nodiscard]] bool isMovingCardsUntil() const [[nodiscard]] bool isMovingCardsUntil() const
@ -92,7 +92,7 @@ signals:
public slots: public slots:
void setLastToken(CardInfoPtr cardInfo); void setLastToken(CardInfoPtr cardInfo);
void setLastTokenInfo(CardInfoPtr cardInfo); void setLastTokenInfo(CardInfoPtr cardInfo);
void playCard(CardItem *c, bool faceDown); void playCard(CardState *card, bool faceDown);
void playCardToTable(const CardItem *c, bool faceDown); void playCardToTable(const CardItem *c, bool faceDown);
void actUntapAll(); void actUntapAll();
@ -124,9 +124,9 @@ public slots:
void actMulliganMinusOne(); void actMulliganMinusOne();
void doMulligan(int number); void doMulligan(int number);
void actPlay(QList<CardItem *> selectedCards); void actPlay(QList<CardState *> selectedCards);
void actPlayFacedown(QList<CardItem *> selectedCards); void actPlayFacedown(QList<CardState *> selectedCards);
void actHide(QList<CardItem *> selectedCards); void actHide(QList<CardState *> selectedCards);
void actMoveTopCardToPlay(); void actMoveTopCardToPlay();
void actMoveTopCardToPlayFaceDown(); void actMoveTopCardToPlayFaceDown();
@ -183,40 +183,40 @@ public slots:
void actCreateAllRelatedCards(); void actCreateAllRelatedCards();
void actRequestMoveCardXCardsFromTopDialog(); void actRequestMoveCardXCardsFromTopDialog();
void actMoveCardXCardsFromTop(QList<CardItem *> selectedCards, int number); void actMoveCardXCardsFromTop(QList<CardState *> selectedCards, int number);
void actRemoveCardCounter(QList<CardItem *> selectedCards, int counterId); void actRemoveCardCounter(QList<CardState *> selectedCards, int counterId);
void actAddCardCounter(QList<CardItem *> selectedCards, int counterId); void actAddCardCounter(QList<CardState *> selectedCards, int counterId);
void actRequestSetCardCounterDialog(QList<CardItem *> selectedCards, int counterId); void actRequestSetCardCounterDialog(QList<CardState *> selectedCards, int counterId);
void actSetCardCounter(QList<CardItem *> selectedCards, int counterId, const QString &counterValue); void actSetCardCounter(QList<CardState *> selectedCards, int counterId, const QString &counterValue);
void actIncrementAllCardCounters(QList<CardItem *> cardsToUpdate); void actIncrementAllCardCounters(QList<CardState *> cardsToUpdate);
void actAttach(); void actAttach();
void actUnattach(QList<CardItem *> selectedCards); void actUnattach(QList<CardState *> selectedCards);
void actDrawArrow(); void actDrawArrow();
void actIncPT(QList<CardItem *> selectedCards, int deltaP, int deltaT); void actIncPT(QList<CardState *> selectedCards, int deltaP, int deltaT);
void actResetPT(QList<CardItem *> selectedCards); void actResetPT(QList<CardState *> selectedCards);
void actRequestSetPTDialog(QList<CardItem *> selectedCards); void actRequestSetPTDialog(QList<CardState *> selectedCards);
void actSetPT(QList<CardItem *> selectedCards, const QString &pt); void actSetPT(QList<CardState *> selectedCards, const QString &pt);
void actIncP(QList<CardItem *> selectedCards); void actIncP(QList<CardState *> selectedCards);
void actDecP(QList<CardItem *> selectedCards); void actDecP(QList<CardState *> selectedCards);
void actIncT(QList<CardItem *> selectedCards); void actIncT(QList<CardState *> selectedCards);
void actDecT(QList<CardItem *> selectedCards); void actDecT(QList<CardState *> selectedCards);
void actIncPT(QList<CardItem *> selectedCards); void actIncPT(QList<CardState *> selectedCards);
void actDecPT(QList<CardItem *> selectedCards); void actDecPT(QList<CardState *> selectedCards);
void actFlowP(QList<CardItem *> selectedCards); void actFlowP(QList<CardState *> selectedCards);
void actFlowT(QList<CardItem *> selectedCards); void actFlowT(QList<CardState *> selectedCards);
void actReduceLifeByPower(QList<CardItem *> selectedCards); void actReduceLifeByPower(QList<CardState *> selectedCards);
void actRequestSetAnnotationDialog(QList<CardItem *> selectedCards); void actRequestSetAnnotationDialog(QList<CardState *> selectedCards);
void actSetAnnotation(QList<CardItem *> selectedCards, const QString &annotation); void actSetAnnotation(QList<CardState *> selectedCards, const QString &annotation);
void actReveal(QList<CardItem *> selectedCards, QAction *action); void actReveal(QList<CardState *> selectedCards, QAction *action);
void actRevealHand(int revealToPlayerId); void actRevealHand(int revealToPlayerId);
void actRevealRandomHandCard(int revealToPlayerId); void actRevealRandomHandCard(int revealToPlayerId);
void actRevealLibrary(int revealToPlayerId); void actRevealLibrary(int revealToPlayerId);
void actSortHand(); void actSortHand();
void cardMenuAction(QList<CardItem *> selectedCards, CardMenuActionType type); void cardMenuAction(QList<CardState *> selectedCards, CardMenuActionType type);
private: private:
PlayerLogic *player; PlayerLogic *player;
@ -242,12 +242,12 @@ private:
CardRelationType attach = CardRelationType::DoesNotAttach, CardRelationType attach = CardRelationType::DoesNotAttach,
bool persistent = false); bool persistent = false);
void playSelectedCards(QList<CardItem *> selectedCards, bool faceDown = false); void playSelectedCards(QList<CardState *> selectedCards, bool faceDown = false);
void cmdSetTopCard(Command_MoveCard &cmd); void cmdSetTopCard(Command_MoveCard &cmd);
void cmdSetBottomCard(Command_MoveCard &cmd); void cmdSetBottomCard(Command_MoveCard &cmd);
void offsetCardCounter(QList<CardItem *> selectedCards, int counterId, int offset); void offsetCardCounter(QList<CardState *> selectedCards, int counterId, int offset);
}; };
#endif // COCKATRICE_PLAYER_ACTIONS_H #endif // COCKATRICE_PLAYER_ACTIONS_H

View file

@ -137,7 +137,7 @@ void PlayerEventHandler::eventCreateToken(const Event_CreateToken &event)
} }
CardRef cardRef = {QString::fromStdString(event.card_name()), QString::fromStdString(event.card_provider_id())}; CardRef cardRef = {QString::fromStdString(event.card_name()), QString::fromStdString(event.card_provider_id())};
CardItem *card = new CardItem(player, nullptr, cardRef, event.card_id()); CardState *card = new CardState(player, cardRef, event.card_id(), zone);
// use db PT if not provided in event and not face-down // use db PT if not provided in event and not face-down
if (!QString::fromStdString(event.pt()).isEmpty()) { if (!QString::fromStdString(event.pt()).isEmpty()) {
card->setPT(QString::fromStdString(event.pt())); card->setPT(QString::fromStdString(event.pt()));
@ -175,7 +175,7 @@ void PlayerEventHandler::eventSetCardAttr(const Event_SetCardAttr &event,
emit logSetTapped(player, nullptr, event.attr_value() == "1"); 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;
@ -185,7 +185,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,
@ -246,7 +246,7 @@ 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;
} }
@ -322,12 +322,12 @@ 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;
} }
if (startZone != targetZone) { if (startZone != targetZone) {
card->deleteCardInfoPopup(); // TODO card->deleteCardInfoPopup();
} }
if (event.has_card_name()) { if (event.has_card_name()) {
QString name = QString::fromStdString(event.card_name()); QString name = QString::fromStdString(event.card_name());
@ -337,22 +337,22 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
} }
if (card->getAttachedTo() && (startZone != targetZone)) { if (card->getAttachedTo() && (startZone != targetZone)) {
CardItem *parentCard = card->getAttachedTo(); CardState *parentCard = card->getAttachedTo();
card->setAttachedTo(nullptr); card->setAttachedTo(nullptr);
parentCard->getZone()->reorganizeCards(); parentCard->getZone()->reorganizeCards();
} }
card->deleteDragItem(); // TODO: card->deleteDragItem();
card->setId(event.new_card_id()); card->setId(event.new_card_id());
card->setFaceDown(event.face_down()); card->setFaceDown(event.face_down());
if (startZone != targetZone) { if (startZone != targetZone) {
card->setBeingPointedAt(false); /* TODO card->setBeingPointedAt(false);
card->setHovered(false); card->setHovered(false);*/
const QList<CardItem *> &attachedCards = card->getAttachedCards(); const QList<CardState *> &attachedCards = card->getAttachedCards();
for (auto attachedCard : attachedCards) { for (auto attachedCard : attachedCards) {
emit targetZone->cardAdded(attachedCard); emit targetZone->cardAdded(attachedCard, 0, 0);
} }
if (startZone->getPlayer() != targetZone->getPlayer()) { if (startZone->getPlayer() != targetZone->getPlayer()) {
@ -385,7 +385,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,12 +408,12 @@ 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;
} }
QList<CardItem *> attachedCards = card->getAttachedCards(); QList<CardState *> attachedCards = card->getAttachedCards();
// This list is always empty except for buggy server implementations. // This list is always empty except for buggy server implementations.
for (auto &attachedCard : attachedCards) { for (auto &attachedCard : attachedCards) {
attachedCard->setAttachedTo(nullptr); attachedCard->setAttachedTo(nullptr);
@ -429,7 +429,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) {
@ -445,12 +445,12 @@ 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;
} }
CardItem *oldParent = startCard->getAttachedTo(); CardState *oldParent = startCard->getAttachedTo();
startCard->setAttachedTo(targetCard); startCard->setAttachedTo(targetCard);
@ -479,7 +479,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});
@ -527,7 +527,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

@ -13,7 +13,7 @@
#include <libcockatrice/protocol/pb/game_event.pb.h> #include <libcockatrice/protocol/pb/game_event.pb.h>
#include <libcockatrice/protocol/pb/game_event_context.pb.h> #include <libcockatrice/protocol/pb/game_event_context.pb.h>
class CardItem; class CardState;
class CardZoneLogic; class CardZoneLogic;
class PlayerLogic; class PlayerLogic;
class Event_AttachCard; class Event_AttachCard;
@ -56,7 +56,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,
@ -66,11 +66,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,
@ -82,8 +82,8 @@ signals:
bool isLentToAnotherPlayer = false); bool isLentToAnotherPlayer = false);
void logAlwaysRevealTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal); void logAlwaysRevealTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal);
void logAlwaysLookAtTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal); void logAlwaysLookAtTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal);
void cardZoneChanged(CardItem *card, bool sameZone); void cardZoneChanged(CardState *card, bool sameZone);
void requestCardMenuUpdate(const CardItem *card); void requestCardMenuUpdate(const CardState *card);
public: public:
PlayerEventHandler(PlayerLogic *player); PlayerEventHandler(PlayerLogic *player);
@ -119,7 +119,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

@ -168,12 +168,12 @@ 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 CardState(this), false, -1);
} }
} else { } else {
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);
auto *card = new CardItem(this); auto *card = new CardState(this);
card->processCardInfo(cardInfo); card->processCardInfo(cardInfo);
zone->addCard(card, false, cardInfo.x(), cardInfo.y()); zone->addCard(card, false, cardInfo.x(), cardInfo.y());
} }
@ -207,8 +207,8 @@ void PlayerLogic::processCardAttachment(const ServerInfo_Player &info)
for (int j = 0; j < cardListSize; ++j) { 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) {
@ -227,12 +227,12 @@ void PlayerLogic::processCardAttachment(const ServerInfo_Player &info)
} }
} }
void PlayerLogic::addCard(CardItem *card) void PlayerLogic::addCard(CardState *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;

View file

@ -41,14 +41,12 @@ class AbstractGame;
class ArrowItem; class ArrowItem;
class ArrowTarget; class ArrowTarget;
class CardDatabase; class CardDatabase;
class CardZone;
class CommandContainer; class CommandContainer;
class GameCommand; class GameCommand;
class GameEvent; class GameEvent;
class PlayerInfo; class PlayerInfo;
class PlayerEventHandler; class PlayerEventHandler;
class PlayerActions; class PlayerActions;
class PlayerMenu;
class QAction; class QAction;
class QMenu; class QMenu;
class ServerInfo_Arrow; class ServerInfo_Arrow;
@ -72,8 +70,8 @@ signals:
const QList<const ServerInfo_Card *> &cardList, const QList<const ServerInfo_Card *> &cardList,
bool withWritePermission); bool withWritePermission);
void deckChanged(); void deckChanged();
void newCardAdded(AbstractCardItem *card); void newCardAdded(AbstractCardState *card);
void requestCardMenuUpdate(const CardItem *card); void requestCardMenuUpdate(const CardState *card);
void counterAdded(CounterState *state); void counterAdded(CounterState *state);
void counterRemoved(int counterId); void counterRemoved(int counterId);
void rearrangeCounters(); void rearrangeCounters();
@ -103,8 +101,8 @@ public:
void processPlayerInfo(const ServerInfo_Player &info); void processPlayerInfo(const ServerInfo_Player &info);
void processCardAttachment(const ServerInfo_Player &info); void processCardAttachment(const ServerInfo_Player &info);
void addCard(CardItem *c); void addCard(CardState *c);
void deleteCard(CardItem *c); void deleteCard(CardState *c);
bool clearCardsToDelete(); bool clearCardsToDelete();
@ -242,7 +240,7 @@ private:
QMap<int, CounterState *> counters; QMap<int, CounterState *> counters;
bool dialogSemaphore; bool dialogSemaphore;
QList<CardItem *> cardsToDelete; QList<CardState *> cardsToDelete;
}; };
class AnnotationDialog : public QInputDialog class AnnotationDialog : public QInputDialog

View file

@ -35,7 +35,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(CardZoneLog) << "CardZoneLogic::addCard() card is null; this shouldn't normally happen"; qCWarning(CardZoneLog) << "CardZoneLogic::addCard() card is null; this shouldn't normally happen";
@ -44,7 +44,8 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x,
for (auto *view : views) { for (auto *view : views) {
if (qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->prepareAddCard(x)) { if (qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->prepareAddCard(x)) {
auto copy = new CardItem(player, nullptr, card->getCardRef(), card->getId());
auto copy = new CardState(player, card->getCardRef(), card->getId());
copy->setFaceDown(card->getFaceDown()); copy->setFaceDown(card->getFaceDown());
view->getLogic()->addCard(copy, reorganize, x, y); view->getLogic()->addCard(copy, reorganize, x, y);
@ -52,7 +53,7 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x,
} }
card->setZone(this); card->setZone(this);
emit cardAdded(card); emit cardAdded(card, x, y);
addCardImpl(card, x, y); addCardImpl(card, x, y);
if (reorganize) { if (reorganize) {
@ -62,7 +63,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
@ -85,18 +86,20 @@ CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->removeCard(position, toNewZone); qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->removeCard(position, toNewZone);
} }
CardItem *c = cards.takeAt(position); CardState *c = cards.takeAt(position);
c->setId(cardId); c->setId(cardId);
emit cardRemoved(c, c->getGridPos().x(), c->getGridPos().y());
emit reorganizeCards(); emit reorganizeCards();
emit cardCountChanged(); emit cardCountChanged();
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(CardZoneLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found"; qCWarning(CardZoneLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found";
return nullptr; return nullptr;
@ -110,7 +113,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(CardZoneLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen"; qCWarning(CardZoneLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen";
@ -119,6 +122,8 @@ void CardZoneLogic::removeCard(CardItem *card)
cards.removeOne(card); cards.removeOne(card);
emit cardRemoved(card, card->getGridPos().x(), card->getGridPos().y());
emit reorganizeCards(); emit reorganizeCards();
emit cardCountChanged(); emit cardCountChanged();
player->deleteCard(card); player->deleteCard(card);
@ -159,17 +164,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<CardState *> &attachedCards = card->getAttachedCards();
for (CardItem *attachedCard : attachedCards) { for (CardState *attachedCard : attachedCards) {
emit attachedCard->getZone()->cardAdded(attachedCard); emit attachedCard->getZone()->cardAdded(attachedCard, 0, 0);
} }
} }
// 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

@ -9,6 +9,7 @@
#include "../../client/translation.h" #include "../../client/translation.h"
#include "../board/card_list.h" #include "../board/card_list.h"
#include "../board/card_state.h"
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QObject> #include <QObject>
@ -27,7 +28,8 @@ class CardZoneLogic : public QObject
Q_OBJECT Q_OBJECT
signals: signals:
void cardAdded(CardItem *addedCard); void cardAdded(CardState *addedCard, int x, int y);
void cardRemoved(CardState *removedCard, int x, int y);
void cardCountChanged(); void cardCountChanged();
void reorganizeCards(); void reorganizeCards();
void updateGraphics(); void updateGraphics();
@ -42,14 +44,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);
} }
@ -113,7 +115,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

@ -13,7 +13,7 @@ HandZoneLogic::HandZoneLogic(PlayerLogic *_player,
{ {
} }
void HandZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) void HandZoneLogic::addCardImpl(CardState *card, int x, int /*y*/)
{ {
CardZoneAlgorithms::addCardToList(cards, card, x, false); CardZoneAlgorithms::addCardToList(cards, card, x, false);
} }

View file

@ -20,7 +20,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

@ -12,15 +12,13 @@ PileZoneLogic::PileZoneLogic(PlayerLogic *_player,
{ {
} }
void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) void PileZoneLogic::addCardImpl(CardState *card, int x, int /*y*/)
{ {
connect(card, &CardItem::sigPixmapUpdated, this, &PileZoneLogic::callUpdate);
// if x is negative set it to add at end // if x 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();
} }
cards.insert(x, card); cards.insert(x, card);
card->setPos(0, 0);
if (!contentsKnown()) { if (!contentsKnown()) {
card->setCardRef({}); card->setCardRef({});
card->setId(-1); card->setId(-1);
@ -30,5 +28,5 @@ void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
} }
} }
card->setVisible(false); card->setVisible(false);
card->resetState(); card->resetState(false);
} }

View file

@ -13,9 +13,6 @@ class PileZoneLogic : public CardZoneLogic
Q_OBJECT Q_OBJECT
signals:
void callUpdate();
public: public:
PileZoneLogic(PlayerLogic *_player, PileZoneLogic(PlayerLogic *_player,
const QString &_name, const QString &_name,
@ -25,7 +22,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

@ -13,7 +13,7 @@ StackZoneLogic::StackZoneLogic(PlayerLogic *_player,
{ {
} }
void StackZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/) void StackZoneLogic::addCardImpl(CardState *card, int x, int /*y*/)
{ {
CardZoneAlgorithms::addCardToList(cards, card, x, true); CardZoneAlgorithms::addCardToList(cards, card, x, true);
} }

View file

@ -20,7 +20,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

@ -12,7 +12,7 @@ TableZoneLogic::TableZoneLogic(PlayerLogic *_player,
{ {
} }
void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _y) void TableZoneLogic::addCardImpl(CardState *card, int _x, int _y)
{ {
cards.append(card); cards.append(card);
if (!card->getFaceDown() && card->getPT().isEmpty()) { if (!card->getFaceDown() && card->getPT().isEmpty()) {
@ -21,13 +21,14 @@ void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _y)
if (card->getCardInfo().getUiAttributes().cipt && card->getCardInfo().getUiAttributes().landscapeOrientation) { if (card->getCardInfo().getUiAttributes().cipt && card->getCardInfo().getUiAttributes().landscapeOrientation) {
card->setDoesntUntap(true); card->setDoesntUntap(true);
} }
card->setGridPoint(QPoint(_x, _y)); card->setGridPoint(QPoint(_x, _y));
card->setVisible(true); card->setVisible(true);
} }
CardItem *TableZoneLogic::takeCard(int position, int cardId, bool toNewZone) CardState *TableZoneLogic::takeCard(int position, int cardId, bool toNewZone)
{ {
CardItem *result = CardZoneLogic::takeCard(position, cardId); CardState *result = CardZoneLogic::takeCard(position, cardId);
if (toNewZone) { if (toNewZone) {
emit contentSizeChanged(); emit contentSizeChanged();

View file

@ -24,7 +24,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;
/** /**
* @brief Removes a card from view. * @brief Removes a card from view.
@ -34,7 +34,7 @@ protected:
* @param toNewZone Whether the destination of the card is not the same as the starting zone. Defaults to true * @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 CardItem that has been removed
*/ */
CardItem *takeCard(int position, int cardId, bool toNewZone = true) override; CardState *takeCard(int position, int cardId, bool toNewZone = true) override;
}; };
#endif // COCKATRICE_TABLE_ZONE_LOGIC_H #endif // COCKATRICE_TABLE_ZONE_LOGIC_H

View file

@ -68,7 +68,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
@ -137,7 +137,7 @@ void ZoneViewZoneLogic::removeCard(int position, bool toNewZone)
return; return;
} }
CardItem *card = cards.takeAt(position); CardState *card = cards.takeAt(position);
card->deleteLater(); card->deleteLater();
// 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

View file

@ -65,7 +65,7 @@ public:
} }
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

@ -25,7 +25,7 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
setCursor(Qt::ClosedHandCursor); setCursor(Qt::ClosedHandCursor);
setZValue(ZValues::DRAG_ITEM); setZValue(ZValues::DRAG_ITEM);
} }
if (item->getTapped()) { if (item->getState()->getTapped()) {
setTransform(QTransform() setTransform(QTransform()
.translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F) .translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F)
.rotate(90) .rotate(90)

View file

@ -13,16 +13,19 @@
#include <libcockatrice/card/database/card_database.h> #include <libcockatrice/card/database/card_database.h>
#include <libcockatrice/card/database/card_database_manager.h> #include <libcockatrice/card/database/card_database_manager.h>
AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id) AbstractCardItem::AbstractCardItem(AbstractCardState *_state, QGraphicsItem *parent)
: ArrowTarget(_owner, parent), id(_id), cardRef(cardRef), tapped(false), facedown(false), tapAngle(0), : ArrowTarget(_state->getOwner(), parent), cardState(_state), tapAngle(0), bgColor(Qt::transparent),
bgColor(Qt::transparent), isHovered(false), realZValue(0) isHovered(false), realZValue(0)
{ {
setCursor(Qt::OpenHandCursor); setCursor(Qt::OpenHandCursor);
setFlag(ItemIsSelectable); setFlag(ItemIsSelectable);
setCacheMode(DeviceCoordinateCache); setCacheMode(DeviceCoordinateCache);
connect(_state, &AbstractCardState::cardInfoRefreshed, this, &AbstractCardItem::onCardInfoRefreshed);
connect(_state, &AbstractCardState::colorChanged, this, &AbstractCardItem::onCardColorChanged);
connect(_state, &AbstractCardState::faceDownChanged, this, [this]() { update(); });
connect(&SettingsCache::instance(), &SettingsCache::displayCardNamesChanged, this, [this] { update(); }); connect(&SettingsCache::instance(), &SettingsCache::displayCardNamesChanged, this, [this] { update(); });
refreshCardInfo();
connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) { connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) {
Q_UNUSED(_roundCardCorners); Q_UNUSED(_roundCardCorners);
@ -34,7 +37,7 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef
AbstractCardItem::~AbstractCardItem() AbstractCardItem::~AbstractCardItem()
{ {
emit deleteCardInfoPopup(cardRef.name); // TODO emit deleteCardInfoPopup(cardRef.name);
} }
QRectF AbstractCardItem::boundingRect() const QRectF AbstractCardItem::boundingRect() const
@ -56,32 +59,6 @@ void AbstractCardItem::pixmapUpdated()
emit sigPixmapUpdated(); emit sigPixmapUpdated();
} }
void AbstractCardItem::refreshCardInfo()
{
exactCard = CardDatabaseManager::query()->getCard(cardRef);
if (!exactCard && !cardRef.name.isEmpty()) {
CardInfo::UiAttributes attributes = {.tableRow = -1};
auto info = CardInfo::newInstance(cardRef.name, "", true, {}, {}, {}, {}, attributes);
exactCard = ExactCard(info);
}
if (exactCard) {
connect(exactCard.getCardPtr().data(), &CardInfo::pixmapUpdated, this, &AbstractCardItem::pixmapUpdated);
}
cacheBgColor();
update();
}
/**
* Convenience method to get the CardInfo of the exactCard
* @return A const reference to the CardInfo, or an empty CardInfo if card was null
*/
const CardInfo &AbstractCardItem::getCardInfo() const
{
return exactCard.getInfo();
}
void AbstractCardItem::setRealZValue(qreal _zValue) void AbstractCardItem::setRealZValue(qreal _zValue)
{ {
realZValue = _zValue; realZValue = _zValue;
@ -124,13 +101,13 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
QPixmap translatedPixmap; QPixmap translatedPixmap;
bool paintImage = true; bool paintImage = true;
if (facedown || cardRef.name.isEmpty()) { if (getState()->getFaceDown() || getState()->getName().isEmpty()) {
// never reveal card color, always paint the card back // never reveal card color, always paint the card back
CardPictureLoader::getCardBackPixmap(translatedPixmap, translatedSize.toSize()); CardPictureLoader::getCardBackPixmap(translatedPixmap, translatedSize.toSize());
} else { } else {
// don't even spend time trying to load the picture if our size is too small // don't even spend time trying to load the picture if our size is too small
if (translatedSize.width() > 10) { if (translatedSize.width() > 10) {
CardPictureLoader::getPixmap(translatedPixmap, exactCard, translatedSize.toSize()); CardPictureLoader::getPixmap(translatedPixmap, getState()->getCard(), translatedSize.toSize());
if (translatedPixmap.isNull()) { if (translatedPixmap.isNull()) {
paintImage = false; paintImage = false;
} }
@ -151,21 +128,21 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
painter->drawPath(shape()); painter->drawPath(shape());
} }
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) { if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || getState()->getFaceDown()) {
painter->save(); painter->save();
transformPainter(painter, translatedSize, angle); transformPainter(painter, translatedSize, angle);
painter->setPen(Qt::white); painter->setPen(Qt::white);
painter->setBackground(Qt::black); painter->setBackground(Qt::black);
painter->setBackgroundMode(Qt::OpaqueMode); painter->setBackgroundMode(Qt::OpaqueMode);
QString nameStr; QString nameStr;
if (facedown) { if (getState()->getFaceDown()) {
nameStr = "# " + QString::number(id); nameStr = "# " + QString::number(getState()->getId());
} else { } else {
QString prefix = ""; QString prefix = "";
if (SettingsCache::instance().debug().getShowCardId()) { if (SettingsCache::instance().debug().getShowCardId()) {
prefix = "#" + QString::number(id) + " "; prefix = "#" + QString::number(getState()->getId()) + " ";
} }
nameStr = prefix + cardRef.name; nameStr = prefix + getState()->getName();
} }
painter->drawText(QRectF(3 * scaleFactor, 3 * scaleFactor, translatedSize.width() - 6 * scaleFactor, painter->drawText(QRectF(3 * scaleFactor, 3 * scaleFactor, translatedSize.width() - 6 * scaleFactor,
translatedSize.height() - 6 * scaleFactor), translatedSize.height() - 6 * scaleFactor),
@ -201,21 +178,6 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
painter->restore(); painter->restore();
} }
void AbstractCardItem::setCardRef(const CardRef &_cardRef)
{
if (cardRef == _cardRef) {
return;
}
emit deleteCardInfoPopup(cardRef.name);
if (exactCard) {
disconnect(exactCard.getCardPtr().data(), nullptr, this, nullptr);
}
cardRef = _cardRef;
refreshCardInfo();
}
void AbstractCardItem::setHovered(bool _hovered) void AbstractCardItem::setHovered(bool _hovered)
{ {
if (isHovered == _hovered) { if (isHovered == _hovered) {
@ -239,9 +201,18 @@ void AbstractCardItem::setHovered(bool _hovered)
update(); update();
} }
void AbstractCardItem::setColor(const QString &_color) void AbstractCardItem::onCardInfoRefreshed()
{
if (getState()->getCard()) {
connect(getState()->getCard().getCardPtr().data(), &CardInfo::pixmapUpdated, this,
&AbstractCardItem::pixmapUpdated);
}
onCardColorChanged();
}
void AbstractCardItem::onCardColorChanged()
{ {
color = _color;
cacheBgColor(); cacheBgColor();
update(); update();
} }
@ -249,10 +220,10 @@ void AbstractCardItem::setColor(const QString &_color)
void AbstractCardItem::cacheBgColor() void AbstractCardItem::cacheBgColor()
{ {
QChar colorChar; QChar colorChar;
if (color.isEmpty()) { if (getState()->getColor().isEmpty()) {
colorChar = exactCard.getInfo().getColorChar(); colorChar = getState()->getCard().getInfo().getColorChar();
} else { } else {
colorChar = color.at(0); colorChar = getState()->getColor().at(0);
} }
switch (colorChar.toLower().toLatin1()) { switch (colorChar.toLower().toLatin1()) {
@ -280,35 +251,10 @@ void AbstractCardItem::cacheBgColor()
} }
} }
void AbstractCardItem::setTapped(bool _tapped, bool canAnimate)
{
if (tapped == _tapped) {
return;
}
tapped = _tapped;
if (SettingsCache::instance().getTapAnimation() && canAnimate) {
static_cast<GameScene *>(scene())->registerAnimationItem(this);
} else {
tapAngle = tapped ? 90 : 0;
setTransform(QTransform()
.translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F)
.rotate(tapAngle)
.translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F));
update();
}
}
void AbstractCardItem::setFaceDown(bool _facedown)
{
facedown = _facedown;
update();
}
void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event) void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
if ((event->modifiers() & Qt::AltModifier) && event->button() == Qt::LeftButton) { if ((event->modifiers() & Qt::AltModifier) && event->button() == Qt::LeftButton) {
emit cardShiftClicked(cardRef.name); emit cardShiftClicked(getState()->getName());
} else if ((event->modifiers() & Qt::ControlModifier)) { } else if ((event->modifiers() & Qt::ControlModifier)) {
setSelected(!isSelected()); setSelected(!isSelected());
} else if (!isSelected()) { } else if (!isSelected()) {
@ -318,7 +264,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
setCursor(Qt::ClosedHandCursor); setCursor(Qt::ClosedHandCursor);
} else if (event->button() == Qt::MiddleButton) { } else if (event->button() == Qt::MiddleButton) {
emit showCardInfoPopup(event->screenPos(), cardRef); emit showCardInfoPopup(event->screenPos(), getState()->getCardRef());
} }
event->accept(); event->accept();
} }
@ -326,7 +272,7 @@ void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
if (event->button() == Qt::MiddleButton) { if (event->button() == Qt::MiddleButton) {
emit deleteCardInfoPopup(cardRef.name); emit deleteCardInfoPopup(getState()->getName());
} }
// This function ensures the parent function doesn't mess around with our selection. // This function ensures the parent function doesn't mess around with our selection.

View file

@ -7,6 +7,7 @@
#ifndef ABSTRACTCARDITEM_H #ifndef ABSTRACTCARDITEM_H
#define ABSTRACTCARDITEM_H #define ABSTRACTCARDITEM_H
#include "../../game/board/abstract_card_state.h"
#include "../card_dimensions.h" #include "../card_dimensions.h"
#include "arrow_target.h" #include "arrow_target.h"
#include "graphics_item_type.h" #include "graphics_item_type.h"
@ -20,13 +21,8 @@ class AbstractCardItem : public ArrowTarget
{ {
Q_OBJECT Q_OBJECT
protected: protected:
ExactCard exactCard; AbstractCardState *cardState;
int id;
CardRef cardRef;
bool tapped;
bool facedown;
int tapAngle; int tapAngle;
QString color;
QColor bgColor; QColor bgColor;
private: private:
@ -35,9 +31,6 @@ private:
private slots: private slots:
void pixmapUpdated(); void pixmapUpdated();
public slots:
void refreshCardInfo();
signals: signals:
void hovered(AbstractCardItem *card); void hovered(AbstractCardItem *card);
void showCardInfoPopup(const QPoint &pos, const CardRef &cardRef); void showCardInfoPopup(const QPoint &pos, const CardRef &cardRef);
@ -59,71 +52,33 @@ public:
{ {
return Type; return Type;
} }
explicit AbstractCardItem(QGraphicsItem *parent = nullptr, explicit AbstractCardItem(AbstractCardState *_state, QGraphicsItem *parent = nullptr);
const CardRef &cardRef = {},
PlayerLogic *_owner = nullptr,
int _id = -1);
~AbstractCardItem() override; ~AbstractCardItem() override;
QRectF boundingRect() const override; QRectF boundingRect() const override;
QPainterPath shape() const override; QPainterPath shape() const override;
QSizeF getTranslatedSize(QPainter *painter) const; QSizeF getTranslatedSize(QPainter *painter) const;
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle); void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
ExactCard getCard() const
{
return exactCard;
}
const CardInfo &getCardInfo() const;
int getId() const
{
return id;
}
void setId(int _id)
{
id = _id;
}
QString getName() const
{
return cardRef.name;
}
QString getProviderId() const
{
return cardRef.providerId;
}
void setCardRef(const CardRef &_cardRef);
CardRef getCardRef() const
{
return cardRef;
}
qreal getRealZValue() const qreal getRealZValue() const
{ {
return realZValue; return realZValue;
} }
void setRealZValue(qreal _zValue); void setRealZValue(qreal _zValue);
void setHovered(bool _hovered); void setHovered(bool _hovered);
void onCardInfoRefreshed();
void onCardColorChanged();
bool getIsHovered() const bool getIsHovered() const
{ {
return isHovered; return isHovered;
} }
QString getColor() const
{
return color;
}
void setColor(const QString &_color);
bool getTapped() const
{
return tapped;
}
void setTapped(bool _tapped, bool canAnimate = false);
bool getFaceDown() const
{
return facedown;
}
void setFaceDown(bool _facedown);
void processHoverEvent(); void processHoverEvent();
void deleteCardInfoPopup() void deleteCardInfoPopup()
{ {
emit deleteCardInfoPopup(cardRef.name); // emit deleteCardInfoPopup(cardRef.name);
}
AbstractCardState *getState() const
{
return cardState;
} }
protected: protected:

View file

@ -237,19 +237,19 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
return; return;
} }
CardZoneLogic *startZone = startCard->getZone(); CardZoneLogic *startZone = startCard->getState()->getZone();
Command_CreateArrow cmd; Command_CreateArrow cmd;
cmd.mutable_arrow_color()->CopyFrom(convertQColorToColor(data->color)); cmd.mutable_arrow_color()->CopyFrom(convertQColorToColor(data->color));
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId()); cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_start_zone(startZone->getName().toStdString()); cmd.set_start_zone(startZone->getName().toStdString());
cmd.set_start_card_id(startCard->getId()); cmd.set_start_card_id(startCard->getState()->getId());
if (auto *targetCard = qgraphicsitem_cast<CardItem *>(targetItem)) { if (auto *targetCard = qgraphicsitem_cast<CardItem *>(targetItem)) {
CardZoneLogic *targetZone = targetCard->getZone(); CardZoneLogic *targetZone = targetCard->getState()->getZone();
cmd.set_target_player_id(targetZone->getPlayer()->getPlayerInfo()->getId()); cmd.set_target_player_id(targetZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_target_zone(targetZone->getName().toStdString()); cmd.set_target_zone(targetZone->getName().toStdString());
cmd.set_target_card_id(targetCard->getId()); cmd.set_target_card_id(targetCard->getState()->getId());
} else if (auto *targetPlayer = qgraphicsitem_cast<PlayerTarget *>(targetItem)) { } else if (auto *targetPlayer = qgraphicsitem_cast<PlayerTarget *>(targetItem)) {
cmd.set_target_player_id(targetPlayer->getOwner()->getPlayerInfo()->getId()); cmd.set_target_player_id(targetPlayer->getOwner()->getPlayerInfo()->getId());
} else { } else {
@ -260,11 +260,11 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
// if the card is in hand then we will move the card to stack or table as part of drawing the arrow // if the card is in hand then we will move the card to stack or table as part of drawing the arrow
if (startZone->getName() == ZoneNames::HAND) { if (startZone->getName() == ZoneNames::HAND) {
startCard->playCard(false); startCard->playCard(false);
CardInfoPtr ci = startCard->getCard().getCardPtr(); CardInfoPtr ci = startCard->getState()->getCard().getCardPtr();
bool playToStack = SettingsCache::instance().getPlayToStack(); bool playToStack = SettingsCache::instance().getPlayToStack();
if (ci && ((!playToStack && ci->getUiAttributes().tableRow == 3) || if (ci && ((!playToStack && ci->getUiAttributes().tableRow == 3) ||
(playToStack && ci->getUiAttributes().tableRow != 0 && (playToStack && ci->getUiAttributes().tableRow != 0 &&
startCard->getZone()->getName() != ZoneNames::STACK))) { startCard->getState()->getZone()->getName() != ZoneNames::STACK))) {
cmd.set_start_zone(ZoneNames::STACK); cmd.set_start_zone(ZoneNames::STACK);
} else { } else {
cmd.set_start_zone(playToStack ? ZoneNames::STACK : ZoneNames::TABLE); cmd.set_start_zone(playToStack ? ZoneNames::STACK : ZoneNames::TABLE);
@ -373,20 +373,20 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
void ArrowAttachItem::attachCards(CardItem *startCard, const CardItem *targetCard) void ArrowAttachItem::attachCards(CardItem *startCard, const CardItem *targetCard)
{ {
if (targetCard->getAttachedTo() || targetCard->getZone()->getName() != ZoneNames::TABLE) { if (targetCard->getState()->getAttachedTo() || targetCard->getState()->getZone()->getName() != ZoneNames::TABLE) {
return; return;
} }
// move card onto table first if attaching from some other zone // move card onto table first if attaching from some other zone
if (startCard->getZone()->getName() != ZoneNames::TABLE) { if (startCard->getState()->getZone()->getName() != ZoneNames::TABLE) {
player->getPlayerActions()->playCardToTable(startCard, false); player->getPlayerActions()->playCardToTable(startCard, false);
} }
Command_AttachCard cmd; Command_AttachCard cmd;
cmd.set_start_zone(ZoneNames::TABLE); cmd.set_start_zone(ZoneNames::TABLE);
cmd.set_card_id(startCard->getId()); cmd.set_card_id(startCard->getState()->getId());
cmd.set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerInfo()->getId()); cmd.set_target_player_id(targetCard->getState()->getZone()->getPlayer()->getPlayerInfo()->getId());
cmd.set_target_zone(targetCard->getZone()->getName().toStdString()); cmd.set_target_zone(targetCard->getState()->getZone()->getName().toStdString());
cmd.set_target_card_id(targetCard->getId()); cmd.set_target_card_id(targetCard->getState()->getId());
player->getPlayerActions()->sendGameCommand(cmd); player->getPlayerActions()->sendGameCommand(cmd);
} }

View file

@ -119,8 +119,9 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
sc->removeItem(this); sc->removeItem(this);
QList<CardDragItem *> dragItemList; QList<CardDragItem *> dragItemList;
CardZoneLogic *startZone = static_cast<CardItem *>(item)->getZone(); CardZoneLogic *startZone = static_cast<CardItem *>(item)->getState()->getZone();
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone->getLogic()))) { if (currentZone &&
!(static_cast<CardItem *>(item)->getState()->getAttachedTo() && (startZone == currentZone->getLogic()))) {
if (!occupied) { if (!occupied) {
dragItemList.append(this); dragItemList.append(this);
} }
@ -128,7 +129,8 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
for (int i = 0; i < childDrags.size(); i++) { for (int i = 0; i < childDrags.size(); i++) {
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]); CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
if (!occupied && if (!occupied &&
!(static_cast<CardItem *>(c->item)->getAttachedTo() && (startZone == currentZone->getLogic())) && !(static_cast<CardItem *>(c->item)->getState()->getAttachedTo() &&
(startZone == currentZone->getLogic())) &&
!c->occupied) { !c->occupied) {
dragItemList.append(c); dragItemList.append(c);
} }

View file

@ -20,20 +20,16 @@
#include <libcockatrice/card/card_info.h> #include <libcockatrice/card/card_info.h>
#include <libcockatrice/protocol/pb/serverinfo_card.pb.h> #include <libcockatrice/protocol/pb/serverinfo_card.pb.h>
CardItem::CardItem(PlayerLogic *_owner, CardItem::CardItem(CardState *_state, CardZone *parent)
QGraphicsItem *parent, : AbstractCardItem(_state, parent), state(_state), zone(parent), dragItem(nullptr)
const CardRef &cardRef,
int _cardid,
CardZoneLogic *_zone)
: AbstractCardItem(parent, cardRef, _owner, _cardid), state(new CardState(this, _zone)), dragItem(nullptr)
{ {
owner->addCard(this);
connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) { connect(&SettingsCache::instance().cardCounters(), &CardCounterSettings::colorChanged, this, [this](int counterId) {
if (state->getCounters().contains(counterId)) { if (state->getCounters().contains(counterId)) {
update(); update();
} }
}); });
connect(state, &CardState::visibleChanged, this, [this](bool visible) { setVisible(visible); });
} }
void CardItem::prepareDelete() void CardItem::prepareDelete()
@ -45,16 +41,6 @@ void CardItem::prepareDelete()
} }
owner = nullptr; owner = nullptr;
} }
while (!attachedCards.isEmpty()) {
attachedCards.first()->setZone(nullptr); // so that it won't try to call reorganizeCards()
attachedCards.first()->setAttachedTo(nullptr);
}
if (state->getAttachedTo() != nullptr) {
state->getAttachedTo()->removeAttachedCard(this);
state->setAttachedTo(nullptr);
}
} }
void CardItem::deleteLater() void CardItem::deleteLater()
@ -66,11 +52,6 @@ void CardItem::deleteLater()
AbstractCardItem::deleteLater(); AbstractCardItem::deleteLater();
} }
void CardItem::setZone(CardZoneLogic *_zone)
{
state->setZone(_zone);
}
void CardItem::retranslateUi() void CardItem::retranslateUi()
{ {
} }
@ -99,7 +80,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->save(); painter->save();
transformPainter(painter, translatedSize, tapAngle); transformPainter(painter, translatedSize, tapAngle);
if (!getFaceDown() && state->getPT() == exactCard.getInfo().getPowTough()) { if (!getState()->getFaceDown() && state->getPT() == getState()->getCard().getInfo().getPowTough()) {
painter->setPen(Qt::white); painter->setPen(Qt::white);
} else { } else {
painter->setPen(QColor(255, 150, 0)); // dark orange painter->setPen(QColor(255, 150, 0)); // dark orange
@ -149,107 +130,21 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->restore(); painter->restore();
} }
void CardItem::setAttacking(bool _attacking)
{
state->setAttacking(_attacking);
update();
}
void CardItem::setCounter(int _id, int _value)
{
state->setCounter(_id, _value);
update();
}
void CardItem::setAnnotation(const QString &_annotation)
{
state->setAnnotation(_annotation);
update();
}
void CardItem::setDoesntUntap(bool _doesntUntap)
{
state->setDoesntUntap(_doesntUntap);
update();
}
void CardItem::setPT(const QString &_pt)
{
state->setPT(_pt);
update();
}
void CardItem::setAttachedTo(CardItem *_attachedTo)
{
if (state->getAttachedTo() != nullptr) {
state->getAttachedTo()->removeAttachedCard(this);
}
gridPoint.setX(-1);
state->setAttachedTo(_attachedTo);
if (state->getAttachedTo() != nullptr) {
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its
// attached cards
if (state->getAttachedTo()->getZone() == nullptr) {
deleteLater();
} else {
emit state->getAttachedTo()->getZone()->cardAdded(this);
state->getAttachedTo()->addAttachedCard(this);
if (state->getZone() != state->getAttachedTo()->getZone()) {
state->getAttachedTo()->getZone()->reorganizeCards();
}
}
} else {
// If the zone is being torn down, it might already be null by the time a card tries to un-attach all its
// attached cards
if (state->getZone() == nullptr) {
deleteLater();
} else {
emit state->getZone()->cardAdded(this);
}
}
if (state->getZone() != nullptr) {
state->getZone()->reorganizeCards();
}
}
/** /**
* @brief Resets the fields that should be reset after a zone transition * @brief Resets the fields that should be reset after a zone transition
*/ */
void CardItem::resetState(bool keepAnnotations) void CardItem::resetState(bool keepAnnotations)
{ {
state->resetState(keepAnnotations); state->resetState(keepAnnotations);
attachedCards.clear(); state->clearAttachedCards();
setTapped(false, false); state->setTapped(false, false);
setDoesntUntap(false); getState()->setDoesntUntap(false);
if (scene()) { if (scene()) {
static_cast<GameScene *>(scene())->unregisterAnimationItem(this); static_cast<GameScene *>(scene())->unregisterAnimationItem(this);
} }
update(); update();
} }
void CardItem::processCardInfo(const ServerInfo_Card &_info)
{
state->clearCounters();
const int counterListSize = _info.counter_list_size();
for (int i = 0; i < counterListSize; ++i) {
const ServerInfo_CardCounter &counterInfo = _info.counter_list(i);
state->insertCounter(counterInfo.id(), counterInfo.value());
}
setId(_info.id());
setCardRef({QString::fromStdString(_info.name()), QString::fromStdString(_info.provider_id())});
setAttacking(_info.attacking());
setFaceDown(_info.face_down());
setPT(QString::fromStdString(_info.pt()));
setAnnotation(QString::fromStdString(_info.annotation()));
setColor(QString::fromStdString(_info.color()));
setTapped(_info.tapped());
setDestroyOnZoneChange(_info.destroy_on_zone_change());
setDoesntUntap(_info.doesnt_untap());
}
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown) CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown)
{ {
deleteDragItem(); deleteDragItem();
@ -292,7 +187,7 @@ void CardItem::drawArrow(const QColor &arrowColor)
if (card == nullptr || card == this) { if (card == nullptr || card == this) {
continue; continue;
} }
if (card->getZone() != state->getZone()) { if (card->getState()->getZone() != state->getZone()) {
continue; continue;
} }
@ -317,7 +212,7 @@ void CardItem::drawAttachArrow()
if (card == nullptr) { if (card == nullptr) {
continue; continue;
} }
if (card->getZone() != state->getZone()) { if (card->getState()->getZone() != state->getZone()) {
continue; continue;
} }
@ -362,13 +257,13 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// Use the buttonDownPos to align the hot spot with the position when // Use the buttonDownPos to align the hot spot with the position when
// the user originally clicked // the user originally clicked
createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown); createDragItem(getState()->getId(), event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown);
dragItem->grabMouse(); dragItem->grabMouse();
int childIndex = 0; int childIndex = 0;
for (const auto &item : scene()->selectedItems()) { for (const auto &item : scene()->selectedItems()) {
CardItem *card = static_cast<CardItem *>(item); CardItem *card = static_cast<CardItem *>(item);
if ((card == this) || (card->getZone() != state->getZone())) { if ((card == this) || (card->getState()->getZone() != state->getZone())) {
continue; continue;
} }
++childIndex; ++childIndex;
@ -378,8 +273,8 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
} else { } else {
childPos = QPointF(childIndex * CardDimensions::WIDTH_HALF_F, 0); childPos = QPointF(childIndex * CardDimensions::WIDTH_HALF_F, 0);
} }
CardDragItem *drag = CardDragItem *drag = new CardDragItem(card, card->getState()->getId(), childPos,
new CardDragItem(card, card->getId(), childPos, card->getFaceDown() || forceFaceDown, dragItem); card->getState()->getFaceDown() || forceFaceDown, dragItem);
drag->setPos(dragItem->pos() + childPos); drag->setPos(dragItem->pos() + childPos);
scene()->addItem(drag); scene()->addItem(drag);
} }
@ -405,7 +300,7 @@ void CardItem::playCard(bool faceDown)
emit playSelected(this); emit playSelected(this);
} }
} else { } else {
state->getZone()->getPlayer()->getPlayerActions()->playCard(this, faceDown); state->getZone()->getPlayer()->getPlayerActions()->playCard(getState(), faceDown);
} }
} }
} }
@ -465,7 +360,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld)
if (SettingsCache::instance().getClickPlaysAllSelected()) { if (SettingsCache::instance().getClickPlaysAllSelected()) {
emit hideSelected(this); emit hideSelected(this);
} else { } else {
state->getZone()->removeCard(this); state->getZone()->removeCard(getState());
} }
} else { } else {
playCard(shiftHeld); playCard(shiftHeld);
@ -476,7 +371,6 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
if (event->button() == Qt::RightButton && owner != nullptr) { if (event->button() == Qt::RightButton && owner != nullptr) {
emit rightClicked(this, event->screenPos()); emit rightClicked(this, event->screenPos());
return;
} }
if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) && if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) &&
(!SettingsCache::instance().getDoubleClickToPlay())) { (!SettingsCache::instance().getDoubleClickToPlay())) {
@ -501,16 +395,16 @@ bool CardItem::animationEvent()
{ {
int rotation = ROTATION_DEGREES_PER_FRAME; int rotation = ROTATION_DEGREES_PER_FRAME;
bool animationIncomplete = true; bool animationIncomplete = true;
if (!tapped) { if (!getState()->getTapped()) {
rotation *= -1; rotation *= -1;
} }
tapAngle += rotation; tapAngle += rotation;
if (tapped && (tapAngle > 90)) { if (getState()->getTapped() && (tapAngle > 90)) {
tapAngle = 90; tapAngle = 90;
animationIncomplete = false; animationIncomplete = false;
} }
if (!tapped && (tapAngle < 0)) { if (!getState()->getTapped() && (tapAngle < 0)) {
tapAngle = 0; tapAngle = 0;
animationIncomplete = false; animationIncomplete = false;
} }

View file

@ -29,10 +29,9 @@ class CardItem : public AbstractCardItem
Q_OBJECT Q_OBJECT
private: private:
CardState *state; CardState *state;
CardZone *zone;
QPoint gridPoint;
CardDragItem *dragItem; CardDragItem *dragItem;
QList<CardItem *> attachedCards;
void prepareDelete(); void prepareDelete();
void handleClickedToPlay(bool shiftHeld); void handleClickedToPlay(bool shiftHeld);
@ -48,95 +47,20 @@ public:
{ {
return Type; return Type;
} }
explicit CardItem(PlayerLogic *_owner, explicit CardItem(CardState *state, CardZone *parent);
QGraphicsItem *parent = nullptr,
const CardRef &cardRef = {},
int _cardid = -1,
CardZoneLogic *_zone = nullptr);
void retranslateUi(); void retranslateUi();
[[nodiscard]] CardZone *getZone() const
{
return zone;
}
[[nodiscard]] CardState *getState() const [[nodiscard]] CardState *getState() const
{ {
return state; return state;
} }
[[nodiscard]] CardZoneLogic *getZone() const
{
return state->getZone();
}
void setZone(CardZoneLogic *_zone);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
[[nodiscard]] QPoint getGridPoint() const
{
return gridPoint;
}
void setGridPoint(const QPoint &_gridPoint)
{
gridPoint = _gridPoint;
}
[[nodiscard]] QPoint getGridPos() const
{
return gridPoint;
}
[[nodiscard]] PlayerLogic *getOwner() const
{
return owner;
}
void setOwner(PlayerLogic *_owner)
{
owner = _owner;
}
[[nodiscard]] bool getAttacking() const
{
return state->getAttacking();
}
void setAttacking(bool _attacking);
[[nodiscard]] const QMap<int, int> &getCounters() const
{
return state->getCounters();
}
void setCounter(int _id, int _value);
[[nodiscard]] QString getAnnotation() const
{
return state->getAnnotation();
}
void setAnnotation(const QString &_annotation);
[[nodiscard]] bool getDoesntUntap() const
{
return state->getDoesntUntap();
}
void setDoesntUntap(bool _doesntUntap);
[[nodiscard]] QString getPT() const
{
return state->getPT();
}
void setPT(const QString &_pt);
[[nodiscard]] bool getDestroyOnZoneChange() const
{
return state->getDestroyOnZoneChange();
}
void setDestroyOnZoneChange(bool _destroy)
{
state->setDestroyOnZoneChange(_destroy);
}
[[nodiscard]] CardItem *getAttachedTo() const
{
return state->getAttachedTo();
}
void setAttachedTo(CardItem *_attachedTo);
void addAttachedCard(CardItem *card)
{
attachedCards.append(card);
}
void removeAttachedCard(CardItem *card)
{
attachedCards.removeOne(card);
}
[[nodiscard]] const QList<CardItem *> &getAttachedCards() const
{
return attachedCards;
}
void resetState(bool keepAnnotations = false); void resetState(bool keepAnnotations = false);
void processCardInfo(const ServerInfo_Card &_info);
bool animationEvent(); bool animationEvent();
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown); CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown);

View file

@ -73,7 +73,7 @@ void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
} }
DeckViewCard::DeckViewCard(QGraphicsItem *parent, const CardRef &cardRef, const QString &_originZone) DeckViewCard::DeckViewCard(QGraphicsItem *parent, const CardRef &cardRef, const QString &_originZone)
: AbstractCardItem(parent, cardRef, 0, -1), originZone(_originZone), dragItem(0) : AbstractCardItem(new AbstractCardState(nullptr, cardRef, -1), parent), originZone(_originZone), dragItem(0)
{ {
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
@ -152,7 +152,7 @@ void DeckView::mouseDoubleClickEvent(QMouseEvent *event)
auto *c = static_cast<DeckViewCard *>(sel.at(i)); auto *c = static_cast<DeckViewCard *>(sel.at(i));
auto *zone = static_cast<DeckViewCardContainer *>(c->parentItem()); auto *zone = static_cast<DeckViewCardContainer *>(c->parentItem());
MoveCard_ToZone m; MoveCard_ToZone m;
m.set_card_name(c->getName().toStdString()); m.set_card_name(c->getState()->getName().toStdString());
m.set_start_zone(zone->getName().toStdString()); m.set_start_zone(zone->getName().toStdString());
if (zone->getName() == DECK_ZONE_MAIN) { if (zone->getName() == DECK_ZONE_MAIN) {
@ -228,13 +228,15 @@ void DeckViewCardContainer::paint(QPainter *painter, const QStyleOptionGraphicsI
void DeckViewCardContainer::addCard(DeckViewCard *card) void DeckViewCardContainer::addCard(DeckViewCard *card)
{ {
cards.append(card); cards.append(card);
cardsByType.insert(card->getCard().isEmpty() ? "" : card->getCardInfo().getMainCardType(), card); cardsByType.insert(card->getState()->getCard().isEmpty() ? "" : card->getState()->getCardInfo().getMainCardType(),
card);
} }
void DeckViewCardContainer::removeCard(DeckViewCard *card) void DeckViewCardContainer::removeCard(DeckViewCard *card)
{ {
cards.removeOne(card); cards.removeOne(card);
cardsByType.remove(card->getCard().isEmpty() ? "" : card->getCardInfo().getMainCardType(), card); cardsByType.remove(card->getState()->getCard().isEmpty() ? "" : card->getState()->getCardInfo().getMainCardType(),
card);
} }
QList<QPair<int, int>> DeckViewCardContainer::getRowsAndCols() const QList<QPair<int, int>> DeckViewCardContainer::getRowsAndCols() const
@ -283,7 +285,7 @@ QSizeF DeckViewCardContainer::calculateBoundingRect(const QList<QPair<int, int>>
bool DeckViewCardContainer::sortCardsByName(DeckViewCard *c1, DeckViewCard *c2) bool DeckViewCardContainer::sortCardsByName(DeckViewCard *c1, DeckViewCard *c2)
{ {
if (c1 && c2) { if (c1 && c2) {
return c1->getName() < c2->getName(); return c1->getState()->getName() < c2->getState()->getName();
} }
return false; return false;
} }
@ -396,7 +398,7 @@ void DeckViewScene::applySideboardPlan(const QList<MoveCard_ToZone> &plan)
DeckViewCard *card = 0; DeckViewCard *card = 0;
const QList<DeckViewCard *> &cardList = start->getCards(); const QList<DeckViewCard *> &cardList = start->getCards();
for (int j = 0; j < cardList.size(); ++j) { for (int j = 0; j < cardList.size(); ++j) {
if (cardList[j]->getName() == QString::fromStdString(m.card_name())) { if (cardList[j]->getState()->getName() == QString::fromStdString(m.card_name())) {
card = cardList[j]; card = cardList[j];
break; break;
} }
@ -498,7 +500,7 @@ QList<MoveCard_ToZone> DeckViewScene::getSideboardPlan() const
for (int i = 0; i < cardList.size(); ++i) { for (int i = 0; i < cardList.size(); ++i) {
if (cardList[i]->getOriginZone() != cont->getName()) { if (cardList[i]->getOriginZone() != cont->getName()) {
MoveCard_ToZone m; MoveCard_ToZone m;
m.set_card_name(cardList[i]->getName().toStdString()); m.set_card_name(cardList[i]->getState()->getName().toStdString());
m.set_start_zone(cardList[i]->getOriginZone().toStdString()); m.set_start_zone(cardList[i]->getOriginZone().toStdString());
m.set_target_zone(cont->getName().toStdString()); m.set_target_zone(cont->getName().toStdString());
result.append(m); result.append(m);

View file

@ -76,6 +76,18 @@ QList<CardItem *> GameScene::selectedCards() const
return selectedCards; return selectedCards;
} }
QList<CardState *> GameScene::selectedCardsAsStates() const
{
QList<CardState *> selectedCards;
for (auto item : selectedItems()) {
if (auto card = qgraphicsitem_cast<CardItem *>(item)) {
selectedCards.append(card->getState());
}
}
return selectedCards;
}
void GameScene::onCardSelectionChanged(AbstractCardItem *abstractCard, bool selected) void GameScene::onCardSelectionChanged(AbstractCardItem *abstractCard, bool selected)
{ {
CardItem *card = qobject_cast<CardItem *>(abstractCard); CardItem *card = qobject_cast<CardItem *>(abstractCard);
@ -86,7 +98,7 @@ void GameScene::onCardSelectionChanged(AbstractCardItem *abstractCard, bool sele
auto *owner = card->getOwner(); auto *owner = card->getOwner();
if (selected) { if (selected) {
owner->requestCardMenuUpdate(card); owner->requestCardMenuUpdate(card->getState());
return; return;
} }
@ -112,7 +124,7 @@ void GameScene::onCardRightClicked(AbstractCardItem *abstractCard, QPoint screen
card->getOwner()->getGame()->setActiveCard(card); card->getOwner()->getGame()->setActiveCard(card);
if (auto *menu = view->getPlayerMenu()->updateCardMenu(card)) { if (auto *menu = view->getPlayerMenu()->updateCardMenu(card->getState())) {
menu->popup(screenPos); menu->popup(screenPos);
} }
} }
@ -125,7 +137,7 @@ void GameScene::playSelected(AbstractCardItem *card)
if (!card->getOwner()) { if (!card->getOwner()) {
return; return;
} }
card->getOwner()->getPlayerActions()->actPlay(selectedCards()); card->getOwner()->getPlayerActions()->actPlay(selectedCardsAsStates());
} }
void GameScene::playSelectedFaceDown(AbstractCardItem *card) void GameScene::playSelectedFaceDown(AbstractCardItem *card)
@ -136,7 +148,7 @@ void GameScene::playSelectedFaceDown(AbstractCardItem *card)
if (!card->getOwner()) { if (!card->getOwner()) {
return; return;
} }
card->getOwner()->getPlayerActions()->actPlayFacedown(selectedCards()); card->getOwner()->getPlayerActions()->actPlayFacedown(selectedCardsAsStates());
} }
void GameScene::hideSelected(AbstractCardItem *card) void GameScene::hideSelected(AbstractCardItem *card)
@ -147,7 +159,7 @@ void GameScene::hideSelected(AbstractCardItem *card)
if (!card->getOwner()) { if (!card->getOwner()) {
return; return;
} }
card->getOwner()->getPlayerActions()->actHide(selectedCards()); card->getOwner()->getPlayerActions()->actHide(selectedCardsAsStates());
} }
/** /**
@ -181,7 +193,8 @@ void GameScene::addPlayer(PlayerLogic *player)
connect(player, &PlayerLogic::arrowsClearedLocally, this, connect(player, &PlayerLogic::arrowsClearedLocally, this,
[this, id = player->getPlayerInfo()->getId()]() { clearArrowsForPlayerLocally(id); }); [this, id = player->getPlayerInfo()->getId()]() { clearArrowsForPlayerLocally(id); });
connect(player->getPlayerEventHandler(), &PlayerEventHandler::cardZoneChanged, this, &GameScene::onCardZoneChanged); // connect(player->getPlayerEventHandler(), &PlayerEventHandler::cardZoneChanged, this,
// &GameScene::onCardZoneChanged);
rearrange(); rearrange();
} }
@ -458,13 +471,12 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
return; return;
} }
PlayerLogic *startLogic = startView->getLogic(); auto *startZoneView = startView->getZoneGraphicsItem(data->startZone);
auto *startZone = startLogic->getZones().value(data->startZone); if (!startZoneView) {
if (!startZone) {
return; return;
} }
CardItem *startCard = startZone->getCard(data->startCardId); CardItem *startCard = startZoneView->getCardItemForId(data->startCardId);
if (!startCard) { if (!startCard) {
return; return;
} }
@ -473,9 +485,9 @@ void GameScene::addArrow(QSharedPointer<ArrowData> data)
if (data->isPlayerTargeted()) { if (data->isPlayerTargeted()) {
targetItem = targetView->getPlayerTarget(); targetItem = targetView->getPlayerTarget();
} else { } else {
auto *zone = targetView->getLogic()->getZones().value(data->targetZone); auto *zone = targetView->getZoneGraphicsItem(data->targetZone);
if (zone) { if (zone) {
targetItem = zone->getCard(data->targetCardId); targetItem = zone->getCardItemForId(data->targetCardId);
} }
} }
if (!targetItem) { if (!targetItem) {
@ -592,11 +604,11 @@ CardItem *GameScene::findTopmostCardInZone(const QList<QGraphicsItem *> &items,
continue; continue;
} }
if (card->getAttachedTo()) { if (card->getState()->getAttachedTo()) {
if (card->getAttachedTo()->getZone() != zone->getLogic()) { if (card->getState()->getAttachedTo()->getZone() != zone->getLogic()) {
continue; continue;
} }
} else if (card->getZone() != zone->getLogic()) { } else if (card->getZone()->getLogic() != zone->getLogic()) {
continue; continue;
} }

View file

@ -85,6 +85,9 @@ public:
/** @brief Gets all selected CardItems. */ /** @brief Gets all selected CardItems. */
QList<CardItem *> selectedCards() const; QList<CardItem *> selectedCards() const;
/** @brief Gets all selected Cards as states. */
QList<CardState *> selectedCardsAsStates() const;
/** /**
* @brief Adds a player to the scene and stores their graphics item. * @brief Adds a player to the scene and stores their graphics item.
* @param player Player to add. * @param player Player to add.

View file

@ -256,7 +256,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,
@ -636,7 +636,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."))
@ -680,7 +680,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) {
@ -691,7 +691,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;
@ -729,7 +729,7 @@ void MessageLogWidget::logSetSideboardLock(PlayerLogic *player, bool locked)
} }
} }
void MessageLogWidget::logSetTapped(PlayerLogic *player, CardItem *card, bool tapped) void MessageLogWidget::logSetTapped(PlayerLogic *player, CardState *card, bool tapped)
{ {
if (currentContext == MessageContext_MoveCard) { if (currentContext == MessageContext_MoveCard) {
return; return;

View file

@ -11,7 +11,7 @@
#include "../../interface/widgets/server/chat_view/chat_view.h" #include "../../interface/widgets/server/chat_view/chat_view.h"
class AbstractGame; class AbstractGame;
class CardItem; class CardState;
class GameEventContext; class GameEventContext;
class PlayerLogic; class PlayerLogic;
class PlayerEventHandler; class PlayerEventHandler;
@ -67,7 +67,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,
@ -88,13 +88,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

@ -44,7 +44,7 @@ static QAction *makeAction(QObject *parent, Slot &&slot, bool checkable = false,
return a; return a;
} }
CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _shortcutsActive) CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardState *_card, bool _shortcutsActive)
: player(_player), card(_card), shortcutsActive(_shortcutsActive) : player(_player), card(_card), shortcutsActive(_shortcutsActive)
{ {
const QList<PlayerLogic *> &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values(); const QList<PlayerLogic *> &players = player->getLogic()->getGame()->getPlayerManager()->getPlayers().values();
@ -63,7 +63,7 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho
auto *gameScene = player->getGameScene(); auto *gameScene = player->getGameScene();
// Single selection resolver used by all lambdas — called at trigger time // Single selection resolver used by all lambdas — called at trigger time
auto sel = [gameScene]() { return gameScene->selectedCards(); }; auto sel = [gameScene]() { return gameScene->selectedCardsAsStates(); };
// Unified dispatcher for card menu actions // Unified dispatcher for card menu actions
auto invoke = [actions, sel](CardMenuActionType type) { auto invoke = [actions, sel](CardMenuActionType type) {
@ -314,7 +314,7 @@ void CardMenu::createHandOrCustomZoneMenu(bool canModifyCard)
initContextualPlayersMenu(revealMenu, aRevealToAll); initContextualPlayersMenu(revealMenu, aRevealToAll);
connect(revealMenu, &QMenu::triggered, this, [this](QAction *action) { connect(revealMenu, &QMenu::triggered, this, [this](QAction *action) {
player->getLogic()->getPlayerActions()->actReveal(player->getGameScene()->selectedCards(), action); player->getLogic()->getPlayerActions()->actReveal(player->getGameScene()->selectedCardsAsStates(), action);
}); });
addSeparator(); addSeparator();

View file

@ -7,9 +7,12 @@
#ifndef COCKATRICE_CARD_MENU_H #ifndef COCKATRICE_CARD_MENU_H
#define COCKATRICE_CARD_MENU_H #define COCKATRICE_CARD_MENU_H
#include "libcockatrice/utility/card_ref.h"
#include <QMenu> #include <QMenu>
#include <libcockatrice/utility/card_ref.h> #include <libcockatrice/utility/card_ref.h>
class CardState;
class CardItem; class CardItem;
class PlayerGraphicsItem; class PlayerGraphicsItem;
class PlayerLogic; class PlayerLogic;
@ -21,7 +24,7 @@ signals:
void cardInfoRequested(const CardRef &cardRef); void cardInfoRequested(const CardRef &cardRef);
public: public:
explicit CardMenu(PlayerGraphicsItem *player, const CardItem *card, bool shortcutsActive); explicit CardMenu(PlayerGraphicsItem *player, const CardState *card, bool shortcutsActive);
void removePlayer(PlayerLogic *playerToRemove); void removePlayer(PlayerLogic *playerToRemove);
void createTableMenu(bool canModifyCard); void createTableMenu(bool canModifyCard);
void createStackMenu(bool canModifyCard); void createStackMenu(bool canModifyCard);
@ -47,7 +50,7 @@ public:
private: private:
PlayerGraphicsItem *player; PlayerGraphicsItem *player;
const CardItem *card; const CardState *card;
QList<QPair<QString, int>> playersInfo; QList<QPair<QString, int>> playersInfo;
bool shortcutsActive; bool shortcutsActive;

View file

@ -25,7 +25,8 @@ MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to"))
auto invoke = [player](CardMenuActionType type) { auto invoke = [player](CardMenuActionType type) {
return [type, player]() { return [type, player]() {
player->getLogic()->getPlayerActions()->cardMenuAction(player->getGameScene()->selectedCards(), type); player->getLogic()->getPlayerActions()->cardMenuAction(player->getGameScene()->selectedCardsAsStates(),
type);
}; };
}; };

View file

@ -69,7 +69,7 @@ void PlayerMenu::setMenusForGraphicItems()
} }
} }
QMenu *PlayerMenu::updateCardMenu(const CardItem *card) QMenu *PlayerMenu::updateCardMenu(const CardState *card)
{ {
if (!card) { if (!card) {
emit cardMenuUpdated(nullptr); emit cardMenuUpdated(nullptr);
@ -78,9 +78,10 @@ QMenu *PlayerMenu::updateCardMenu(const CardItem *card)
// If is spectator (as spectators don't need card menus), return // If is spectator (as spectators don't need card menus), return
// only update the menu if the card is actually selected // only update the menu if the card is actually selected
auto *activeCard = player->getLogic()->getGame()->getActiveCard();
if ((player->getLogic()->getGame()->getPlayerManager()->isSpectator() && if ((player->getLogic()->getGame()->getPlayerManager()->isSpectator() &&
!player->getLogic()->getGame()->getPlayerManager()->isJudge()) || !player->getLogic()->getGame()->getPlayerManager()->isJudge()) ||
player->getLogic()->getGame()->getActiveCard() != card) { !activeCard || activeCard->getState() != card) {
return nullptr; return nullptr;
} }

View file

@ -21,7 +21,7 @@
#include <QMenu> #include <QMenu>
#include <QObject> #include <QObject>
class CardItem; class CardState;
class CardMenu; class CardMenu;
class PlayerGraphicsItem; class PlayerGraphicsItem;
class PlayerMenu : public QObject class PlayerMenu : public QObject
@ -37,7 +37,7 @@ signals:
public slots: public slots:
void setMenusForGraphicItems(); void setMenusForGraphicItems();
QMenu *updateCardMenu(const CardItem *card); QMenu *updateCardMenu(const CardState *card);
private slots: private slots:
void refreshShortcuts(); void refreshShortcuts();

View file

@ -10,34 +10,35 @@ PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness"))
aIncP = new QAction(this); aIncP = new QAction(this);
connect(aIncP, &QAction::triggered, playerActions, connect(aIncP, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actIncP(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actIncP(player->getGameScene()->selectedCardsAsStates()); });
aDecP = new QAction(this); aDecP = new QAction(this);
connect(aDecP, &QAction::triggered, playerActions, connect(aDecP, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actDecP(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actDecP(player->getGameScene()->selectedCardsAsStates()); });
aIncT = new QAction(this); aIncT = new QAction(this);
connect(aIncT, &QAction::triggered, playerActions, connect(aIncT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actIncT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actIncT(player->getGameScene()->selectedCardsAsStates()); });
aDecT = new QAction(this); aDecT = new QAction(this);
connect(aDecT, &QAction::triggered, playerActions, connect(aDecT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actDecT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actDecT(player->getGameScene()->selectedCardsAsStates()); });
aIncPT = new QAction(this); aIncPT = new QAction(this);
connect(aIncPT, &QAction::triggered, playerActions, connect(aIncPT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actIncPT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actIncPT(player->getGameScene()->selectedCardsAsStates()); });
aDecPT = new QAction(this); aDecPT = new QAction(this);
connect(aDecPT, &QAction::triggered, playerActions, connect(aDecPT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actDecPT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actDecPT(player->getGameScene()->selectedCardsAsStates()); });
aFlowP = new QAction(this); aFlowP = new QAction(this);
connect(aFlowP, &QAction::triggered, playerActions, connect(aFlowP, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actFlowP(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actFlowP(player->getGameScene()->selectedCardsAsStates()); });
aFlowT = new QAction(this); aFlowT = new QAction(this);
connect(aFlowT, &QAction::triggered, playerActions, connect(aFlowT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actFlowT(player->getGameScene()->selectedCardsAsStates()); });
aSetPT = new QAction(this); aSetPT = new QAction(this);
connect(aSetPT, &QAction::triggered, playerActions, connect(aSetPT, &QAction::triggered, playerActions, [player, playerActions] {
[player, playerActions] { playerActions->actRequestSetPTDialog(player->getGameScene()->selectedCards()); }); playerActions->actRequestSetPTDialog(player->getGameScene()->selectedCardsAsStates());
});
aResetPT = new QAction(this); aResetPT = new QAction(this);
connect(aResetPT, &QAction::triggered, playerActions, connect(aResetPT, &QAction::triggered, playerActions,
[player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCards()); }); [player, playerActions] { playerActions->actResetPT(player->getGameScene()->selectedCardsAsStates()); });
addAction(aIncP); addAction(aIncP);
addAction(aDecP); addAction(aDecP);

View file

@ -38,7 +38,7 @@ UtilityMenu::UtilityMenu(PlayerGraphicsItem *_player, QMenu *playerMenu) : QMenu
aIncrementAllCardCounters = new QAction(this); aIncrementAllCardCounters = new QAction(this);
connect(aIncrementAllCardCounters, &QAction::triggered, playerActions, [this]() { connect(aIncrementAllCardCounters, &QAction::triggered, playerActions, [this]() {
player->getLogic()->getPlayerActions()->actIncrementAllCardCounters( player->getLogic()->getPlayerActions()->actIncrementAllCardCounters(
player->getGameScene()->selectedCards()); player->getGameScene()->selectedCardsAsStates());
}); });
createPredefinedTokenMenu = new QMenu(QString()); createPredefinedTokenMenu = new QMenu(QString());

View file

@ -8,6 +8,7 @@
#define COCKATRICE_UTILITY_MENU_H #define COCKATRICE_UTILITY_MENU_H
#include "abstract_player_component.h" #include "abstract_player_component.h"
#include "libcockatrice/card/card_info.h"
#include <QMenu> #include <QMenu>
#include <libcockatrice/card/card_info.h> #include <libcockatrice/card/card_info.h>

View file

@ -241,14 +241,14 @@ void PlayerDialogs::onMoveCardXCardsFromTopDialogRequested(int defaultNumberTopC
number -= 1; // indexes start at 0 number -= 1; // indexes start at 0
if (ok) { if (ok) {
playerActions->actMoveCardXCardsFromTop(player->getGameScene()->selectedCards(), number); playerActions->actMoveCardXCardsFromTop(player->getGameScene()->selectedCardsAsStates(), number);
} }
} }
void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT) void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT)
{ {
bool ok; bool ok;
auto cards = player->getGameScene()->selectedCards(); auto cards = player->getGameScene()->selectedCardsAsStates();
emit requestDialogSemaphore(true); emit requestDialogSemaphore(true);
QString pt = getTextWithMax(dialogParent(), tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, QString pt = getTextWithMax(dialogParent(), tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal,
oldPT, &ok); oldPT, &ok);
@ -263,7 +263,7 @@ void PlayerDialogs::onSetPTDialogRequested(const QString &oldPT)
void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation) void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation)
{ {
auto cards = player->getGameScene()->selectedCards(); auto cards = player->getGameScene()->selectedCardsAsStates();
emit requestDialogSemaphore(true); emit requestDialogSemaphore(true);
AnnotationDialog *dialog = new AnnotationDialog(dialogParent()); AnnotationDialog *dialog = new AnnotationDialog(dialogParent());
dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput); dialog->setOptions(QInputDialog::UsePlainTextEditForTextInput);
@ -281,7 +281,7 @@ void PlayerDialogs::onSetAnnotationDialogRequested(const QString &oldAnnotation)
void PlayerDialogs::onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg) void PlayerDialogs::onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg)
{ {
auto cards = player->getGameScene()->selectedCards(); auto cards = player->getGameScene()->selectedCardsAsStates();
emit requestDialogSemaphore(true); emit requestDialogSemaphore(true);
auto &cardCounterSettings = SettingsCache::instance().cardCounters(); auto &cardCounterSettings = SettingsCache::instance().cardCounters();

View file

@ -126,12 +126,19 @@ void PlayerGraphicsItem::initializeZones()
connect(handCounter, &HandCounter::showContextMenu, handZoneGraphicsItem, &HandZone::showContextMenu); connect(handCounter, &HandCounter::showContextMenu, handZoneGraphicsItem, &HandZone::showContextMenu);
zoneGraphicsItems.insert(player->getDeckZone()->getName(), deckZoneGraphicsItem); zoneGraphicsItems.insert(player->getDeckZone()->getName(), deckZoneGraphicsItem);
connect(deckZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
zoneGraphicsItems.insert(player->getGraveZone()->getName(), graveyardZoneGraphicsItem); zoneGraphicsItems.insert(player->getGraveZone()->getName(), graveyardZoneGraphicsItem);
connect(graveyardZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
zoneGraphicsItems.insert(player->getRfgZone()->getName(), rfgZoneGraphicsItem); zoneGraphicsItems.insert(player->getRfgZone()->getName(), rfgZoneGraphicsItem);
connect(rfgZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
zoneGraphicsItems.insert(player->getSideboardZone()->getName(), sideboardGraphicsItem); zoneGraphicsItems.insert(player->getSideboardZone()->getName(), sideboardGraphicsItem);
connect(sideboardGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
zoneGraphicsItems.insert(player->getTableZone()->getName(), tableZoneGraphicsItem); zoneGraphicsItems.insert(player->getTableZone()->getName(), tableZoneGraphicsItem);
connect(tableZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
zoneGraphicsItems.insert(player->getStackZone()->getName(), stackZoneGraphicsItem); zoneGraphicsItems.insert(player->getStackZone()->getName(), stackZoneGraphicsItem);
connect(stackZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
zoneGraphicsItems.insert(player->getHandZone()->getName(), handZoneGraphicsItem); zoneGraphicsItems.insert(player->getHandZone()->getName(), handZoneGraphicsItem);
connect(handZoneGraphicsItem, &CardZone::cardItemAdded, this, &PlayerGraphicsItem::cardItemAdded);
} }
void PlayerGraphicsItem::onCustomZoneAdded(QString customZoneName) void PlayerGraphicsItem::onCustomZoneAdded(QString customZoneName)

View file

@ -126,6 +126,7 @@ signals:
void playerCountChanged(); void playerCountChanged();
void mirroredChanged(bool isMirrored); void mirroredChanged(bool isMirrored);
void cardInfoRequested(const CardRef &cardRef); void cardInfoRequested(const CardRef &cardRef);
void cardItemAdded(CardItem *added);
private: private:
PlayerLogic *player; PlayerLogic *player;

View file

@ -7,26 +7,45 @@
#include <QMenu> #include <QMenu>
CardZone::CardZone(CardZoneLogic *_logic, QGraphicsItem *parent) CardZone::CardZone(CardZoneLogic *_logic, QGraphicsItem *parent)
: AbstractGraphicsItem(parent), menu(nullptr), doubleClickAction(0), logic(_logic) : AbstractGraphicsItem(parent), logic(_logic), menu(nullptr), doubleClickAction(0)
{ {
connect(logic, &CardZoneLogic::retranslateUi, this, &CardZone::retranslateUi); connect(logic, &CardZoneLogic::retranslateUi, this, &CardZone::retranslateUi);
connect(logic, &CardZoneLogic::cardAdded, this, &CardZone::onCardAdded); connect(logic, &CardZoneLogic::cardAdded, this, &CardZone::onCardAdded);
connect(logic, &CardZoneLogic::cardRemoved, this, &CardZone::onCardRemoved);
connect(logic, &CardZoneLogic::setGraphicsVisibility, this, [this](bool v) { this->setVisible(v); }); connect(logic, &CardZoneLogic::setGraphicsVisibility, this, [this](bool v) { this->setVisible(v); });
connect(logic, &CardZoneLogic::updateGraphics, this, [this]() { update(); }); connect(logic, &CardZoneLogic::updateGraphics, this, [this]() { update(); });
connect(logic, &CardZoneLogic::reorganizeCards, this, &CardZone::reorganizeCards); connect(logic, &CardZoneLogic::reorganizeCards, this, &CardZone::reorganizeCards);
} }
void CardZone::onCardAdded(CardItem *addedCard) void CardZone::onCardAdded(CardState *toAdd, int /*x*/, int /*y*/)
{ {
CardItem *addedCard = new CardItem(toAdd, this);
addedCard->setParentItem(this); addedCard->setParentItem(this);
addedCard->setVisible(true); addedCard->setVisible(true);
addedCard->update(); addedCard->update();
cards.append(addedCard);
emit cardItemAdded(addedCard);
}
void CardZone::onCardRemoved(CardState *toRemove, int /*x*/, int /*y*/)
{
CardItem *removedCard = getCardItemForId(toRemove->getId());
if (!removedCard) {
return;
}
if (cards.contains(removedCard)) {
cards.remove(cards.indexOf(removedCard));
}
removedCard->setVisible(false);
removedCard->setParentItem(nullptr);
removedCard->deleteLater();
} }
void CardZone::retranslateUi() void CardZone::retranslateUi()
{ {
for (int i = 0; i < getLogic()->getCards().size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
getLogic()->getCards()[i]->retranslateUi(); cards[i]->retranslateUi();
} }
} }

View file

@ -9,6 +9,7 @@
#include "../../game/zones/card_zone_logic.h" #include "../../game/zones/card_zone_logic.h"
#include "../board/abstract_graphics_item.h" #include "../board/abstract_graphics_item.h"
#include "../board/card_item.h"
#include "../board/graphics_item_type.h" #include "../board/graphics_item_type.h"
#include <QLoggingCategory> #include <QLoggingCategory>
@ -26,6 +27,9 @@ class CardZone : public AbstractGraphicsItem
{ {
Q_OBJECT Q_OBJECT
protected: protected:
CardZoneLogic *logic;
QList<CardItem *> cards;
QMenu *menu; QMenu *menu;
QAction *doubleClickAction; QAction *doubleClickAction;
@ -46,7 +50,11 @@ 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, int x, int y);
void onCardRemoved(CardState *toAdd, int x, int y);
signals:
void cardItemAdded(CardItem *added);
public: public:
enum enum
@ -67,14 +75,21 @@ public:
return logic; return logic;
} }
CardItem *getCardItemForId(int id) const
{
for (CardItem *card : cards) {
if (card->getState()->getId() == id) {
return card;
}
}
return nullptr;
}
void setMenu(QMenu *_menu, QAction *_doubleClickAction = 0) void setMenu(QMenu *_menu, QAction *_doubleClickAction = 0)
{ {
menu = _menu; menu = _menu;
doubleClickAction = _doubleClickAction; doubleClickAction = _doubleClickAction;
} }
private:
CardZoneLogic *logic;
}; };
#endif #endif

View file

@ -35,7 +35,7 @@ void HandZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
int x = -1; int x = -1;
if (SettingsCache::instance().getHorizontalHand()) { if (SettingsCache::instance().getHorizontalHand()) {
for (x = 0; x < getLogic()->getCards().size(); x++) { for (x = 0; x < getLogic()->getCards().size(); x++) {
if (point.x() < static_cast<CardItem *>(getLogic()->getCards().at(x))->scenePos().x()) { if (point.x() < getCardItemForId(getLogic()->getCards().at(x)->getId())->scenePos().x()) {
break; break;
} }
} }
@ -75,23 +75,23 @@ void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio
void HandZone::reorganizeCards() void HandZone::reorganizeCards()
{ {
if (!getLogic()->getCards().isEmpty()) { if (!cards.isEmpty()) {
const int cardCount = getLogic()->getCards().size(); const int cardCount = cards.size();
if (SettingsCache::instance().getHorizontalHand()) { if (SettingsCache::instance().getHorizontalHand()) {
bool leftJustified = SettingsCache::instance().getLeftJustified(); bool leftJustified = SettingsCache::instance().getLeftJustified();
qreal cardWidth = getLogic()->getCards().at(0)->boundingRect().width(); qreal cardWidth = cards.at(0)->boundingRect().width();
const int xPadding = leftJustified ? cardWidth * 1.4 : 5; const int xPadding = leftJustified ? cardWidth * 1.4 : 5;
qreal totalWidth = qreal totalWidth =
leftJustified ? boundingRect().width() - (1 * xPadding) - 5 : boundingRect().width() - 2 * xPadding; leftJustified ? boundingRect().width() - (1 * xPadding) - 5 : boundingRect().width() - 2 * xPadding;
if (cardCount == 1) { if (cardCount == 1) {
CardItem *c = getLogic()->getCards().at(0); CardItem *c = cards.at(0);
qreal xPosition = leftJustified ? xPadding : xPadding + (totalWidth - cardWidth) / 2; qreal xPosition = leftJustified ? xPadding : xPadding + (totalWidth - cardWidth) / 2;
c->setPos(xPosition, 5); c->setPos(xPosition, 5);
c->setRealZValue(0); c->setRealZValue(0);
} else { } else {
for (int i = 0; i < cardCount; i++) { for (int i = 0; i < cardCount; i++) {
CardItem *c = getLogic()->getCards().at(i); CardItem *c = cards.at(i);
// If the total width of the cards is smaller than the available width, // If the total width of the cards is smaller than the available width,
// the cards do not need to overlap and are displayed in the center of the area. // the cards do not need to overlap and are displayed in the center of the area.
if (cardWidth * cardCount > totalWidth) { if (cardWidth * cardCount > totalWidth) {

View file

@ -31,6 +31,17 @@ PileZone::PileZone(PileZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_log
}); });
} }
void PileZone::onCardAdded(CardState *toAdd, int /*x*/, int /*y*/)
{
CardItem *addedCard = new CardItem(toAdd, this);
addedCard->setParentItem(this);
addedCard->setVisible(false);
addedCard->setPos(0, 0);
addedCard->update();
connect(addedCard, &CardItem::sigPixmapUpdated, this, [this]() { update(); });
cards.append(addedCard);
}
QRectF PileZone::boundingRect() const QRectF PileZone::boundingRect() const
{ {
return QRectF(0, 0, CardDimensions::WIDTH_F, CardDimensions::HEIGHT_F); return QRectF(0, 0, CardDimensions::WIDTH_F, CardDimensions::HEIGHT_F);
@ -48,15 +59,15 @@ void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio
{ {
painter->drawPath(shape()); painter->drawPath(shape());
if (!getLogic()->getCards().isEmpty()) { if (!cards.isEmpty()) {
getLogic()->getCards().at(0)->paintPicture(painter, getLogic()->getCards().at(0)->getTranslatedSize(painter), CardItem *cardAt = cards.at(0);
90); cardAt->paintPicture(painter, cardAt->getTranslatedSize(painter), 90);
} }
painter->translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F); painter->translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F);
painter->rotate(-90); painter->rotate(-90);
painter->translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F); painter->translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F);
paintNumberEllipse(getLogic()->getCards().size(), 28, Qt::white, -1, -1, painter); paintNumberEllipse(cards.size(), 28, Qt::white, -1, -1, painter);
} }
void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &) void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &)
@ -113,10 +124,11 @@ void PileZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier); bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
bool bottomCard = event->modifiers().testFlag(Qt::ControlModifier); bool bottomCard = event->modifiers().testFlag(Qt::ControlModifier);
CardItem *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first(); CardState *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first();
const int cardid = const int cardid =
getLogic()->contentsKnown() ? card->getId() : (bottomCard ? getLogic()->getCards().size() - 1 : 0); getLogic()->contentsKnown() ? card->getId() : (bottomCard ? getLogic()->getCards().size() - 1 : 0);
CardDragItem *drag = card->createDragItem(cardid, event->pos(), event->scenePos(), forceFaceDown); CardDragItem *drag =
getCardItemForId(card->getId())->createDragItem(cardid, event->pos(), event->scenePos(), forceFaceDown);
drag->grabMouse(); drag->grabMouse();
setCursor(Qt::OpenHandCursor); setCursor(Qt::OpenHandCursor);
} }
@ -128,8 +140,8 @@ void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
void PileZone::hoverEnterEvent(QGraphicsSceneHoverEvent *event) void PileZone::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{ {
if (!getLogic()->getCards().isEmpty()) { if (!cards.isEmpty()) {
getLogic()->getCards()[0]->processHoverEvent(); cards[0]->processHoverEvent();
} }
QGraphicsItem::hoverEnterEvent(event); QGraphicsItem::hoverEnterEvent(event);
} }

View file

@ -17,11 +17,8 @@
class PileZone : public CardZone class PileZone : public CardZone
{ {
Q_OBJECT Q_OBJECT
private slots: public slots:
void callUpdate() void onCardAdded(CardState *toAdd, int, int) override;
{
update();
}
public: public:
PileZone(PileZoneLogic *_logic, QGraphicsItem *parent); PileZone(PileZoneLogic *_logic, QGraphicsItem *parent);

View file

@ -85,7 +85,7 @@ SelectZone::StackLayoutParams SelectZone::buildStackParams(qreal minOffset) cons
return {0, boundingRect().height(), 0.0, 0.0, minOffset}; return {0, boundingRect().height(), 0.0, 0.0, minOffset};
} }
const auto cardCount = static_cast<int>(cards.size()); const auto cardCount = static_cast<int>(cards.size());
const qreal cardHeight = cards.at(0)->boundingRect().height(); const qreal cardHeight = 200; // TODO cards.at(0)->boundingRect().height();
const qreal offset = stackingOffset(cardHeight); const qreal offset = stackingOffset(cardHeight);
return {cardCount, boundingRect().height(), cardHeight, offset, minOffset}; return {cardCount, boundingRect().height(), cardHeight, offset, minOffset};
} }
@ -109,7 +109,7 @@ void SelectZone::restoreStaleEscapedCards()
if (!cardClipContainer) { if (!cardClipContainer) {
return; return;
} }
for (auto *card : getLogic()->getCards()) { for (auto *card : cards) {
// A card parented to the zone (instead of the clip container) should // A card parented to the zone (instead of the clip container) should
// only occur while it is actively hovered. If hover cleanup was // only occur while it is actively hovered. If hover cleanup was
// missed, reparent it back so clipping resumes. // missed, reparent it back so clipping resumes.
@ -121,7 +121,6 @@ void SelectZone::restoreStaleEscapedCards()
void SelectZone::layoutCardsVertically(const StackLayoutParams &params) void SelectZone::layoutCardsVertically(const StackLayoutParams &params)
{ {
const auto &cards = getLogic()->getCards();
if (cards.isEmpty() || params.cardCount <= 0) { if (cards.isEmpty() || params.cardCount <= 0) {
return; return;
} }
@ -158,7 +157,7 @@ SelectZone::~SelectZone()
// parent-child tree is consistent for destruction. setParentItem() does // parent-child tree is consistent for destruction. setParentItem() does
// not invalidate getLogic()->getCards() (it modifies the graphics tree, // not invalidate getLogic()->getCards() (it modifies the graphics tree,
// not the zone's logical card list). // not the zone's logical card list).
for (auto *card : getLogic()->getCards()) { for (auto *card : cards) {
if (card && card->parentItem() == this) { if (card && card->parentItem() == this) {
card->setParentItem(cardClipContainer); card->setParentItem(cardClipContainer);
} }
@ -166,14 +165,16 @@ SelectZone::~SelectZone()
} }
} }
void SelectZone::onCardAdded(CardItem *addedCard) void SelectZone::onCardAdded(CardState *toAdd, int x, int y)
{ {
if (cardClipContainer && addedCard) { if (cardClipContainer && toAdd) {
CardItem *addedCard = new CardItem(toAdd, this);
addedCard->setParentItem(cardClipContainer); addedCard->setParentItem(cardClipContainer);
addedCard->setVisible(true); addedCard->setVisible(true);
addedCard->update(); addedCard->update();
emit cardItemAdded(addedCard);
} else { } else {
CardZone::onCardAdded(addedCard); CardZone::onCardAdded(toAdd, x, y);
} }
} }
@ -241,8 +242,8 @@ void SelectZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
} }
QRectF selectionRect = QRectF(selectionOrigin, pos).normalized(); QRectF selectionRect = QRectF(selectionOrigin, pos).normalized();
for (auto card : getLogic()->getCards()) { for (auto card : cards) {
if (card->getAttachedTo() && card->getAttachedTo()->getZone() != getLogic()) { if (card->getState()->getAttachedTo() && card->getState()->getAttachedTo()->getZone() != getLogic()) {
continue; continue;
} }

View file

@ -29,7 +29,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, int x, int y) 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

@ -146,7 +146,7 @@ void TableZone::handleDropEventByGrid(const QList<CardDragItem *> &dragItems,
ctm->set_face_down(true); ctm->set_face_down(true);
} }
if (startZone->getName() != getLogic()->getName() && !item->isForceFaceDown()) { if (startZone->getName() != getLogic()->getName() && !item->isForceFaceDown()) {
const auto &card = item->getItem()->getCard(); const auto &card = item->getItem()->getState()->getCard();
if (card) { if (card) {
ctm->set_pt(card.getInfo().getPowTough().toStdString()); ctm->set_pt(card.getInfo().getPowTough().toStdString());
} }
@ -161,8 +161,8 @@ void TableZone::reorganizeCards()
// Calculate card stack widths so mapping functions work properly // Calculate card stack widths so mapping functions work properly
computeCardStackWidths(); computeCardStackWidths();
for (int i = 0; i < getLogic()->getCards().size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
QPoint gridPoint = getLogic()->getCards()[i]->getGridPos(); QPoint gridPoint = cards[i]->getState()->getGridPos();
if (gridPoint.x() == -1) { if (gridPoint.x() == -1) {
continue; continue;
} }
@ -171,21 +171,22 @@ void TableZone::reorganizeCards()
qreal x = mapPoint.x(); qreal x = mapPoint.x();
qreal y = mapPoint.y(); qreal y = mapPoint.y();
int numberAttachedCards = getLogic()->getCards()[i]->getAttachedCards().size(); int numberAttachedCards = cards[i]->getState()->getAttachedCards().size();
qreal actualX = x + numberAttachedCards * STACKED_CARD_OFFSET_X; qreal actualX = x + numberAttachedCards * STACKED_CARD_OFFSET_X;
qreal actualY = y; qreal actualY = y;
if (numberAttachedCards) { if (numberAttachedCards) {
actualY += 15; actualY += 15;
} }
getLogic()->getCards()[i]->setPos(actualX, actualY); cards[i]->setPos(actualX, actualY);
getLogic()->getCards()[i]->setRealZValue(ZValues::tableCardZValue(actualX, actualY)); cards[i]->setRealZValue(ZValues::tableCardZValue(actualX, actualY));
QListIterator<CardItem *> attachedCardIterator(getLogic()->getCards()[i]->getAttachedCards()); QListIterator<CardState *> attachedCardIterator(cards[i]->getState()->getAttachedCards());
int j = 0; int j = 0;
while (attachedCardIterator.hasNext()) { while (attachedCardIterator.hasNext()) {
++j; ++j;
CardItem *attachedCard = attachedCardIterator.next(); CardState *attachedState = attachedCardIterator.next();
CardItem *attachedCard = getCardItemForId(attachedState->getId());
qreal childX = actualX - j * STACKED_CARD_OFFSET_X; qreal childX = actualX - j * STACKED_CARD_OFFSET_X;
qreal childY = y + 5; qreal childY = y + 5;
attachedCard->setPos(childX, childY); attachedCard->setPos(childX, childY);
@ -204,7 +205,7 @@ void TableZone::toggleTapped()
auto isCardOnTable = [](const QGraphicsItem *item) { auto isCardOnTable = [](const QGraphicsItem *item) {
if (auto card = qgraphicsitem_cast<const CardItem *>(item)) { if (auto card = qgraphicsitem_cast<const CardItem *>(item)) {
return card->getZone()->getName() == ZoneNames::TABLE; return card->getState()->getZone()->getName() == ZoneNames::TABLE;
} }
return false; return false;
}; };
@ -212,15 +213,15 @@ void TableZone::toggleTapped()
std::copy_if(selectedItemsRaw.begin(), selectedItemsRaw.end(), std::back_inserter(selectedItems), isCardOnTable); std::copy_if(selectedItemsRaw.begin(), selectedItemsRaw.end(), std::back_inserter(selectedItems), isCardOnTable);
bool tapAll = std::any_of(selectedItems.begin(), selectedItems.end(), [](const QGraphicsItem *item) { bool tapAll = std::any_of(selectedItems.begin(), selectedItems.end(), [](const QGraphicsItem *item) {
return !qgraphicsitem_cast<const CardItem *>(item)->getTapped(); return !qgraphicsitem_cast<const CardItem *>(item)->getState()->getTapped();
}); });
QList<const ::google::protobuf::Message *> cmdList; QList<const ::google::protobuf::Message *> cmdList;
for (const auto &selectedItem : selectedItems) { for (const auto &selectedItem : selectedItems) {
CardItem *temp = qgraphicsitem_cast<CardItem *>(selectedItem); CardItem *temp = qgraphicsitem_cast<CardItem *>(selectedItem);
if (temp->getTapped() != tapAll) { if (temp->getState()->getTapped() != tapAll) {
Command_SetCardAttr *cmd = new Command_SetCardAttr; Command_SetCardAttr *cmd = new Command_SetCardAttr;
cmd->set_zone(getLogic()->getName().toStdString()); cmd->set_zone(getLogic()->getName().toStdString());
cmd->set_card_id(temp->getId()); cmd->set_card_id(temp->getState()->getId());
cmd->set_attribute(AttrTapped); cmd->set_attribute(AttrTapped);
cmd->set_attr_value(tapAll ? "1" : "0"); cmd->set_attr_value(tapAll ? "1" : "0");
cmdList.append(cmd); cmdList.append(cmd);
@ -235,9 +236,9 @@ void TableZone::resizeToContents()
int xMax = 0; int xMax = 0;
// Find rightmost card position, which includes the left margin amount. // Find rightmost card position, which includes the left margin amount.
for (int i = 0; i < getLogic()->getCards().size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
if (getLogic()->getCards()[i]->pos().x() > xMax) { if (cards[i]->pos().x() > xMax) {
xMax = (int)getLogic()->getCards()[i]->pos().x(); xMax = (int)cards[i]->pos().x();
} }
} }
@ -258,9 +259,9 @@ void TableZone::resizeToContents()
CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const
{ {
for (int i = 0; i < getLogic()->getCards().size(); i++) { for (int i = 0; i < cards.size(); i++) {
if (getLogic()->getCards().at(i)->getGridPoint() == gridPoint) { if (cards.at(i)->getState()->getGridPoint() == gridPoint) {
return getLogic()->getCards().at(i); return cards.at(i);
} }
} }
return 0; return 0;
@ -277,8 +278,8 @@ void TableZone::computeCardStackWidths()
// Each card stack is three grid points worth of card locations. // Each card stack is three grid points worth of card locations.
// First pass: compute the number of cards at each card stack. // First pass: compute the number of cards at each card stack.
QMap<int, int> cardStackCount; QMap<int, int> cardStackCount;
for (int i = 0; i < getLogic()->getCards().size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
const QPoint &gridPoint = getLogic()->getCards()[i]->getGridPos(); const QPoint &gridPoint = cards[i]->getState()->getGridPos();
if (gridPoint.x() == -1) { if (gridPoint.x() == -1) {
continue; continue;
} }
@ -289,8 +290,8 @@ void TableZone::computeCardStackWidths()
// Second pass: compute the width at each card stack. // Second pass: compute the width at each card stack.
cardStackWidth.clear(); cardStackWidth.clear();
for (int i = 0; i < getLogic()->getCards().size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
const QPoint &gridPoint = getLogic()->getCards()[i]->getGridPos(); const QPoint &gridPoint = cards[i]->getState()->getGridPos();
if (gridPoint.x() == -1) { if (gridPoint.x() == -1) {
continue; continue;
} }
@ -298,8 +299,8 @@ void TableZone::computeCardStackWidths()
const int key = getCardStackMapKey(gridPoint.x() / 3, gridPoint.y()); const int key = getCardStackMapKey(gridPoint.x() / 3, gridPoint.y());
const int stackCount = cardStackCount.value(key, 0); const int stackCount = cardStackCount.value(key, 0);
if (stackCount == 1) { if (stackCount == 1) {
cardStackWidth.insert(key, CardDimensions::WIDTH + getLogic()->getCards()[i]->getAttachedCards().size() * cardStackWidth.insert(key, CardDimensions::WIDTH +
STACKED_CARD_OFFSET_X); cards[i]->getState()->getAttachedCards().size() * STACKED_CARD_OFFSET_X);
} else { } else {
cardStackWidth.insert(key, CardDimensions::WIDTH + (stackCount - 1) * STACKED_CARD_OFFSET_X); cardStackWidth.insert(key, CardDimensions::WIDTH + (stackCount - 1) * STACKED_CARD_OFFSET_X);
} }

View file

@ -68,7 +68,9 @@ void ZoneViewZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardList) void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardList)
{ {
int numberCards = qobject_cast<ZoneViewZoneLogic *>(getLogic())->getNumberCards(); // TODO
Q_UNUSED(cardList);
/*int numberCards = qobject_cast<ZoneViewZoneLogic *>(getLogic())->getNumberCards();
if (!cardList.isEmpty()) { if (!cardList.isEmpty()) {
for (int i = 0; i < cardList.size(); ++i) { for (int i = 0; i < cardList.size(); ++i) {
auto card = cardList[i]; auto card = cardList[i];
@ -100,12 +102,14 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
getLogic()->addCard(copy, false, i); getLogic()->addCard(copy, false, i);
} }
reorganizeCards(); reorganizeCards();
} }*/
} }
void ZoneViewZone::zoneDumpReceived(const Response &r) void ZoneViewZone::zoneDumpReceived(const Response &r)
{ {
const Response_DumpZone &resp = r.GetExtension(Response_DumpZone::ext); Q_UNUSED(r);
// TODO
/*const Response_DumpZone &resp = r.GetExtension(Response_DumpZone::ext);
const int respCardListSize = resp.zone_info().card_list_size(); const int respCardListSize = resp.zone_info().card_list_size();
for (int i = 0; i < respCardListSize; ++i) { for (int i = 0; i < respCardListSize; ++i) {
const ServerInfo_Card &cardInfo = resp.zone_info().card_list(i); const ServerInfo_Card &cardInfo = resp.zone_info().card_list(i);
@ -117,7 +121,7 @@ void ZoneViewZone::zoneDumpReceived(const Response &r)
} }
qobject_cast<ZoneViewZoneLogic *>(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE); qobject_cast<ZoneViewZoneLogic *>(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE);
reorganizeCards(); reorganizeCards();*/
// clang-format off // clang-format off
emit getLogic()->cardCountChanged(); // emit keyword causes spurious spacing around -> emit getLogic()->cardCountChanged(); // emit keyword causes spurious spacing around ->
// clang-format on // clang-format on
@ -130,11 +134,11 @@ void ZoneViewZone::reorganizeCards()
CardList cardsToDisplay = CardList(getLogic()->getCards().getContentsKnown()); CardList cardsToDisplay = CardList(getLogic()->getCards().getContentsKnown());
for (auto card : getLogic()->getCards()) { for (auto card : getLogic()->getCards()) {
if (filterString.check(card->getCard().getCardPtr())) { if (filterString.check(card->getCard().getCardPtr())) {
card->show(); // card->show();
cardsToDisplay.append(card); cardsToDisplay.append(card);
} else { } /* else {
card->hide(); card->hide();
} }*/
} }
// sort cards // sort cards
@ -199,7 +203,7 @@ 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);
QString columnProp = extractor(c); QString columnProp = extractor(c);
if (i) { // if not the first card if (i) { // if not the first card
@ -211,12 +215,12 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
} }
} }
lastColumnProp = columnProp; /* TODO lastColumnProp = columnProp;
qreal x = col * CardDimensions::WIDTH_F; qreal 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); c->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
c->setRealZValue(i); c->setRealZValue(i);
longestRow = qMax(row, longestRow); longestRow = qMax(row, longestRow);*/
} }
// +1 because the row/col variables used in the calculations are 0-indexed but // +1 because the row/col variables used in the calculations are 0-indexed but
@ -240,11 +244,12 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
qCDebug(ViewZoneLog) << "reorganizeCards: rows=" << rows << "cols=" << cols; 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); CardState *c = cards.at(i);
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); CardItem *ci = getCardItemForId(c->getId());
c->setRealZValue(i); ci->setPos(HORIZONTAL_PADDING + x, VERTICAL_PADDING + y);
ci->setRealZValue(i);
} }
return GridSize{rows, qMax(cols, 1)}; return GridSize{rows, qMax(cols, 1)};

View file

@ -65,7 +65,7 @@ void CardInfoDisplayWidget::setCard(const CardRef &cardRef)
void CardInfoDisplayWidget::setCard(AbstractCardItem *card) void CardInfoDisplayWidget::setCard(AbstractCardItem *card)
{ {
setCard(card->getCard()); setCard(card->getState()->getCard());
} }
void CardInfoDisplayWidget::clear() void CardInfoDisplayWidget::clear()

View file

@ -171,7 +171,7 @@ void CardInfoFrameWidget::setCard(const CardRef &cardRef)
void CardInfoFrameWidget::setCard(AbstractCardItem *card) void CardInfoFrameWidget::setCard(AbstractCardItem *card)
{ {
if (card) { if (card) {
setCard(card->getCard()); setCard(card->getState()->getCard());
} }
} }

View file

@ -658,7 +658,7 @@ PlayerLogic *TabGame::addPlayer(PlayerLogic *newPlayer)
auto *view = scene->viewForPlayer(newPlayer->getPlayerInfo()->getId()); auto *view = scene->viewForPlayer(newPlayer->getPlayerInfo()->getId());
connect(newPlayer, &PlayerLogic::newCardAdded, this, &TabGame::newCardAdded); connect(view, &PlayerGraphicsItem::cardItemAdded, this, &TabGame::newCardAdded);
connect(newPlayer, &PlayerLogic::openDeckEditor, this, &TabGame::openDeckEditor); connect(newPlayer, &PlayerLogic::openDeckEditor, this, &TabGame::openDeckEditor);
connect(view->getPlayerMenu(), &PlayerMenu::cardMenuUpdated, this, &TabGame::setCardMenu); connect(view->getPlayerMenu(), &PlayerMenu::cardMenuUpdated, this, &TabGame::setCardMenu);
connect(view, &PlayerGraphicsItem::cardInfoRequested, this, &TabGame::viewCardInfo); connect(view, &PlayerGraphicsItem::cardInfoRequested, this, &TabGame::viewCardInfo);