mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-02 11:33:55 -07:00
Player refactor (#6112)
* Player refactor. Took 1 hour 43 minutes Took 1 minute Took 23 seconds * Tiny lint. Took 3 minutes * Hook up tap logic again. Took 13 minutes * Fix an include. Took 3 minutes * Stuff. Took 6 minutes * Fix typo. Took 7 minutes * Include. Took 1 minute * Reorganize method/variable definitions, remove unused ones. Took 1 hour 8 minutes Took 24 seconds * Clean up some unused imports. Took 6 minutes * Player holds the deck, emits deckChanged(), other elements player->getDeck() to respond to changes. Took 37 minutes * Connect player->openDeckEditor signal directly in the player constructor Took 6 minutes * Emit openDeckEditor signal in player_actions again. Took 3 minutes * Do to-do's Took 3 hours 32 minutes * Lint. Took 3 minutes * Lint again. Took 2 minutes * Fix include. Took 32 minutes * The stack should ensure card visibility. Took 21 minutes * Fine, the game can remember the tab. Took 10 minutes Took 21 seconds Took 9 seconds * zoneId is a dynamic gameplay property and thus belongs in player.cpp Took 11 minutes Took 19 seconds * Signal view removal, addition. Took 5 minutes * Ensure all players are considered local in local game. Took 10 minutes * ENSURE they are. Took 8 minutes * Bounds check data sent by QAction() Took 54 minutes * Move comment. Took 20 seconds * Reimplement logging category for game_event_handler.cpp, remove linebreaks. Took 36 seconds * PlayerGraphicsItem is responsible for retranslateUi, not Player. Took 14 seconds * Set menu for sideboard again, translate some menu titles, reimplement actIncPT action Took 54 seconds * Comment spacing. Took 43 seconds * Change message_log_widget.cpp slots to take CardZoneLogic parameters as emitted by PlayerEventHandler. Took 7 minutes Took 14 seconds * Remove unused player_logger.cpp Took 2 minutes * Query local game state correctly from tab_supervisor again Took 3 minutes * Revert Deck legality checker. Took 3 minutes * Instantiate menu before graphics item. Took 1 hour 5 minutes Took 55 minutes * Differentiate games and replays. Took 9 seconds * Lint. Took 10 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
b8e545bfa4
commit
9601a1fa4e
92 changed files with 7104 additions and 5827 deletions
|
|
@ -1,102 +1,31 @@
|
|||
#include "card_zone.h"
|
||||
|
||||
#include "../board/card_item.h"
|
||||
#include "../cards/card_database_manager.h"
|
||||
#include "../player/player.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "pile_zone.h"
|
||||
#include "view_zone.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMenu>
|
||||
|
||||
/**
|
||||
* @param _p the player that the zone belongs to
|
||||
* @param _name internal name of the zone
|
||||
* @param _isShufflable whether it makes sense to shuffle this zone by default after viewing it
|
||||
* @param _contentsKnown whether the cards in the zone are known to the client
|
||||
* @param parent the parent graphics object.
|
||||
*/
|
||||
CardZone::CardZone(Player *_p,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QGraphicsItem *parent)
|
||||
: AbstractGraphicsItem(parent), player(_p), name(_name), cards(_contentsKnown), views{}, menu(nullptr),
|
||||
doubleClickAction(0), hasCardAttr(_hasCardAttr), isShufflable(_isShufflable)
|
||||
CardZone::CardZone(CardZoneLogic *_logic, QGraphicsItem *parent)
|
||||
: AbstractGraphicsItem(parent), menu(nullptr), doubleClickAction(0), logic(_logic)
|
||||
{
|
||||
// If we join a game before the card db finishes loading, the cards might have the wrong printings.
|
||||
// Force refresh all cards in the zone when db finishes loading to fix that.
|
||||
connect(CardDatabaseManager::getInstance(), &CardDatabase::cardDatabaseLoadingFinished, this,
|
||||
&CardZone::refreshCardInfos);
|
||||
connect(logic, &CardZoneLogic::retranslateUi, this, &CardZone::retranslateUi);
|
||||
connect(logic, &CardZoneLogic::cardAdded, this, &CardZone::onCardAdded);
|
||||
connect(logic, &CardZoneLogic::setGraphicsVisibility, this, [this](bool v) { this->setVisible(v); });
|
||||
connect(logic, &CardZoneLogic::updateGraphics, this, [this]() { update(); });
|
||||
connect(logic, &CardZoneLogic::reorganizeCards, this, &CardZone::reorganizeCards);
|
||||
}
|
||||
|
||||
void CardZone::onCardAdded(CardItem *addedCard)
|
||||
{
|
||||
addedCard->setParentItem(this);
|
||||
addedCard->update();
|
||||
}
|
||||
|
||||
void CardZone::retranslateUi()
|
||||
{
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
cards[i]->retranslateUi();
|
||||
}
|
||||
|
||||
void CardZone::clearContents()
|
||||
{
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
// If an incorrectly implemented server doesn't return attached cards to whom they belong before dropping a
|
||||
// player, we have to return them to avoid a crash.
|
||||
const QList<CardItem *> &attachedCards = cards[i]->getAttachedCards();
|
||||
for (auto attachedCard : attachedCards)
|
||||
attachedCard->setParentItem(attachedCard->getZone());
|
||||
|
||||
player->deleteCard(cards.at(i));
|
||||
}
|
||||
cards.clear();
|
||||
emit cardCountChanged();
|
||||
}
|
||||
|
||||
QString CardZone::getTranslatedName(bool theirOwn, GrammaticalCase gc) const
|
||||
{
|
||||
QString ownerName = player->getName();
|
||||
if (name == "hand")
|
||||
return (theirOwn ? tr("their hand", "nominative") : tr("%1's hand", "nominative").arg(ownerName));
|
||||
else if (name == "deck")
|
||||
switch (gc) {
|
||||
case CaseLookAtZone:
|
||||
return (theirOwn ? tr("their library", "look at zone")
|
||||
: tr("%1's library", "look at zone").arg(ownerName));
|
||||
case CaseTopCardsOfZone:
|
||||
return (theirOwn ? tr("of their library", "top cards of zone,")
|
||||
: tr("of %1's library", "top cards of zone").arg(ownerName));
|
||||
case CaseRevealZone:
|
||||
return (theirOwn ? tr("their library", "reveal zone")
|
||||
: tr("%1's library", "reveal zone").arg(ownerName));
|
||||
case CaseShuffleZone:
|
||||
return (theirOwn ? tr("their library", "shuffle") : tr("%1's library", "shuffle").arg(ownerName));
|
||||
default:
|
||||
return (theirOwn ? tr("their library", "nominative") : tr("%1's library", "nominative").arg(ownerName));
|
||||
}
|
||||
else if (name == "grave")
|
||||
return (theirOwn ? tr("their graveyard", "nominative") : tr("%1's graveyard", "nominative").arg(ownerName));
|
||||
else if (name == "rfg")
|
||||
return (theirOwn ? tr("their exile", "nominative") : tr("%1's exile", "nominative").arg(ownerName));
|
||||
else if (name == "sb")
|
||||
switch (gc) {
|
||||
case CaseLookAtZone:
|
||||
return (theirOwn ? tr("their sideboard", "look at zone")
|
||||
: tr("%1's sideboard", "look at zone").arg(ownerName));
|
||||
case CaseNominative:
|
||||
return (theirOwn ? tr("their sideboard", "nominative")
|
||||
: tr("%1's sideboard", "nominative").arg(ownerName));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else {
|
||||
return (theirOwn ? tr("their custom zone '%1'", "nominative").arg(name)
|
||||
: tr("%1's custom zone '%2'", "nominative").arg(ownerName).arg(name));
|
||||
}
|
||||
return QString();
|
||||
for (int i = 0; i < getLogic()->getCards().size(); ++i)
|
||||
getLogic()->getCards()[i]->retranslateUi();
|
||||
}
|
||||
|
||||
void CardZone::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * /*event*/)
|
||||
|
|
@ -114,13 +43,6 @@ bool CardZone::showContextMenu(const QPoint &screenPos)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CardZone::refreshCardInfos()
|
||||
{
|
||||
for (const auto &cardItem : cards) {
|
||||
cardItem->refreshCardInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void CardZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
|
|
@ -132,104 +54,6 @@ void CardZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
event->ignore();
|
||||
}
|
||||
|
||||
void CardZone::addCard(CardItem *card, const bool reorganize, const int x, const int y)
|
||||
{
|
||||
if (!card) {
|
||||
qCWarning(CardZoneLog) << "CardZone::addCard() card is null; this shouldn't normally happen";
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto *view : views) {
|
||||
if (view->prepareAddCard(x)) {
|
||||
view->addCard(new CardItem(player, nullptr, card->getCardRef(), card->getId()), reorganize, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
card->setZone(this);
|
||||
addCardImpl(card, x, y);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
|
||||
emit cardCountChanged();
|
||||
}
|
||||
|
||||
CardItem *CardZone::getCard(int cardId)
|
||||
{
|
||||
CardItem *c = cards.findCard(cardId);
|
||||
if (!c) {
|
||||
qCWarning(CardZoneLog) << "CardZone::getCard: card id=" << cardId << "not found";
|
||||
return nullptr;
|
||||
}
|
||||
// If the card's id is -1, this zone is invisible,
|
||||
// so we need to give the card an id as it comes out.
|
||||
// It can be assumed that in an invisible zone, all cards are equal.
|
||||
if (c->getId() == -1) {
|
||||
c->setId(cardId);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
CardItem *CardZone::takeCard(int position, int cardId, bool toNewZone)
|
||||
{
|
||||
if (position == -1) {
|
||||
// position == -1 means either that the zone is indexed by card id
|
||||
// or that it doesn't matter which card you take.
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
if (cards[i]->getId() == cardId) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
if (position == -1)
|
||||
position = 0;
|
||||
}
|
||||
if (position >= cards.size())
|
||||
return nullptr;
|
||||
|
||||
for (auto *view : views) {
|
||||
view->removeCard(position, toNewZone);
|
||||
}
|
||||
|
||||
CardItem *c = cards.takeAt(position);
|
||||
|
||||
c->setId(cardId);
|
||||
|
||||
reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
return c;
|
||||
}
|
||||
|
||||
void CardZone::removeCard(CardItem *card)
|
||||
{
|
||||
if (!card) {
|
||||
qCWarning(CardZoneLog) << "CardZone::removeCard: card is null, this shouldn't normally happen";
|
||||
return;
|
||||
}
|
||||
|
||||
cards.removeOne(card);
|
||||
reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
player->deleteCard(card);
|
||||
}
|
||||
|
||||
void CardZone::moveAllToZone()
|
||||
{
|
||||
QList<QVariant> data = static_cast<QAction *>(sender())->data().toList();
|
||||
QString targetZone = data[0].toString();
|
||||
int targetX = data[1].toInt();
|
||||
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(targetZone.toStdString());
|
||||
cmd.set_x(targetX);
|
||||
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(cards[i]->getId());
|
||||
|
||||
player->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
QPointF CardZone::closestGridPoint(const QPointF &point)
|
||||
{
|
||||
return point;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,15 @@
|
|||
#ifndef CARDZONE_H
|
||||
#define CARDZONE_H
|
||||
|
||||
#include "../../client/translation.h"
|
||||
#include "../board/abstract_graphics_item.h"
|
||||
#include "../board/card_list.h"
|
||||
#include "../board/graphics_item_type.h"
|
||||
#include "logic/card_zone_logic.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QString>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CardZoneLog, "card_zone");
|
||||
|
||||
class Player;
|
||||
class ZoneViewZone;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
class QPainter;
|
||||
class CardDragItem;
|
||||
|
||||
/**
|
||||
* A zone in the game that can contain cards.
|
||||
* This class contains methods to get and modify the cards that are contained inside this zone.
|
||||
|
|
@ -27,26 +20,21 @@ class CardZone : public AbstractGraphicsItem
|
|||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
Player *player;
|
||||
QString name;
|
||||
CardList cards;
|
||||
QList<ZoneViewZone *> views;
|
||||
QMenu *menu;
|
||||
QAction *doubleClickAction;
|
||||
bool hasCardAttr;
|
||||
bool isShufflable;
|
||||
bool alwaysRevealTopCard;
|
||||
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
virtual void addCardImpl(CardItem *card, int x, int y) = 0;
|
||||
signals:
|
||||
void cardCountChanged();
|
||||
public slots:
|
||||
void moveAllToZone();
|
||||
bool showContextMenu(const QPoint &screenPos);
|
||||
virtual void reorganizeCards() = 0;
|
||||
virtual QPointF closestGridPoint(const QPointF &point);
|
||||
|
||||
private slots:
|
||||
void refreshCardInfos();
|
||||
QMenu *getMenu() const
|
||||
{
|
||||
return menu;
|
||||
}
|
||||
public slots:
|
||||
bool showContextMenu(const QPoint &screenPos);
|
||||
void onCardAdded(CardItem *addedCard);
|
||||
|
||||
public:
|
||||
enum
|
||||
|
|
@ -58,69 +46,23 @@ public:
|
|||
return Type;
|
||||
}
|
||||
virtual void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItem, CardZone *startZone, const QPoint &dropPoint) = 0;
|
||||
CardZone(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItem, CardZoneLogic *startZone, const QPoint &dropPoint) = 0;
|
||||
CardZone(CardZoneLogic *logic, QGraphicsItem *parent = nullptr);
|
||||
void retranslateUi();
|
||||
void clearContents();
|
||||
bool getHasCardAttr() const
|
||||
|
||||
CardZoneLogic *getLogic() const
|
||||
{
|
||||
return hasCardAttr;
|
||||
}
|
||||
bool getIsShufflable() const
|
||||
{
|
||||
return isShufflable;
|
||||
}
|
||||
QMenu *getMenu() const
|
||||
{
|
||||
return menu;
|
||||
return logic;
|
||||
}
|
||||
|
||||
void setMenu(QMenu *_menu, QAction *_doubleClickAction = 0)
|
||||
{
|
||||
menu = _menu;
|
||||
doubleClickAction = _doubleClickAction;
|
||||
}
|
||||
QString getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
QString getTranslatedName(bool theirOwn, GrammaticalCase gc) const;
|
||||
Player *getPlayer() const
|
||||
{
|
||||
return player;
|
||||
}
|
||||
bool contentsKnown() const
|
||||
{
|
||||
return cards.getContentsKnown();
|
||||
}
|
||||
const CardList &getCards() const
|
||||
{
|
||||
return cards;
|
||||
}
|
||||
void addCard(CardItem *card, bool reorganize, int x, int y = -1);
|
||||
// getCard() finds a card by id.
|
||||
CardItem *getCard(int cardId);
|
||||
// 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);
|
||||
void removeCard(CardItem *card);
|
||||
QList<ZoneViewZone *> &getViews()
|
||||
{
|
||||
return views;
|
||||
}
|
||||
virtual void reorganizeCards() = 0;
|
||||
virtual QPointF closestGridPoint(const QPointF &point);
|
||||
bool getAlwaysRevealTopCard() const
|
||||
{
|
||||
return alwaysRevealTopCard;
|
||||
}
|
||||
void setAlwaysRevealTopCard(bool _alwaysRevealTopCard)
|
||||
{
|
||||
alwaysRevealTopCard = _alwaysRevealTopCard;
|
||||
}
|
||||
|
||||
private:
|
||||
CardZoneLogic *logic;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
#include <QPainter>
|
||||
|
||||
HandZone::HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent)
|
||||
: SelectZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight)
|
||||
HandZone::HandZone(HandZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent)
|
||||
: SelectZone(_logic, parent), zoneHeight(_zoneHeight)
|
||||
{
|
||||
connect(themeManager, &ThemeManager::themeChanged, this, &HandZone::updateBg);
|
||||
updateBg();
|
||||
|
|
@ -22,50 +22,34 @@ void HandZone::updateBg()
|
|||
update();
|
||||
}
|
||||
|
||||
void HandZone::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
|
||||
if (!cards.getContentsKnown()) {
|
||||
card->setId(-1);
|
||||
card->setCardRef({});
|
||||
}
|
||||
card->setParentItem(this);
|
||||
card->resetState();
|
||||
card->setVisible(true);
|
||||
card->update();
|
||||
}
|
||||
|
||||
void HandZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint)
|
||||
void HandZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||
CardZoneLogic *startZone,
|
||||
const QPoint &dropPoint)
|
||||
{
|
||||
QPoint point = dropPoint + scenePos().toPoint();
|
||||
int x = -1;
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
for (x = 0; x < cards.size(); x++)
|
||||
if (point.x() < static_cast<CardItem *>(cards.at(x))->scenePos().x())
|
||||
for (x = 0; x < getLogic()->getCards().size(); x++)
|
||||
if (point.x() < static_cast<CardItem *>(getLogic()->getCards().at(x))->scenePos().x())
|
||||
break;
|
||||
} else {
|
||||
for (x = 0; x < cards.size(); x++)
|
||||
if (point.y() < static_cast<CardItem *>(cards.at(x))->scenePos().y())
|
||||
for (x = 0; x < getLogic()->getCards().size(); x++)
|
||||
if (point.y() < static_cast<CardItem *>(getLogic()->getCards().at(x))->scenePos().y())
|
||||
break;
|
||||
}
|
||||
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getId());
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_start_zone(startZone->getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(getLogic()->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_target_zone(getLogic()->getName().toStdString());
|
||||
cmd.set_x(x);
|
||||
cmd.set_y(-1);
|
||||
|
||||
for (int i = 0; i < dragItems.size(); ++i)
|
||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId());
|
||||
|
||||
player->sendGameCommand(cmd);
|
||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
QRectF HandZone::boundingRect() const
|
||||
|
|
@ -78,23 +62,23 @@ QRectF HandZone::boundingRect() const
|
|||
|
||||
void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Hand, player->getZoneId());
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Hand, getLogic()->getPlayer()->getZoneId());
|
||||
painter->fillRect(boundingRect(), brush);
|
||||
}
|
||||
|
||||
void HandZone::reorganizeCards()
|
||||
{
|
||||
if (!cards.isEmpty()) {
|
||||
const int cardCount = cards.size();
|
||||
if (!getLogic()->getCards().isEmpty()) {
|
||||
const int cardCount = getLogic()->getCards().size();
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
bool leftJustified = SettingsCache::instance().getLeftJustified();
|
||||
qreal cardWidth = cards.at(0)->boundingRect().width();
|
||||
qreal cardWidth = getLogic()->getCards().at(0)->boundingRect().width();
|
||||
const int xPadding = leftJustified ? cardWidth * 1.4 : 5;
|
||||
qreal totalWidth =
|
||||
leftJustified ? boundingRect().width() - (1 * xPadding) - 5 : boundingRect().width() - 2 * xPadding;
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *c = cards.at(i);
|
||||
CardItem *c = getLogic()->getCards().at(i);
|
||||
// If the total width of the cards is smaller than the available width,
|
||||
// the cards do not need to overlap and are displayed in the center of the area.
|
||||
if (cardWidth * cardCount > totalWidth)
|
||||
|
|
@ -109,16 +93,16 @@ void HandZone::reorganizeCards()
|
|||
}
|
||||
} else {
|
||||
qreal totalWidth = boundingRect().width();
|
||||
qreal cardWidth = cards.at(0)->boundingRect().width();
|
||||
qreal cardWidth = getLogic()->getCards().at(0)->boundingRect().width();
|
||||
qreal xspace = 5;
|
||||
qreal x1 = xspace;
|
||||
qreal x2 = totalWidth - xspace - cardWidth;
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *card = cards.at(i);
|
||||
CardItem *card = getLogic()->getCards().at(i);
|
||||
qreal x = (i % 2) ? x2 : x1;
|
||||
qreal y =
|
||||
divideCardSpaceInZone(i, cardCount, boundingRect().height(), cards.at(0)->boundingRect().height());
|
||||
qreal y = divideCardSpaceInZone(i, cardCount, boundingRect().height(),
|
||||
getLogic()->getCards().at(0)->boundingRect().height());
|
||||
card->setPos(x, y);
|
||||
card->setRealZValue(i);
|
||||
}
|
||||
|
|
@ -129,10 +113,10 @@ void HandZone::reorganizeCards()
|
|||
|
||||
void HandZone::sortHand()
|
||||
{
|
||||
if (cards.isEmpty()) {
|
||||
if (getLogic()->getCards().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
cards.sortBy({CardList::SortByMainType, CardList::SortByManaValue, CardList::SortByColorGrouping});
|
||||
getLogic()->sortCards({CardList::SortByMainType, CardList::SortByManaValue, CardList::SortByColorGrouping});
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef HANDZONE_H
|
||||
#define HANDZONE_H
|
||||
|
||||
#include "logic/hand_zone_logic.h"
|
||||
#include "select_zone.h"
|
||||
|
||||
class HandZone : public SelectZone
|
||||
|
|
@ -14,16 +15,14 @@ public slots:
|
|||
void updateOrientation();
|
||||
|
||||
public:
|
||||
HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = nullptr);
|
||||
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint) override;
|
||||
HandZone(HandZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent = nullptr);
|
||||
void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void reorganizeCards() override;
|
||||
void sortHand();
|
||||
void setWidth(qreal _width);
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
206
cockatrice/src/game/zones/logic/card_zone_logic.cpp
Normal file
206
cockatrice/src/game/zones/logic/card_zone_logic.cpp
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
#include "card_zone_logic.h"
|
||||
|
||||
#include "../../board/card_item.h"
|
||||
#include "../../cards/card_database_manager.h"
|
||||
#include "../../player/player.h"
|
||||
#include "../pile_zone.h"
|
||||
#include "../view_zone.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "view_zone_logic.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @param _player the player that the zone belongs to
|
||||
* @param _name internal name of the zone
|
||||
* @param _isShufflable whether it makes sense to shuffle this zone by default after viewing it
|
||||
* @param _contentsKnown whether the cards in the zone are known to the client
|
||||
* @param parent the parent QObject.
|
||||
*/
|
||||
CardZoneLogic::CardZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent)
|
||||
: QObject(parent), player(_player), name(_name), cards(_contentsKnown), views{}, hasCardAttr(_hasCardAttr),
|
||||
isShufflable(_isShufflable)
|
||||
{
|
||||
// If we join a game before the card db finishes loading, the cards might have the wrong printings.
|
||||
// Force refresh all cards in the zone when db finishes loading to fix that.
|
||||
connect(CardDatabaseManager::getInstance(), &CardDatabase::cardDatabaseLoadingFinished, this,
|
||||
&CardZoneLogic::refreshCardInfos);
|
||||
}
|
||||
|
||||
void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x, const int y)
|
||||
{
|
||||
if (!card) {
|
||||
qCWarning(CardZoneLog) << "CardZoneLogic::addCard() card is null; this shouldn't normally happen";
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto *view : views) {
|
||||
if (qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->prepareAddCard(x)) {
|
||||
view->getLogic()->addCard(new CardItem(player, nullptr, card->getCardRef(), card->getId()), reorganize, x,
|
||||
y);
|
||||
}
|
||||
}
|
||||
|
||||
card->setZone(this);
|
||||
emit cardAdded(card);
|
||||
addCardImpl(card, x, y);
|
||||
|
||||
if (reorganize)
|
||||
emit reorganizeCards();
|
||||
|
||||
emit cardCountChanged();
|
||||
}
|
||||
|
||||
CardItem *CardZoneLogic::takeCard(int position, int cardId, bool toNewZone)
|
||||
{
|
||||
if (position == -1) {
|
||||
// position == -1 means either that the zone is indexed by card id
|
||||
// or that it doesn't matter which card you take.
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
if (cards[i]->getId() == cardId) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
if (position == -1)
|
||||
position = 0;
|
||||
}
|
||||
if (position >= cards.size())
|
||||
return nullptr;
|
||||
|
||||
for (auto *view : views) {
|
||||
qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->removeCard(position, toNewZone);
|
||||
}
|
||||
|
||||
CardItem *c = cards.takeAt(position);
|
||||
|
||||
c->setId(cardId);
|
||||
|
||||
emit reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
return c;
|
||||
}
|
||||
|
||||
CardItem *CardZoneLogic::getCard(int cardId)
|
||||
{
|
||||
CardItem *c = cards.findCard(cardId);
|
||||
if (!c) {
|
||||
qCWarning(CardZoneLog) << "CardZoneLogic::getCard: card id=" << cardId << "not found";
|
||||
return nullptr;
|
||||
}
|
||||
// If the card's id is -1, this zone is invisible,
|
||||
// so we need to give the card an id as it comes out.
|
||||
// It can be assumed that in an invisible zone, all cards are equal.
|
||||
if (c->getId() == -1) {
|
||||
c->setId(cardId);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void CardZoneLogic::removeCard(CardItem *card)
|
||||
{
|
||||
if (!card) {
|
||||
qCWarning(CardZoneLog) << "CardZoneLogic::removeCard: card is null, this shouldn't normally happen";
|
||||
return;
|
||||
}
|
||||
|
||||
cards.removeOne(card);
|
||||
|
||||
emit reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
player->deleteCard(card);
|
||||
}
|
||||
|
||||
void CardZoneLogic::refreshCardInfos()
|
||||
{
|
||||
for (const auto &cardItem : cards) {
|
||||
cardItem->refreshCardInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void CardZoneLogic::moveAllToZone()
|
||||
{
|
||||
QList<QVariant> data = static_cast<QAction *>(sender())->data().toList();
|
||||
if (data.length() < 2) {
|
||||
return;
|
||||
}
|
||||
QString targetZone = data[0].toString();
|
||||
int targetX = data[1].toInt();
|
||||
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(player->getPlayerInfo()->getId());
|
||||
cmd.set_target_zone(targetZone.toStdString());
|
||||
cmd.set_x(targetX);
|
||||
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(cards[i]->getId());
|
||||
|
||||
player->getPlayerActions()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void CardZoneLogic::clearContents()
|
||||
{
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
// If an incorrectly implemented server doesn't return attached cards to whom they belong before dropping a
|
||||
// player, we have to return them to avoid a crash.
|
||||
|
||||
const QList<CardItem *> &attachedCards = cards[i]->getAttachedCards();
|
||||
for (auto attachedCard : attachedCards) {
|
||||
emit attachedCard->getZone()->cardAdded(attachedCard);
|
||||
}
|
||||
|
||||
player->deleteCard(cards.at(i));
|
||||
}
|
||||
cards.clear();
|
||||
emit cardCountChanged();
|
||||
}
|
||||
|
||||
QString CardZoneLogic::getTranslatedName(bool theirOwn, GrammaticalCase gc) const
|
||||
{
|
||||
QString ownerName = player->getPlayerInfo()->getName();
|
||||
if (name == "hand")
|
||||
return (theirOwn ? tr("their hand", "nominative") : tr("%1's hand", "nominative").arg(ownerName));
|
||||
else if (name == "deck")
|
||||
switch (gc) {
|
||||
case CaseLookAtZone:
|
||||
return (theirOwn ? tr("their library", "look at zone")
|
||||
: tr("%1's library", "look at zone").arg(ownerName));
|
||||
case CaseTopCardsOfZone:
|
||||
return (theirOwn ? tr("of their library", "top cards of zone,")
|
||||
: tr("of %1's library", "top cards of zone").arg(ownerName));
|
||||
case CaseRevealZone:
|
||||
return (theirOwn ? tr("their library", "reveal zone")
|
||||
: tr("%1's library", "reveal zone").arg(ownerName));
|
||||
case CaseShuffleZone:
|
||||
return (theirOwn ? tr("their library", "shuffle") : tr("%1's library", "shuffle").arg(ownerName));
|
||||
default:
|
||||
return (theirOwn ? tr("their library", "nominative") : tr("%1's library", "nominative").arg(ownerName));
|
||||
}
|
||||
else if (name == "grave")
|
||||
return (theirOwn ? tr("their graveyard", "nominative") : tr("%1's graveyard", "nominative").arg(ownerName));
|
||||
else if (name == "rfg")
|
||||
return (theirOwn ? tr("their exile", "nominative") : tr("%1's exile", "nominative").arg(ownerName));
|
||||
else if (name == "sb")
|
||||
switch (gc) {
|
||||
case CaseLookAtZone:
|
||||
return (theirOwn ? tr("their sideboard", "look at zone")
|
||||
: tr("%1's sideboard", "look at zone").arg(ownerName));
|
||||
case CaseNominative:
|
||||
return (theirOwn ? tr("their sideboard", "nominative")
|
||||
: tr("%1's sideboard", "nominative").arg(ownerName));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else {
|
||||
return (theirOwn ? tr("their custom zone '%1'", "nominative").arg(name)
|
||||
: tr("%1's custom zone '%2'", "nominative").arg(ownerName).arg(name));
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
113
cockatrice/src/game/zones/logic/card_zone_logic.h
Normal file
113
cockatrice/src/game/zones/logic/card_zone_logic.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#ifndef COCKATRICE_CARD_ZONE_LOGIC_H
|
||||
#define COCKATRICE_CARD_ZONE_LOGIC_H
|
||||
|
||||
#include "../../../client/translation.h"
|
||||
#include "../../board/card_list.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QObject>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CardZoneLogicLog, "card_zone_logic");
|
||||
|
||||
class Player;
|
||||
class ZoneViewZone;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
class QPainter;
|
||||
class CardDragItem;
|
||||
|
||||
class CardZoneLogic : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void cardAdded(CardItem *addedCard);
|
||||
void cardCountChanged();
|
||||
void reorganizeCards();
|
||||
void updateGraphics();
|
||||
void setGraphicsVisibility(bool visible);
|
||||
void retranslateUi();
|
||||
|
||||
public:
|
||||
explicit CardZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
void addCard(CardItem *card, bool reorganize, int x, int y = -1);
|
||||
// getCard() finds a card by id.
|
||||
CardItem *getCard(int cardId);
|
||||
void removeCard(CardItem *card);
|
||||
// takeCard() finds a card by position and removes it from the zone and from all of its views.
|
||||
virtual CardItem *takeCard(int position, int cardId, bool canResize = true);
|
||||
|
||||
void rawInsertCard(CardItem *card, int index)
|
||||
{
|
||||
cards.insert(index, card);
|
||||
};
|
||||
|
||||
[[nodiscard]] const CardList &getCards() const
|
||||
{
|
||||
return cards;
|
||||
}
|
||||
|
||||
void sortCards(const QList<CardList::SortOption> &options)
|
||||
{
|
||||
cards.sortBy(options);
|
||||
}
|
||||
QString getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
QString getTranslatedName(bool theirOwn, GrammaticalCase gc) const;
|
||||
Player *getPlayer() const
|
||||
{
|
||||
return player;
|
||||
}
|
||||
bool contentsKnown() const
|
||||
{
|
||||
return cards.getContentsKnown();
|
||||
}
|
||||
QList<ZoneViewZone *> &getViews()
|
||||
{
|
||||
return views;
|
||||
}
|
||||
void setAlwaysRevealTopCard(bool _alwaysRevealTopCard)
|
||||
{
|
||||
alwaysRevealTopCard = _alwaysRevealTopCard;
|
||||
}
|
||||
bool getAlwaysRevealTopCard() const
|
||||
{
|
||||
return alwaysRevealTopCard;
|
||||
}
|
||||
bool getHasCardAttr() const
|
||||
{
|
||||
return hasCardAttr;
|
||||
}
|
||||
bool getIsShufflable() const
|
||||
{
|
||||
return isShufflable;
|
||||
}
|
||||
void clearContents();
|
||||
|
||||
public slots:
|
||||
void moveAllToZone();
|
||||
|
||||
private slots:
|
||||
void refreshCardInfos();
|
||||
|
||||
protected:
|
||||
Player *player;
|
||||
QString name;
|
||||
CardList cards;
|
||||
QList<ZoneViewZone *> views;
|
||||
bool hasCardAttr;
|
||||
bool isShufflable;
|
||||
bool alwaysRevealTopCard;
|
||||
|
||||
virtual void addCardImpl(CardItem *card, int x, int y) = 0;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_ZONE_LOGIC_H
|
||||
29
cockatrice/src/game/zones/logic/hand_zone_logic.cpp
Normal file
29
cockatrice/src/game/zones/logic/hand_zone_logic.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "hand_zone_logic.h"
|
||||
|
||||
#include "../../board/card_item.h"
|
||||
|
||||
HandZoneLogic::HandZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent)
|
||||
: CardZoneLogic(_player, _name, _hasCardAttr, _isShufflable, _contentsKnown, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void HandZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
|
||||
if (!cards.getContentsKnown()) {
|
||||
card->setId(-1);
|
||||
card->setCardRef({});
|
||||
}
|
||||
card->resetState();
|
||||
card->setVisible(true);
|
||||
}
|
||||
20
cockatrice/src/game/zones/logic/hand_zone_logic.h
Normal file
20
cockatrice/src/game/zones/logic/hand_zone_logic.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef COCKATRICE_HAND_ZONE_LOGIC_H
|
||||
#define COCKATRICE_HAND_ZONE_LOGIC_H
|
||||
#include "card_zone_logic.h"
|
||||
|
||||
class HandZoneLogic : public CardZoneLogic
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HandZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_HAND_ZONE_LOGIC_H
|
||||
33
cockatrice/src/game/zones/logic/pile_zone_logic.cpp
Normal file
33
cockatrice/src/game/zones/logic/pile_zone_logic.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include "pile_zone_logic.h"
|
||||
|
||||
#include "../../board/card_item.h"
|
||||
|
||||
PileZoneLogic::PileZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent)
|
||||
: CardZoneLogic(_player, _name, _hasCardAttr, _isShufflable, _contentsKnown, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void PileZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
connect(card, &CardItem::sigPixmapUpdated, this, &PileZoneLogic::callUpdate);
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
if (!contentsKnown()) {
|
||||
card->setCardRef({});
|
||||
card->setId(-1);
|
||||
// If we obscure a previously revealed card, its name has to be forgotten
|
||||
if (cards.size() > x + 1)
|
||||
cards.at(x + 1)->setCardRef({});
|
||||
}
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
}
|
||||
25
cockatrice/src/game/zones/logic/pile_zone_logic.h
Normal file
25
cockatrice/src/game/zones/logic/pile_zone_logic.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef COCKATRICE_PILE_ZONE_LOGIC_H
|
||||
#define COCKATRICE_PILE_ZONE_LOGIC_H
|
||||
#include "card_zone_logic.h"
|
||||
|
||||
class PileZoneLogic : public CardZoneLogic
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void callUpdate();
|
||||
|
||||
public:
|
||||
PileZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_PILE_ZONE_LOGIC_H
|
||||
29
cockatrice/src/game/zones/logic/stack_zone_logic.cpp
Normal file
29
cockatrice/src/game/zones/logic/stack_zone_logic.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "stack_zone_logic.h"
|
||||
|
||||
#include "../../board/card_item.h"
|
||||
|
||||
StackZoneLogic::StackZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent)
|
||||
: CardZoneLogic(_player, _name, _hasCardAttr, _isShufflable, _contentsKnown, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void StackZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = static_cast<int>(cards.size());
|
||||
}
|
||||
cards.insert(x, card);
|
||||
|
||||
if (!cards.getContentsKnown()) {
|
||||
card->setId(-1);
|
||||
card->setCardRef({});
|
||||
}
|
||||
card->resetState(true);
|
||||
card->setVisible(true);
|
||||
}
|
||||
20
cockatrice/src/game/zones/logic/stack_zone_logic.h
Normal file
20
cockatrice/src/game/zones/logic/stack_zone_logic.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef COCKATRICE_STACK_ZONE_LOGIC_H
|
||||
#define COCKATRICE_STACK_ZONE_LOGIC_H
|
||||
#include "card_zone_logic.h"
|
||||
|
||||
class StackZoneLogic : public CardZoneLogic
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StackZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_STACK_ZONE_LOGIC_H
|
||||
29
cockatrice/src/game/zones/logic/table_zone_logic.cpp
Normal file
29
cockatrice/src/game/zones/logic/table_zone_logic.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "table_zone_logic.h"
|
||||
|
||||
#include "../../board/card_item.h"
|
||||
|
||||
TableZoneLogic::TableZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent)
|
||||
: CardZoneLogic(_player, _name, _hasCardAttr, _isShufflable, _contentsKnown, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void TableZoneLogic::addCardImpl(CardItem *card, int _x, int _y)
|
||||
{
|
||||
cards.append(card);
|
||||
card->setGridPoint(QPoint(_x, _y));
|
||||
card->setVisible(true);
|
||||
}
|
||||
|
||||
CardItem *TableZoneLogic::takeCard(int position, int cardId, bool toNewZone)
|
||||
{
|
||||
CardItem *result = CardZoneLogic::takeCard(position, cardId);
|
||||
|
||||
if (toNewZone)
|
||||
emit contentSizeChanged();
|
||||
return result;
|
||||
}
|
||||
34
cockatrice/src/game/zones/logic/table_zone_logic.h
Normal file
34
cockatrice/src/game/zones/logic/table_zone_logic.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef COCKATRICE_TABLE_ZONE_LOGIC_H
|
||||
#define COCKATRICE_TABLE_ZONE_LOGIC_H
|
||||
#include "card_zone_logic.h"
|
||||
|
||||
class TableZoneLogic : public CardZoneLogic
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void contentSizeChanged();
|
||||
void toggleTapped();
|
||||
|
||||
public:
|
||||
TableZoneLogic(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
|
||||
/**
|
||||
* @brief Removes a card from view.
|
||||
*
|
||||
* @param position card position
|
||||
* @param cardId id of card to take
|
||||
* @param toNewZone Whether the destination of the card is not the same as the starting zone. Defaults to true
|
||||
* @return CardItem that has been removed
|
||||
*/
|
||||
CardItem *takeCard(int position, int cardId, bool toNewZone = true) override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_TABLE_ZONE_LOGIC_H
|
||||
159
cockatrice/src/game/zones/logic/view_zone_logic.cpp
Normal file
159
cockatrice/src/game/zones/logic/view_zone_logic.cpp
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#include "view_zone_logic.h"
|
||||
|
||||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../board/card_item.h"
|
||||
|
||||
ZoneViewZoneLogic::ZoneViewZoneLogic(Player *_player,
|
||||
CardZoneLogic *_origZone,
|
||||
int _numberCards,
|
||||
bool _revealZone,
|
||||
bool _writeableRevealZone,
|
||||
bool _isReversed,
|
||||
QObject *parent)
|
||||
: CardZoneLogic(_player, _origZone->getName(), false, false, true, parent), origZone(_origZone),
|
||||
numberCards(_numberCards), revealZone(_revealZone), writeableRevealZone(_writeableRevealZone),
|
||||
isReversed(_isReversed)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if inserting a card at the given position requires an actual new card to be created and added to the view.
|
||||
* Also does any cardId updates that would be required if a card is inserted in that position.
|
||||
*
|
||||
* Note that this method can end up modifying the cardIds despite returning false.
|
||||
* (for example, if the card is inserted into a hidden portion of the deck while the view is reversed)
|
||||
*
|
||||
* Make sure to call this method once before calling addCard(), so that you skip creating a new CardItem and calling
|
||||
* addCard() if it's not required.
|
||||
*
|
||||
* @param x The position to insert the card at.
|
||||
* @return Whether to proceed with calling addCard.
|
||||
*/
|
||||
bool ZoneViewZoneLogic::prepareAddCard(int x)
|
||||
{
|
||||
bool doInsert = false;
|
||||
if (!isReversed) {
|
||||
if (x <= cards.size() || cards.size() == -1) {
|
||||
doInsert = true;
|
||||
}
|
||||
} else {
|
||||
// map x (which is in origZone indexes) to this viewZone's cardList index
|
||||
int firstId = cards.isEmpty() ? origZone->getCards().size() : cards.front()->getId();
|
||||
int insertionIndex = x - firstId;
|
||||
if (insertionIndex >= 0) {
|
||||
// card was put into a portion of the deck that's in the view
|
||||
doInsert = true;
|
||||
} else {
|
||||
// card was put into a portion of the deck that's not in the view; update ids but don't insert card
|
||||
updateCardIds(ADD_CARD);
|
||||
}
|
||||
}
|
||||
|
||||
// autoclose check is done both here and in removeCard
|
||||
|
||||
if (cards.isEmpty() && !doInsert && SettingsCache::instance().getCloseEmptyCardView()) {
|
||||
emit closeView();
|
||||
}
|
||||
|
||||
return doInsert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure prepareAddCard() was called before calling addCard().
|
||||
* This method assumes we already checked that the card is being inserted into the visible portion
|
||||
*/
|
||||
void ZoneViewZoneLogic::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
if (!isReversed) {
|
||||
// if x is negative set it to add at end
|
||||
// if x is out-of-bounds then also set it to add at the end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
} else {
|
||||
// map x (which is in origZone indexes) to this viewZone's cardList index
|
||||
int firstId = cards.isEmpty() ? origZone->getCards().size() : cards.front()->getId();
|
||||
int insertionIndex = x - firstId;
|
||||
// qMin to prevent out-of-bounds error when bottoming a card that is already in the view
|
||||
cards.insert(qMin(insertionIndex, cards.size()), card);
|
||||
}
|
||||
|
||||
updateCardIds(ADD_CARD);
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewZoneLogic::updateCardIds(CardAction action)
|
||||
{
|
||||
if (origZone->contentsKnown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cards.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cardCount = cards.size();
|
||||
|
||||
auto startId = 0;
|
||||
|
||||
if (isReversed) {
|
||||
// the card has not been added to origZone's cardList at this point
|
||||
startId = origZone->getCards().size() - cardCount;
|
||||
switch (action) {
|
||||
case INITIALIZE:
|
||||
break;
|
||||
case ADD_CARD:
|
||||
startId += 1;
|
||||
break;
|
||||
case REMOVE_CARD:
|
||||
startId -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cardCount; ++i) {
|
||||
cards[i]->setId(i + startId);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneViewZoneLogic::removeCard(int position, bool toNewZone)
|
||||
{
|
||||
if (isReversed) {
|
||||
position -= cards.first()->getId();
|
||||
if (position < 0 || position >= cards.size()) {
|
||||
updateCardIds(REMOVE_CARD);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (position >= cards.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CardItem *card = cards.takeAt(position);
|
||||
card->deleteLater();
|
||||
|
||||
// The toNewZone check is to prevent the view from auto-closing if the view contains only a single card and that
|
||||
// card gets dragged within the view.
|
||||
// Another autoclose check is done in prepareAddCard so that the view autocloses if the last card was moved to an
|
||||
// unrevealed portion of the same zone.
|
||||
if (cards.isEmpty() && SettingsCache::instance().getCloseEmptyCardView() && toNewZone) {
|
||||
emit closeView();
|
||||
return;
|
||||
}
|
||||
|
||||
updateCardIds(REMOVE_CARD);
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewZoneLogic::setWriteableRevealZone(bool _writeableRevealZone)
|
||||
{
|
||||
|
||||
if (writeableRevealZone && !_writeableRevealZone) {
|
||||
emit addToViews();
|
||||
} else if (!writeableRevealZone && _writeableRevealZone) {
|
||||
emit removeFromViews();
|
||||
}
|
||||
writeableRevealZone = _writeableRevealZone;
|
||||
}
|
||||
65
cockatrice/src/game/zones/logic/view_zone_logic.h
Normal file
65
cockatrice/src/game/zones/logic/view_zone_logic.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef COCKATRICE_VIEW_ZONE_LOGIC_H
|
||||
#define COCKATRICE_VIEW_ZONE_LOGIC_H
|
||||
#include "card_zone_logic.h"
|
||||
|
||||
class ZoneViewZoneLogic : public CardZoneLogic
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void addToViews();
|
||||
void removeFromViews();
|
||||
void closeView();
|
||||
|
||||
private:
|
||||
CardZoneLogic *origZone;
|
||||
int numberCards;
|
||||
bool revealZone, writeableRevealZone;
|
||||
bool isReversed;
|
||||
|
||||
public:
|
||||
enum CardAction
|
||||
{
|
||||
INITIALIZE,
|
||||
ADD_CARD,
|
||||
REMOVE_CARD
|
||||
};
|
||||
|
||||
ZoneViewZoneLogic(Player *_player,
|
||||
CardZoneLogic *_origZone,
|
||||
int _numberCards,
|
||||
bool _revealZone,
|
||||
bool _writeableRevealZone,
|
||||
bool _isReversed,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
bool prepareAddCard(int x);
|
||||
void removeCard(int position, bool toNewZone);
|
||||
void updateCardIds(CardAction action);
|
||||
int getNumberCards() const
|
||||
{
|
||||
return numberCards;
|
||||
}
|
||||
bool getRevealZone() const
|
||||
{
|
||||
return revealZone;
|
||||
}
|
||||
bool getWriteableRevealZone() const
|
||||
{
|
||||
return writeableRevealZone;
|
||||
}
|
||||
void setWriteableRevealZone(bool _writeableRevealZone);
|
||||
bool getIsReversed() const
|
||||
{
|
||||
return isReversed;
|
||||
}
|
||||
|
||||
CardZoneLogic *getOriginalZone() const
|
||||
{
|
||||
return origZone;
|
||||
}
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_VIEW_ZONE_LOGIC_H
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../board/card_drag_item.h"
|
||||
#include "../board/card_item.h"
|
||||
#include "../player/player.h"
|
||||
#include "logic/pile_zone_logic.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
#include "view_zone.h"
|
||||
|
||||
|
|
@ -10,8 +11,7 @@
|
|||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
PileZone::PileZone(Player *_p, const QString &_name, bool _isShufflable, bool _contentsKnown, QGraphicsItem *parent)
|
||||
: CardZone(_p, _name, false, _isShufflable, _contentsKnown, parent)
|
||||
PileZone::PileZone(PileZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_logic, parent)
|
||||
{
|
||||
setCacheMode(DeviceCoordinateCache); // Do not move this line to the parent constructor!
|
||||
setAcceptHoverEvents(true);
|
||||
|
|
@ -47,52 +47,30 @@ void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio
|
|||
{
|
||||
painter->drawPath(shape());
|
||||
|
||||
if (!cards.isEmpty())
|
||||
cards.at(0)->paintPicture(painter, cards.at(0)->getTranslatedSize(painter), 90);
|
||||
if (!getLogic()->getCards().isEmpty())
|
||||
getLogic()->getCards().at(0)->paintPicture(painter, getLogic()->getCards().at(0)->getTranslatedSize(painter),
|
||||
90);
|
||||
|
||||
painter->translate((float)CARD_WIDTH / 2, (float)CARD_HEIGHT / 2);
|
||||
painter->rotate(-90);
|
||||
painter->translate((float)-CARD_WIDTH / 2, (float)-CARD_HEIGHT / 2);
|
||||
paintNumberEllipse(cards.size(), 28, Qt::white, -1, -1, painter);
|
||||
paintNumberEllipse(getLogic()->getCards().size(), 28, Qt::white, -1, -1, painter);
|
||||
}
|
||||
|
||||
void PileZone::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
connect(card, &CardItem::sigPixmapUpdated, this, &PileZone::callUpdate);
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
if (!contentsKnown()) {
|
||||
card->setCardRef({});
|
||||
card->setId(-1);
|
||||
// If we obscure a previously revealed card, its name has to be forgotten
|
||||
if (cards.size() > x + 1)
|
||||
cards.at(x + 1)->setCardRef({});
|
||||
}
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
}
|
||||
|
||||
void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||
CardZone *startZone,
|
||||
const QPoint & /*dropPoint*/)
|
||||
void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &)
|
||||
{
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getId());
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_start_zone(startZone->getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(getLogic()->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_target_zone(getLogic()->getName().toStdString());
|
||||
cmd.set_x(0);
|
||||
cmd.set_y(0);
|
||||
|
||||
for (int i = 0; i < dragItems.size(); ++i)
|
||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId());
|
||||
|
||||
player->sendGameCommand(cmd);
|
||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void PileZone::reorganizeCards()
|
||||
|
|
@ -119,13 +97,14 @@ void PileZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
if (cards.isEmpty())
|
||||
if (getLogic()->getCards().isEmpty())
|
||||
return;
|
||||
|
||||
bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
||||
bool bottomCard = event->modifiers().testFlag(Qt::ControlModifier);
|
||||
CardItem *card = bottomCard ? cards.last() : cards.first();
|
||||
const int cardid = contentsKnown() ? card->getId() : (bottomCard ? cards.size() - 1 : 0);
|
||||
CardItem *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first();
|
||||
const int cardid =
|
||||
getLogic()->contentsKnown() ? card->getId() : (bottomCard ? getLogic()->getCards().size() - 1 : 0);
|
||||
CardDragItem *drag = card->createDragItem(cardid, event->pos(), event->scenePos(), faceDown);
|
||||
drag->grabMouse();
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
|
|
@ -138,7 +117,7 @@ void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
|||
|
||||
void PileZone::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
if (!cards.isEmpty())
|
||||
cards[0]->processHoverEvent();
|
||||
if (!getLogic()->getCards().isEmpty())
|
||||
getLogic()->getCards()[0]->processHoverEvent();
|
||||
QGraphicsItem::hoverEnterEvent(event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define PILEZONE_H
|
||||
|
||||
#include "card_zone.h"
|
||||
#include "logic/pile_zone_logic.h"
|
||||
|
||||
/**
|
||||
* A CardZone where the cards are in a single pile instead of being laid out.
|
||||
|
|
@ -17,23 +18,19 @@ private slots:
|
|||
}
|
||||
|
||||
public:
|
||||
PileZone(Player *_p,
|
||||
const QString &_name,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
QRectF boundingRect() const override;
|
||||
QPainterPath shape() const override;
|
||||
PileZone(PileZoneLogic *_logic, QGraphicsItem *parent);
|
||||
[[nodiscard]] QRectF boundingRect() const override;
|
||||
[[nodiscard]] QPainterPath shape() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void reorganizeCards() override;
|
||||
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint) override;
|
||||
void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,13 +32,7 @@ qreal divideCardSpaceInZone(qreal index, int cardCount, qreal totalHeight, qreal
|
|||
return y;
|
||||
}
|
||||
|
||||
SelectZone::SelectZone(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QGraphicsItem *parent)
|
||||
: CardZone(_player, _name, _hasCardAttr, _isShufflable, _contentsKnown, parent)
|
||||
SelectZone::SelectZone(CardZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_logic, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -57,8 +51,8 @@ void SelectZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
pos.setY(br.height());
|
||||
|
||||
QRectF selectionRect = QRectF(selectionOrigin, pos).normalized();
|
||||
for (auto card : cards) {
|
||||
if (card->getAttachedTo() && card->getAttachedTo()->getZone() != this) {
|
||||
for (auto card : getLogic()->getCards()) {
|
||||
if (card->getAttachedTo() && card->getAttachedTo()->getZone() != getLogic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,7 @@ protected:
|
|||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
public:
|
||||
SelectZone(Player *_player,
|
||||
const QString &_name,
|
||||
bool _hasCardAttr,
|
||||
bool _isShufflable,
|
||||
bool _contentsKnown,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
SelectZone(CardZoneLogic *logic, QGraphicsItem *parent = nullptr);
|
||||
};
|
||||
|
||||
qreal divideCardSpaceInZone(qreal index, int cardCount, qreal totalHeight, qreal cardHeight, bool reverse = false);
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@
|
|||
#include "../board/card_drag_item.h"
|
||||
#include "../board/card_item.h"
|
||||
#include "../player/player.h"
|
||||
#include "logic/stack_zone_logic.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QSet>
|
||||
|
||||
StackZone::StackZone(Player *_p, int _zoneHeight, QGraphicsItem *parent)
|
||||
: SelectZone(_p, "stack", false, false, true, parent), zoneHeight(_zoneHeight)
|
||||
StackZone::StackZone(StackZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent)
|
||||
: SelectZone(_logic, parent), zoneHeight(_zoneHeight)
|
||||
{
|
||||
connect(themeManager, &ThemeManager::themeChanged, this, &StackZone::updateBg);
|
||||
updateBg();
|
||||
|
|
@ -24,24 +25,6 @@ void StackZone::updateBg()
|
|||
update();
|
||||
}
|
||||
|
||||
void StackZone::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = static_cast<int>(cards.size());
|
||||
}
|
||||
cards.insert(x, card);
|
||||
|
||||
if (!cards.getContentsKnown()) {
|
||||
card->setId(-1);
|
||||
card->setCardRef({});
|
||||
}
|
||||
card->setParentItem(this);
|
||||
card->resetState(true);
|
||||
card->setVisible(true);
|
||||
card->update();
|
||||
}
|
||||
|
||||
QRectF StackZone::boundingRect() const
|
||||
{
|
||||
return {0, 0, 100, zoneHeight};
|
||||
|
|
@ -49,27 +32,29 @@ QRectF StackZone::boundingRect() const
|
|||
|
||||
void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Stack, player->getZoneId());
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Stack, getLogic()->getPlayer()->getZoneId());
|
||||
painter->fillRect(boundingRect(), brush);
|
||||
}
|
||||
|
||||
void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint)
|
||||
void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||
CardZoneLogic *startZone,
|
||||
const QPoint &dropPoint)
|
||||
{
|
||||
if (startZone == nullptr || startZone->getPlayer() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getId());
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_start_zone(startZone->getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(getLogic()->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_target_zone(getLogic()->getName().toStdString());
|
||||
|
||||
int index = 0;
|
||||
|
||||
if (!cards.isEmpty()) {
|
||||
const auto cardCount = static_cast<int>(cards.size());
|
||||
const auto &card = cards.at(0);
|
||||
if (!getLogic()->getCards().isEmpty()) {
|
||||
const auto cardCount = static_cast<int>(getLogic()->getCards().size());
|
||||
const auto &card = getLogic()->getCards().at(0);
|
||||
|
||||
index = qRound(divideCardSpaceInZone(dropPoint.y(), cardCount, boundingRect().height(),
|
||||
card->boundingRect().height(), true));
|
||||
|
|
@ -78,9 +63,9 @@ void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone
|
|||
// currently, so clamp it to avoid crashes.
|
||||
index = qBound(0, index, cardCount - 1);
|
||||
|
||||
if (startZone == this) {
|
||||
if (startZone == getLogic()) {
|
||||
const auto &dragItem = dragItems.at(0);
|
||||
const auto &card = cards.at(index);
|
||||
const auto &card = getLogic()->getCards().at(index);
|
||||
|
||||
if (card->getId() == dragItem->getId()) {
|
||||
return;
|
||||
|
|
@ -97,24 +82,24 @@ void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone
|
|||
}
|
||||
}
|
||||
|
||||
player->sendGameCommand(cmd);
|
||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void StackZone::reorganizeCards()
|
||||
{
|
||||
if (!cards.isEmpty()) {
|
||||
const auto cardCount = static_cast<int>(cards.size());
|
||||
if (!getLogic()->getCards().isEmpty()) {
|
||||
const auto cardCount = static_cast<int>(getLogic()->getCards().size());
|
||||
qreal totalWidth = boundingRect().width();
|
||||
qreal cardWidth = cards.at(0)->boundingRect().width();
|
||||
qreal cardWidth = getLogic()->getCards().at(0)->boundingRect().width();
|
||||
qreal xspace = 5;
|
||||
qreal x1 = xspace;
|
||||
qreal x2 = totalWidth - xspace - cardWidth;
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *card = cards.at(i);
|
||||
CardItem *card = getLogic()->getCards().at(i);
|
||||
qreal x = (i % 2) ? x2 : x1;
|
||||
qreal y =
|
||||
divideCardSpaceInZone(i, cardCount, boundingRect().height(), cards.at(0)->boundingRect().height());
|
||||
qreal y = divideCardSpaceInZone(i, cardCount, boundingRect().height(),
|
||||
getLogic()->getCards().at(0)->boundingRect().height());
|
||||
card->setPos(x, y);
|
||||
card->setRealZValue(i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef STACKZONE_H
|
||||
#define STACKZONE_H
|
||||
|
||||
#include "logic/stack_zone_logic.h"
|
||||
#include "select_zone.h"
|
||||
|
||||
class StackZone : public SelectZone
|
||||
|
|
@ -12,14 +13,12 @@ private slots:
|
|||
void updateBg();
|
||||
|
||||
public:
|
||||
StackZone(Player *_p, int _zoneHeight, QGraphicsItem *parent = nullptr);
|
||||
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint) override;
|
||||
StackZone(StackZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent);
|
||||
void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void reorganizeCards() override;
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "../board/card_item.h"
|
||||
#include "../cards/card_info.h"
|
||||
#include "../player/player.h"
|
||||
#include "logic/table_zone_logic.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
#include "pb/command_set_card_attr.pb.h"
|
||||
|
||||
|
|
@ -19,9 +20,10 @@ const QColor TableZone::FADE_MASK = QColor(0, 0, 0, 80);
|
|||
const QColor TableZone::GRADIENT_COLOR = QColor(255, 255, 255, 150);
|
||||
const QColor TableZone::GRADIENT_COLORLESS = QColor(255, 255, 255, 0);
|
||||
|
||||
TableZone::TableZone(Player *_p, const QString &name, QGraphicsItem *parent)
|
||||
: SelectZone(_p, name, true, false, true, parent), active(false)
|
||||
TableZone::TableZone(TableZoneLogic *_logic, QGraphicsItem *parent) : SelectZone(_logic, parent), active(false)
|
||||
{
|
||||
connect(_logic, &TableZoneLogic::contentSizeChanged, this, &TableZone::resizeToContents);
|
||||
connect(_logic, &TableZoneLogic::toggleTapped, this, &TableZone::toggleTapped);
|
||||
connect(themeManager, &ThemeManager::themeChanged, this, &TableZone::updateBg);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::invertVerticalCoordinateChanged, this,
|
||||
&TableZone::reorganizeCards);
|
||||
|
|
@ -48,13 +50,15 @@ QRectF TableZone::boundingRect() const
|
|||
|
||||
bool TableZone::isInverted() const
|
||||
{
|
||||
return ((player->getMirrored() && !SettingsCache::instance().getInvertVerticalCoordinate()) ||
|
||||
(!player->getMirrored() && SettingsCache::instance().getInvertVerticalCoordinate()));
|
||||
return ((getLogic()->getPlayer()->getGraphicsItem()->getMirrored() &&
|
||||
!SettingsCache::instance().getInvertVerticalCoordinate()) ||
|
||||
(!getLogic()->getPlayer()->getGraphicsItem()->getMirrored() &&
|
||||
SettingsCache::instance().getInvertVerticalCoordinate()));
|
||||
}
|
||||
|
||||
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Table, player->getZoneId());
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Table, getLogic()->getPlayer()->getZoneId());
|
||||
painter->fillRect(boundingRect(), brush);
|
||||
|
||||
if (active) {
|
||||
|
|
@ -108,30 +112,22 @@ void TableZone::paintLandDivider(QPainter *painter)
|
|||
painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
|
||||
}
|
||||
|
||||
void TableZone::addCardImpl(CardItem *card, int _x, int _y)
|
||||
{
|
||||
cards.append(card);
|
||||
card->setGridPoint(QPoint(_x, _y));
|
||||
|
||||
card->setParentItem(this);
|
||||
card->setVisible(true);
|
||||
card->update();
|
||||
}
|
||||
|
||||
void TableZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint)
|
||||
void TableZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||
CardZoneLogic *startZone,
|
||||
const QPoint &dropPoint)
|
||||
{
|
||||
handleDropEventByGrid(dragItems, startZone, mapToGrid(dropPoint));
|
||||
}
|
||||
|
||||
void TableZone::handleDropEventByGrid(const QList<CardDragItem *> &dragItems,
|
||||
CardZone *startZone,
|
||||
CardZoneLogic *startZone,
|
||||
const QPoint &gridPoint)
|
||||
{
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getId());
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_start_zone(startZone->getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(getLogic()->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_target_zone(getLogic()->getName().toStdString());
|
||||
cmd.set_x(gridPoint.x());
|
||||
cmd.set_y(gridPoint.y());
|
||||
|
||||
|
|
@ -139,7 +135,7 @@ void TableZone::handleDropEventByGrid(const QList<CardDragItem *> &dragItems,
|
|||
CardToMove *ctm = cmd.mutable_cards_to_move()->add_card();
|
||||
ctm->set_card_id(item->getId());
|
||||
ctm->set_face_down(item->getFaceDown());
|
||||
if (startZone->getName() != name && !item->getFaceDown()) {
|
||||
if (startZone->getName() != getLogic()->getName() && !item->getFaceDown()) {
|
||||
const auto &card = item->getItem()->getCard();
|
||||
if (card) {
|
||||
ctm->set_pt(card.getInfo().getPowTough().toStdString());
|
||||
|
|
@ -147,7 +143,7 @@ void TableZone::handleDropEventByGrid(const QList<CardDragItem *> &dragItems,
|
|||
}
|
||||
}
|
||||
|
||||
startZone->getPlayer()->sendGameCommand(cmd);
|
||||
startZone->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void TableZone::reorganizeCards()
|
||||
|
|
@ -155,8 +151,8 @@ void TableZone::reorganizeCards()
|
|||
// Calculate card stack widths so mapping functions work properly
|
||||
computeCardStackWidths();
|
||||
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
QPoint gridPoint = cards[i]->getGridPos();
|
||||
for (int i = 0; i < getLogic()->getCards().size(); ++i) {
|
||||
QPoint gridPoint = getLogic()->getCards()[i]->getGridPos();
|
||||
if (gridPoint.x() == -1)
|
||||
continue;
|
||||
|
||||
|
|
@ -164,16 +160,16 @@ void TableZone::reorganizeCards()
|
|||
qreal x = mapPoint.x();
|
||||
qreal y = mapPoint.y();
|
||||
|
||||
int numberAttachedCards = cards[i]->getAttachedCards().size();
|
||||
int numberAttachedCards = getLogic()->getCards()[i]->getAttachedCards().size();
|
||||
qreal actualX = x + numberAttachedCards * STACKED_CARD_OFFSET_X;
|
||||
qreal actualY = y;
|
||||
if (numberAttachedCards)
|
||||
actualY += 15;
|
||||
|
||||
cards[i]->setPos(actualX, actualY);
|
||||
cards[i]->setRealZValue((actualY + CARD_HEIGHT) * 100000 + (actualX + 1) * 100);
|
||||
getLogic()->getCards()[i]->setPos(actualX, actualY);
|
||||
getLogic()->getCards()[i]->setRealZValue((actualY + CARD_HEIGHT) * 100000 + (actualX + 1) * 100);
|
||||
|
||||
QListIterator<CardItem *> attachedCardIterator(cards[i]->getAttachedCards());
|
||||
QListIterator<CardItem *> attachedCardIterator(getLogic()->getCards()[i]->getAttachedCards());
|
||||
int j = 0;
|
||||
while (attachedCardIterator.hasNext()) {
|
||||
++j;
|
||||
|
|
@ -211,22 +207,15 @@ void TableZone::toggleTapped()
|
|||
CardItem *temp = qgraphicsitem_cast<CardItem *>(selectedItem);
|
||||
if (temp->getTapped() != tapAll) {
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(name.toStdString());
|
||||
cmd->set_zone(getLogic()->getName().toStdString());
|
||||
cmd->set_card_id(temp->getId());
|
||||
cmd->set_attribute(AttrTapped);
|
||||
cmd->set_attr_value(tapAll ? "1" : "0");
|
||||
cmdList.append(cmd);
|
||||
}
|
||||
}
|
||||
player->sendGameCommand(player->prepareGameCommand(cmdList));
|
||||
}
|
||||
|
||||
CardItem *TableZone::takeCard(int position, int cardId, bool toNewZone)
|
||||
{
|
||||
CardItem *result = CardZone::takeCard(position, cardId);
|
||||
if (toNewZone)
|
||||
resizeToContents();
|
||||
return result;
|
||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(
|
||||
getLogic()->getPlayer()->getPlayerActions()->prepareGameCommand(cmdList));
|
||||
}
|
||||
|
||||
void TableZone::resizeToContents()
|
||||
|
|
@ -234,9 +223,9 @@ void TableZone::resizeToContents()
|
|||
int xMax = 0;
|
||||
|
||||
// Find rightmost card position, which includes the left margin amount.
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
if (cards[i]->pos().x() > xMax)
|
||||
xMax = (int)cards[i]->pos().x();
|
||||
for (int i = 0; i < getLogic()->getCards().size(); ++i)
|
||||
if (getLogic()->getCards()[i]->pos().x() > xMax)
|
||||
xMax = (int)getLogic()->getCards()[i]->pos().x();
|
||||
|
||||
// Minimum width is the rightmost card position plus enough room for
|
||||
// another card with padding, then margin.
|
||||
|
|
@ -254,9 +243,9 @@ void TableZone::resizeToContents()
|
|||
|
||||
CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const
|
||||
{
|
||||
for (int i = 0; i < cards.size(); i++)
|
||||
if (cards.at(i)->getGridPoint() == gridPoint)
|
||||
return cards.at(i);
|
||||
for (int i = 0; i < getLogic()->getCards().size(); i++)
|
||||
if (getLogic()->getCards().at(i)->getGridPoint() == gridPoint)
|
||||
return getLogic()->getCards().at(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -271,8 +260,8 @@ void TableZone::computeCardStackWidths()
|
|||
// Each card stack is three grid points worth of card locations.
|
||||
// First pass: compute the number of cards at each card stack.
|
||||
QMap<int, int> cardStackCount;
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
const QPoint &gridPoint = cards[i]->getGridPos();
|
||||
for (int i = 0; i < getLogic()->getCards().size(); ++i) {
|
||||
const QPoint &gridPoint = getLogic()->getCards()[i]->getGridPos();
|
||||
if (gridPoint.x() == -1)
|
||||
continue;
|
||||
|
||||
|
|
@ -282,15 +271,16 @@ void TableZone::computeCardStackWidths()
|
|||
|
||||
// Second pass: compute the width at each card stack.
|
||||
cardStackWidth.clear();
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
const QPoint &gridPoint = cards[i]->getGridPos();
|
||||
for (int i = 0; i < getLogic()->getCards().size(); ++i) {
|
||||
const QPoint &gridPoint = getLogic()->getCards()[i]->getGridPos();
|
||||
if (gridPoint.x() == -1)
|
||||
continue;
|
||||
|
||||
const int key = getCardStackMapKey(gridPoint.x() / 3, gridPoint.y());
|
||||
const int stackCount = cardStackCount.value(key, 0);
|
||||
if (stackCount == 1)
|
||||
cardStackWidth.insert(key, CARD_WIDTH + cards[i]->getAttachedCards().size() * STACKED_CARD_OFFSET_X);
|
||||
cardStackWidth.insert(key, CARD_WIDTH + getLogic()->getCards()[i]->getAttachedCards().size() *
|
||||
STACKED_CARD_OFFSET_X);
|
||||
else
|
||||
cardStackWidth.insert(key, CARD_WIDTH + (stackCount - 1) * STACKED_CARD_OFFSET_X);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define TABLEZONE_H
|
||||
|
||||
#include "../board/abstract_card_item.h"
|
||||
#include "logic/table_zone_logic.h"
|
||||
#include "select_zone.h"
|
||||
|
||||
/*
|
||||
|
|
@ -75,7 +76,7 @@ private:
|
|||
/*
|
||||
If this TableZone is currently active
|
||||
*/
|
||||
bool active;
|
||||
bool active = false;
|
||||
|
||||
bool isInverted() const;
|
||||
|
||||
|
|
@ -98,7 +99,7 @@ public:
|
|||
@param _p the Player
|
||||
@param parent defaults to null
|
||||
*/
|
||||
explicit TableZone(Player *_p, const QString &name, QGraphicsItem *parent = nullptr);
|
||||
explicit TableZone(TableZoneLogic *_logic, QGraphicsItem *parent = nullptr);
|
||||
|
||||
/**
|
||||
@return a QRectF of the TableZone bounding box.
|
||||
|
|
@ -121,12 +122,14 @@ public:
|
|||
/**
|
||||
See HandleDropEventByGrid
|
||||
*/
|
||||
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint) override;
|
||||
void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;
|
||||
|
||||
/**
|
||||
Handles the placement of cards
|
||||
*/
|
||||
void handleDropEventByGrid(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &gridPoint);
|
||||
void
|
||||
handleDropEventByGrid(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &gridPoint);
|
||||
|
||||
/**
|
||||
@return CardItem from grid location
|
||||
|
|
@ -142,16 +145,6 @@ public:
|
|||
|
||||
static int clampValidTableRow(const int row);
|
||||
|
||||
/**
|
||||
Removes a card from view.
|
||||
|
||||
@param position card position
|
||||
@param cardId id of card to take
|
||||
@param toNewZone Whether the destination of the card is not the same as the starting zone. Defaults to true
|
||||
@return CardItem that has been removed
|
||||
*/
|
||||
CardItem *takeCard(int position, int cardId, bool toNewZone = true) override;
|
||||
|
||||
/**
|
||||
Resizes the TableZone in case CardItems are within or
|
||||
outside of the TableZone constraints.
|
||||
|
|
@ -177,9 +170,6 @@ public:
|
|||
update();
|
||||
}
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
|
||||
private:
|
||||
void paintZoneOutline(QPainter *painter);
|
||||
void paintLandDivider(QPainter *painter);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "../board/card_item.h"
|
||||
#include "../cards/card_info.h"
|
||||
#include "../player/player.h"
|
||||
#include "logic/view_zone_logic.h"
|
||||
#include "pb/command_dump_zone.pb.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
#include "pb/response_dump_zone.pb.h"
|
||||
|
|
@ -23,21 +24,24 @@
|
|||
* @param _writeableRevealZone whether the player can interact with the revealed cards.
|
||||
* @param parent the parent QGraphicsWidget containing the reveal zone
|
||||
*/
|
||||
ZoneViewZone::ZoneViewZone(Player *_p,
|
||||
CardZone *_origZone,
|
||||
int _numberCards,
|
||||
bool _revealZone,
|
||||
bool _writeableRevealZone,
|
||||
QGraphicsItem *parent,
|
||||
bool _isReversed)
|
||||
: SelectZone(_p, _origZone->getName(), false, false, true, parent), bRect(QRectF()), minRows(0),
|
||||
numberCards(_numberCards), origZone(_origZone), revealZone(_revealZone),
|
||||
writeableRevealZone(_writeableRevealZone), groupBy(CardList::NoSort), sortBy(CardList::NoSort),
|
||||
isReversed(_isReversed)
|
||||
ZoneViewZone::ZoneViewZone(ZoneViewZoneLogic *_logic, QGraphicsItem *parent)
|
||||
: SelectZone(_logic, parent), bRect(QRectF()), minRows(0), groupBy(CardList::NoSort), sortBy(CardList::NoSort)
|
||||
{
|
||||
if (!(revealZone && !writeableRevealZone)) {
|
||||
origZone->getViews().append(this);
|
||||
if (!(qobject_cast<ZoneViewZoneLogic *>(getLogic())->getRevealZone() &&
|
||||
!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getWriteableRevealZone())) {
|
||||
qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getViews().append(this);
|
||||
}
|
||||
connect(_logic, &ZoneViewZoneLogic::closeView, this, &ZoneViewZone::close);
|
||||
}
|
||||
|
||||
void ZoneViewZone::addToViews()
|
||||
{
|
||||
qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getViews().append(this);
|
||||
}
|
||||
|
||||
void ZoneViewZone::removeFromViews()
|
||||
{
|
||||
qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getViews().removeOne(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,8 +51,9 @@ ZoneViewZone::ZoneViewZone(Player *_p,
|
|||
void ZoneViewZone::close()
|
||||
{
|
||||
emit closed();
|
||||
if (!(revealZone && !writeableRevealZone)) {
|
||||
origZone->getViews().removeOne(this);
|
||||
if (!(qobject_cast<ZoneViewZoneLogic *>(getLogic())->getRevealZone() &&
|
||||
!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getWriteableRevealZone())) {
|
||||
qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getViews().removeOne(this);
|
||||
}
|
||||
deleteLater();
|
||||
}
|
||||
|
|
@ -67,29 +72,31 @@ void ZoneViewZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
|
|||
|
||||
void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardList)
|
||||
{
|
||||
int numberCards = qobject_cast<ZoneViewZoneLogic *>(getLogic())->getNumberCards();
|
||||
if (!cardList.isEmpty()) {
|
||||
for (int i = 0; i < cardList.size(); ++i) {
|
||||
auto card = cardList[i];
|
||||
CardRef cardRef = {QString::fromStdString(card->name()), QString::fromStdString(card->provider_id())};
|
||||
addCard(new CardItem(player, this, cardRef, card->id()), false, i);
|
||||
getLogic()->addCard(new CardItem(getLogic()->getPlayer(), this, cardRef, card->id()), false, i);
|
||||
}
|
||||
reorganizeCards();
|
||||
} else if (!origZone->contentsKnown()) {
|
||||
} else if (!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->contentsKnown()) {
|
||||
Command_DumpZone cmd;
|
||||
cmd.set_player_id(player->getId());
|
||||
cmd.set_zone_name(name.toStdString());
|
||||
cmd.set_player_id(getLogic()->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_zone_name(getLogic()->getName().toStdString());
|
||||
cmd.set_number_cards(numberCards);
|
||||
cmd.set_is_reversed(isReversed);
|
||||
cmd.set_is_reversed(qobject_cast<ZoneViewZoneLogic *>(getLogic())->getIsReversed());
|
||||
|
||||
PendingCommand *pend = player->prepareGameCommand(cmd);
|
||||
PendingCommand *pend = getLogic()->getPlayer()->getPlayerActions()->prepareGameCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &ZoneViewZone::zoneDumpReceived);
|
||||
player->sendGameCommand(pend);
|
||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(pend);
|
||||
} else {
|
||||
const CardList &c = origZone->getCards();
|
||||
const CardList &c = qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->getCards();
|
||||
int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size());
|
||||
for (int i = 0; i < number; i++) {
|
||||
CardItem *card = c.at(i);
|
||||
addCard(new CardItem(player, this, card->getCardRef(), card->getId()), false, i);
|
||||
getLogic()->addCard(new CardItem(getLogic()->getPlayer(), this, card->getCardRef(), card->getId()), false,
|
||||
i);
|
||||
}
|
||||
reorganizeCards();
|
||||
}
|
||||
|
|
@ -103,55 +110,21 @@ void ZoneViewZone::zoneDumpReceived(const Response &r)
|
|||
const ServerInfo_Card &cardInfo = resp.zone_info().card_list(i);
|
||||
auto cardName = QString::fromStdString(cardInfo.name());
|
||||
auto cardProviderId = QString::fromStdString(cardInfo.provider_id());
|
||||
auto *card = new CardItem(player, this, {cardName, cardProviderId}, cardInfo.id(), this);
|
||||
cards.insert(i, card);
|
||||
auto card = new CardItem(getLogic()->getPlayer(), this, {cardName, cardProviderId}, cardInfo.id(), getLogic());
|
||||
getLogic()->rawInsertCard(card, i);
|
||||
}
|
||||
|
||||
updateCardIds(INITIALIZE);
|
||||
qobject_cast<ZoneViewZoneLogic *>(getLogic())->updateCardIds(ZoneViewZoneLogic::INITIALIZE);
|
||||
reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
}
|
||||
|
||||
void ZoneViewZone::updateCardIds(CardAction action)
|
||||
{
|
||||
if (origZone->contentsKnown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cards.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cardCount = cards.size();
|
||||
|
||||
auto startId = 0;
|
||||
|
||||
if (isReversed) {
|
||||
// the card has not been added to origZone's cardList at this point
|
||||
startId = origZone->getCards().size() - cardCount;
|
||||
switch (action) {
|
||||
case INITIALIZE:
|
||||
break;
|
||||
case ADD_CARD:
|
||||
startId += 1;
|
||||
break;
|
||||
case REMOVE_CARD:
|
||||
startId -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cardCount; ++i) {
|
||||
cards[i]->setId(i + startId);
|
||||
}
|
||||
emit getLogic()->cardCountChanged();
|
||||
}
|
||||
|
||||
// Because of boundingRect(), this function must not be called before the zone was added to a scene.
|
||||
void ZoneViewZone::reorganizeCards()
|
||||
{
|
||||
// filter cards
|
||||
CardList cardsToDisplay = CardList(cards.getContentsKnown());
|
||||
for (auto card : cards) {
|
||||
CardList cardsToDisplay = CardList(getLogic()->getCards().getContentsKnown());
|
||||
for (auto card : getLogic()->getCards()) {
|
||||
if (filterString.check(card->getCard().getCardPtr())) {
|
||||
card->show();
|
||||
cardsToDisplay.append(card);
|
||||
|
|
@ -297,122 +270,23 @@ void ZoneViewZone::setPileView(int _pileView)
|
|||
reorganizeCards();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if inserting a card at the given position requires an actual new card to be created and added to the view.
|
||||
* Also does any cardId updates that would be required if a card is inserted in that position.
|
||||
*
|
||||
* Note that this method can end up modifying the cardIds despite returning false.
|
||||
* (for example, if the card is inserted into a hidden portion of the deck while the view is reversed)
|
||||
*
|
||||
* Make sure to call this method once before calling addCard(), so that you skip creating a new CardItem and calling
|
||||
* addCard() if it's not required.
|
||||
*
|
||||
* @param x The position to insert the card at.
|
||||
* @return Whether to proceed with calling addCard.
|
||||
*/
|
||||
bool ZoneViewZone::prepareAddCard(int x)
|
||||
{
|
||||
bool doInsert = false;
|
||||
if (!isReversed) {
|
||||
if (x <= cards.size() || cards.size() == -1) {
|
||||
doInsert = true;
|
||||
}
|
||||
} else {
|
||||
// map x (which is in origZone indexes) to this viewZone's cardList index
|
||||
int firstId = cards.isEmpty() ? origZone->getCards().size() : cards.front()->getId();
|
||||
int insertionIndex = x - firstId;
|
||||
if (insertionIndex >= 0) {
|
||||
// card was put into a portion of the deck that's in the view
|
||||
doInsert = true;
|
||||
} else {
|
||||
// card was put into a portion of the deck that's not in the view; update ids but don't insert card
|
||||
updateCardIds(ADD_CARD);
|
||||
}
|
||||
}
|
||||
|
||||
// autoclose check is done both here and in removeCard
|
||||
if (cards.isEmpty() && !doInsert && SettingsCache::instance().getCloseEmptyCardView()) {
|
||||
close();
|
||||
}
|
||||
|
||||
return doInsert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure prepareAddCard() was called before calling addCard().
|
||||
* This method assumes we already checked that the card is being inserted into the visible portion
|
||||
*/
|
||||
void ZoneViewZone::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
if (!isReversed) {
|
||||
// if x is negative set it to add at end
|
||||
// if x is out-of-bounds then also set it to add at the end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
} else {
|
||||
// map x (which is in origZone indexes) to this viewZone's cardList index
|
||||
int firstId = cards.isEmpty() ? origZone->getCards().size() : cards.front()->getId();
|
||||
int insertionIndex = x - firstId;
|
||||
// qMin to prevent out-of-bounds error when bottoming a card that is already in the view
|
||||
cards.insert(qMin(insertionIndex, cards.size()), card);
|
||||
}
|
||||
|
||||
card->setParentItem(this);
|
||||
card->update();
|
||||
|
||||
updateCardIds(ADD_CARD);
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||
CardZone *startZone,
|
||||
CardZoneLogic *startZone,
|
||||
const QPoint & /*dropPoint*/)
|
||||
{
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getId());
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_start_zone(startZone->getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(getName().toStdString());
|
||||
cmd.set_target_player_id(getLogic()->getPlayer()->getPlayerInfo()->getId());
|
||||
cmd.set_target_zone(getLogic()->getName().toStdString());
|
||||
cmd.set_x(0);
|
||||
cmd.set_y(0);
|
||||
cmd.set_is_reversed(isReversed);
|
||||
cmd.set_is_reversed(qobject_cast<ZoneViewZoneLogic *>(getLogic())->getIsReversed());
|
||||
|
||||
for (int i = 0; i < dragItems.size(); ++i)
|
||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId());
|
||||
|
||||
player->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void ZoneViewZone::removeCard(int position, bool toNewZone)
|
||||
{
|
||||
if (isReversed) {
|
||||
position -= cards.first()->getId();
|
||||
if (position < 0 || position >= cards.size()) {
|
||||
updateCardIds(REMOVE_CARD);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (position >= cards.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CardItem *card = cards.takeAt(position);
|
||||
card->deleteLater();
|
||||
|
||||
// The toNewZone check is to prevent the view from auto-closing if the view contains only a single card and that
|
||||
// card gets dragged within the view.
|
||||
// Another autoclose check is done in prepareAddCard so that the view autocloses if the last card was moved to an
|
||||
// unrevealed portion of the same zone.
|
||||
if (cards.isEmpty() && SettingsCache::instance().getCloseEmptyCardView() && toNewZone) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
updateCardIds(REMOVE_CARD);
|
||||
reorganizeCards();
|
||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void ZoneViewZone::setGeometry(const QRectF &rect)
|
||||
|
|
@ -427,16 +301,6 @@ QSizeF ZoneViewZone::sizeHint(Qt::SizeHint /*which*/, const QSizeF & /*constrain
|
|||
return optimumRect.size();
|
||||
}
|
||||
|
||||
void ZoneViewZone::setWriteableRevealZone(bool _writeableRevealZone)
|
||||
{
|
||||
if (writeableRevealZone && !_writeableRevealZone) {
|
||||
origZone->getViews().append(this);
|
||||
} else if (!writeableRevealZone && _writeableRevealZone) {
|
||||
origZone->getViews().removeOne(this);
|
||||
}
|
||||
writeableRevealZone = _writeableRevealZone;
|
||||
}
|
||||
|
||||
void ZoneViewZone::wheelEvent(QGraphicsSceneWheelEvent *event)
|
||||
{
|
||||
emit wheelEventReceived(event);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define ZONEVIEWERZONE_H
|
||||
|
||||
#include "../filters/filter_string.h"
|
||||
#include "logic/view_zone_logic.h"
|
||||
#include "select_zone.h"
|
||||
|
||||
#include <QGraphicsLayoutItem>
|
||||
|
|
@ -33,22 +34,10 @@ private:
|
|||
static constexpr int VERTICAL_PADDING = 5;
|
||||
|
||||
QRectF bRect, optimumRect;
|
||||
int minRows, numberCards;
|
||||
CardZone *origZone;
|
||||
bool revealZone, writeableRevealZone;
|
||||
int minRows;
|
||||
FilterString filterString = FilterString("");
|
||||
CardList::SortOption groupBy, sortBy;
|
||||
bool pileView;
|
||||
bool isReversed;
|
||||
|
||||
enum CardAction
|
||||
{
|
||||
INITIALIZE,
|
||||
ADD_CARD,
|
||||
REMOVE_CARD
|
||||
};
|
||||
|
||||
void updateCardIds(CardAction action);
|
||||
|
||||
struct GridSize
|
||||
{
|
||||
|
|
@ -58,45 +47,23 @@ private:
|
|||
|
||||
GridSize positionCardsForDisplay(CardList &cards, CardList::SortOption pileOption = CardList::NoSort);
|
||||
|
||||
void handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint) override;
|
||||
void
|
||||
handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneLogic *startZone, const QPoint &dropPoint) override;
|
||||
|
||||
public:
|
||||
ZoneViewZone(Player *_p,
|
||||
CardZone *_origZone,
|
||||
int _numberCards = -1,
|
||||
bool _revealZone = false,
|
||||
bool _writeableRevealZone = false,
|
||||
QGraphicsItem *parent = nullptr,
|
||||
bool _isReversed = false);
|
||||
ZoneViewZone(ZoneViewZoneLogic *_logic, QGraphicsItem *parent);
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void reorganizeCards() override;
|
||||
void initializeCards(const QList<const ServerInfo_Card *> &cardList = QList<const ServerInfo_Card *>());
|
||||
bool prepareAddCard(int x);
|
||||
void removeCard(int position, bool toNewZone);
|
||||
int getNumberCards() const
|
||||
{
|
||||
return numberCards;
|
||||
}
|
||||
void setGeometry(const QRectF &rect) override;
|
||||
QRectF getOptimumRect() const
|
||||
{
|
||||
return optimumRect;
|
||||
}
|
||||
bool getRevealZone() const
|
||||
{
|
||||
return revealZone;
|
||||
}
|
||||
bool getWriteableRevealZone() const
|
||||
{
|
||||
return writeableRevealZone;
|
||||
}
|
||||
void setWriteableRevealZone(bool _writeableRevealZone);
|
||||
bool getIsReversed() const
|
||||
{
|
||||
return isReversed;
|
||||
}
|
||||
public slots:
|
||||
void addToViews();
|
||||
void removeFromViews();
|
||||
void close();
|
||||
void setFilterString(const QString &_filterString);
|
||||
void setGroupBy(CardList::SortOption _groupBy);
|
||||
|
|
@ -110,7 +77,6 @@ signals:
|
|||
void wheelEventReceived(QGraphicsSceneWheelEvent *event);
|
||||
|
||||
protected:
|
||||
void addCardImpl(CardItem *card, int x, int y) override;
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override;
|
||||
void wheelEvent(QGraphicsSceneWheelEvent *event) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
* @param _writeableRevealZone whether the player can interact with the revealed cards.
|
||||
*/
|
||||
ZoneViewWidget::ZoneViewWidget(Player *_player,
|
||||
CardZone *_origZone,
|
||||
CardZoneLogic *_origZone,
|
||||
int numberCards,
|
||||
bool _revealZone,
|
||||
bool _writeableRevealZone,
|
||||
|
|
@ -130,8 +130,9 @@ ZoneViewWidget::ZoneViewWidget(Player *_player,
|
|||
|
||||
vbox->addItem(zoneHBox);
|
||||
|
||||
zone =
|
||||
new ZoneViewZone(player, _origZone, numberCards, _revealZone, _writeableRevealZone, zoneContainer, _isReversed);
|
||||
zone = new ZoneViewZone(new ZoneViewZoneLogic(player, _origZone, numberCards, _revealZone, _writeableRevealZone,
|
||||
_isReversed, zoneContainer),
|
||||
zoneContainer);
|
||||
connect(zone, &ZoneViewZone::wheelEventReceived, scrollBarProxy, &ScrollableGraphicsProxyWidget::recieveWheelEvent);
|
||||
|
||||
retranslateUi();
|
||||
|
|
@ -211,7 +212,7 @@ void ZoneViewWidget::processSetPileView(QT_STATE_CHANGED_T value)
|
|||
|
||||
void ZoneViewWidget::retranslateUi()
|
||||
{
|
||||
setWindowTitle(zone->getTranslatedName(false, CaseNominative));
|
||||
setWindowTitle(zone->getLogic()->getTranslatedName(false, CaseNominative));
|
||||
|
||||
{ // We can't change the strings after they're put into the QComboBox, so this is our workaround
|
||||
int oldIndex = groupBySelector.currentIndex();
|
||||
|
|
@ -353,7 +354,7 @@ void ZoneViewWidget::closeEvent(QCloseEvent *event)
|
|||
// manually call zone->close in order to remove it from the origZones views
|
||||
zone->close();
|
||||
if (shuffleCheckBox.isChecked())
|
||||
player->sendGameCommand(Command_Shuffle());
|
||||
player->getPlayerActions()->sendGameCommand(Command_Shuffle());
|
||||
zoneDeleted();
|
||||
event->accept();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define ZONEVIEWWIDGET_H
|
||||
|
||||
#include "../../utility/macros.h"
|
||||
#include "logic/card_zone_logic.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
|
|
@ -75,7 +76,7 @@ private slots:
|
|||
|
||||
public:
|
||||
ZoneViewWidget(Player *_player,
|
||||
CardZone *_origZone,
|
||||
CardZoneLogic *_origZone,
|
||||
int numberCards = 0,
|
||||
bool _revealZone = false,
|
||||
bool _writeableRevealZone = false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue