Lots of todos but it compiles.

Took 3 hours 38 minutes

Took 11 seconds

Took 9 minutes

Took 2 minutes

Took 22 minutes

Took 43 minutes

Took 4 minutes

Took 31 minutes

Took 7 seconds

Took 1 minute

[Game][Player] Pull out graphics_items out of player_logic

Took 3 minutes

Took 24 seconds

Took 5 minutes

Took 19 minutes

Took 7 minutes

Took 32 seconds

Took 3 minutes

Took 14 minutes

Took 5 seconds

Took 28 minutes

Took 5 minutes

Took 28 minutes

Took 7 seconds

Took 12 minutes

Took 20 minutes

Took 2 minutes
This commit is contained in:
Lukas Brübach 2026-05-21 23:26:31 +02:00
parent 0f3e6fbe26
commit 0cfffdf9df
62 changed files with 789 additions and 699 deletions

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 <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.
*/
CardItem *CardList::findCard(const int cardId) const
CardState *CardList::findCard(const int cardId) const
{
if (!contentsKnown && !empty()) {
return at(0);
@ -46,7 +46,7 @@ void CardList::sortBy(const QList<SortOption> &option)
return;
}
auto comparator = [&option](CardItem *a, CardItem *b) {
auto comparator = [&option](CardState *a, CardState *b) {
for (auto prop : option) {
auto extractor = getExtractorFor(prop);
QString t1 = extractor(a);
@ -113,24 +113,24 @@ static QString getColorSortString(const CardInfo &c, bool appendAtEnd)
/**
* @brief returns the function that extracts the given property from the CardItem.
*/
std::function<QString(CardItem *)> CardList::getExtractorFor(SortOption option)
std::function<QString(CardState *)> CardList::getExtractorFor(SortOption option)
{
switch (option) {
case NoSort:
return [](CardItem *) { return ""; };
return [](CardState *) { return ""; };
case SortByMainType:
return [](CardItem *c) { return c->getCardInfo().getMainCardType(); };
return [](CardState *c) { return c->getCardInfo().getMainCardType(); };
case SortByManaValue:
// getCmc returns the int as a string. We pad with 0's so that string comp also works on it
return [](CardItem *c) { return c->getCard() ? c->getCardInfo().getCmc().rightJustified(4, '0') : ""; };
return [](CardState *c) { return c->getCard() ? c->getCardInfo().getCmc().rightJustified(4, '0') : ""; };
case SortByColorGrouping:
return [](CardItem *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), false) : ""; };
return [](CardState *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), false) : ""; };
case SortByName:
return [](CardItem *c) { return c->getName(); };
return [](CardState *c) { return c->getName(); };
case SortByType:
return [](CardItem *c) { return c->getCardInfo().getCardType(); };
return [](CardState *c) { return c->getCardInfo().getCardType(); };
case SortByManaCost:
return [](CardItem *c) {
return [](CardState *c) {
if (!c->getCard()) {
return QString();
}
@ -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());
};
case SortByColors:
return [](CardItem *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), true) : ""; };
return [](CardState *c) { return c->getCard() ? getColorSortString(c->getCardInfo(), true) : ""; };
case SortByPt:
// do the same padding trick as above
return
[](CardItem *c) { return c->getCard() ? c->getCardInfo().getPowTough().rightJustified(10, '0') : ""; };
[](CardState *c) { return c->getCard() ? c->getCardInfo().getPowTough().rightJustified(10, '0') : ""; };
case SortBySet:
return [](CardItem *c) { return c->getCardInfo().getSetsNames(); };
return [](CardState *c) { return c->getCardInfo().getSetsNames(); };
case SortByPrinting:
return [](CardItem *c) { return c->getProviderId(); };
return [](CardState *c) { return c->getProviderId(); };
}
// this line should never be reached
qCWarning(CardListLog) << "cardlist.cpp: Could not find extractor for SortOption" << option;
return [](CardItem *) { return ""; };
return [](CardState *) { return ""; };
}

View file

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

View file

@ -1,5 +1,43 @@
#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);
}
}
void CardState::processCardInfo(const ServerInfo_Card &_info)
{
clearCounters();
const int counterListSize = _info.counter_list_size();
for (int i = 0; i < counterListSize; ++i) {
const ServerInfo_CardCounter &counterInfo = _info.counter_list(i);
insertCounter(counterInfo.id(), counterInfo.value());
}
setId(_info.id());
setCardRef({QString::fromStdString(_info.name()), QString::fromStdString(_info.provider_id())});
setAttacking(_info.attacking());
setFaceDown(_info.face_down());
setPT(QString::fromStdString(_info.pt()));
setAnnotation(QString::fromStdString(_info.annotation()));
setColor(QString::fromStdString(_info.color()));
setTapped(_info.tapped());
setDestroyOnZoneChange(_info.destroy_on_zone_change());
setDoesntUntap(_info.doesnt_untap());
}
void CardState::resetState(bool keepAnnotations)
{
attacking = false;
@ -11,6 +49,11 @@ void CardState::resetState(bool keepAnnotations)
attachedTo = nullptr;
}
void CardState::clearAttachedCards()
{
attachedCards.clear();
}
void CardState::setZone(CardZoneLogic *_zone)
{
if (zone == _zone) {
@ -100,7 +143,7 @@ void CardState::setDestroyOnZoneChange(bool _destroyOnZoneChange)
emit stateChanged();
}
void CardState::setAttachedTo(CardItem *_attachedTo)
void CardState::setAttachedTo(CardState *_attachedTo)
{
if (attachedTo == _attachedTo) {
return;
@ -108,4 +151,40 @@ void CardState::setAttachedTo(CardItem *_attachedTo)
attachedTo = _attachedTo;
emit attachedToChanged(_attachedTo);
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
#define COCKATRICE_CARD_STATE_H
#include "abstract_card_state.h"
#include <QMap>
#include <QObject>
#include <QPoint>
#include <libcockatrice/protocol/pb/serverinfo_card.pb.h>
class CardZoneLogic;
class CardItem;
class CardState : public QObject
class CardState : public AbstractCardState
{
Q_OBJECT
@ -17,8 +20,12 @@ private:
QString pt;
bool doesntUntap = false;
bool destroyOnZoneChange = false;
bool visible = false;
CardItem *attachedTo = nullptr;
QPoint gridPoint;
CardState *attachedTo = nullptr;
QList<CardState *> attachedCards;
CardZoneLogic *zone = nullptr;
signals:
@ -30,15 +37,17 @@ signals:
void ptChanged(const QString &newPt);
void doesntUntapChanged(bool newValue);
void destroyOnZoneChangeChanged(bool newValue);
void attachedToChanged(CardItem *newAttachedTo);
void attachedToChanged(CardState *newAttachedTo);
void zoneChanged(CardState *changedCard, CardZoneLogic *newZone);
void visibleChanged(bool visible);
public:
explicit CardState(QObject *parent, CardZoneLogic *_zone) : QObject(parent), zone(_zone)
{
}
explicit CardState(PlayerLogic *_owner, const CardRef &cardRef = {}, int _id = -1, CardZoneLogic *_zone = nullptr);
void prepareDelete();
void processCardInfo(const ServerInfo_Card &_info);
void resetState(bool keepAnnotations);
void clearAttachedCards();
CardZoneLogic *getZone() const
{
@ -92,12 +101,51 @@ public:
void setDestroyOnZoneChange(bool _destroyOnZoneChange);
CardItem *getAttachedTo() const
CardState *getAttachedTo() const
{
return attachedTo;
}
void setAttachedTo(CardItem *_attachedTo);
[[nodiscard]] QPoint getGridPoint() const
{
return gridPoint;
}
void setGridPoint(const QPoint &_gridPoint)
{
gridPoint = _gridPoint;
}
[[nodiscard]] QPoint getGridPos() const
{
return gridPoint;
}
bool getVisible() const
{
return visible;
}
void setVisible(bool _visible)
{
if (_visible == visible) {
return;
}
visible = _visible;
emit visibleChanged(visible);
}
void setAttachedTo(CardState *_attachedTo);
void addAttachedCard(CardState *card)
{
attachedCards.append(card);
}
void removeAttachedCard(CardState *card)
{
attachedCards.removeOne(card);
}
[[nodiscard]] const QList<CardState *> &getAttachedCards() const
{
return attachedCards;
}
};
#endif // COCKATRICE_CARD_STATE_H