From 231887367c30bb7e2f1f9755c32f3c9a063148f3 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Thu, 23 Dec 2010 19:21:47 +0100 Subject: [PATCH] card menu improvement, change controller support (bug #3) --- cockatrice/src/abstractcarddragitem.h | 1 + cockatrice/src/carddragitem.cpp | 4 +- cockatrice/src/carddragitem.h | 1 + cockatrice/src/carditem.cpp | 301 ++++++++++++++++---------- cockatrice/src/carditem.h | 17 +- cockatrice/src/cardzone.cpp | 2 +- cockatrice/src/cardzone.h | 3 +- cockatrice/src/handzone.cpp | 5 +- cockatrice/src/handzone.h | 2 +- cockatrice/src/pilezone.cpp | 4 +- cockatrice/src/pilezone.h | 2 +- cockatrice/src/player.cpp | 49 +++-- cockatrice/src/player.h | 12 +- cockatrice/src/stackzone.cpp | 5 +- cockatrice/src/stackzone.h | 2 +- cockatrice/src/tablezone.cpp | 24 +- cockatrice/src/tablezone.h | 6 +- cockatrice/src/zoneviewzone.cpp | 5 +- cockatrice/src/zoneviewzone.h | 2 +- common/protocol_items.cpp | 6 +- common/protocol_items.dat | 4 +- common/protocol_items.h | 6 +- common/server_player.cpp | 38 ++-- common/server_player.h | 2 +- common/server_protocolhandler.cpp | 7 +- 25 files changed, 305 insertions(+), 205 deletions(-) diff --git a/cockatrice/src/abstractcarddragitem.h b/cockatrice/src/abstractcarddragitem.h index 62f36436..047c4f55 100644 --- a/cockatrice/src/abstractcarddragitem.h +++ b/cockatrice/src/abstractcarddragitem.h @@ -20,6 +20,7 @@ public: ~AbstractCardDragItem(); QRectF boundingRect() const { return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + AbstractCardItem *getItem() const { return item; } QPointF getHotSpot() const { return hotSpot; } void addChildDrag(AbstractCardDragItem *child); virtual void updatePosition(const QPointF &cursorScenePos) = 0; diff --git a/cockatrice/src/carddragitem.cpp b/cockatrice/src/carddragitem.cpp index 5375bae0..f3ab1a54 100644 --- a/cockatrice/src/carddragitem.cpp +++ b/cockatrice/src/carddragitem.cpp @@ -75,11 +75,11 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) CardZone *startZone = static_cast(item)->getZone(); if (currentZone && !(static_cast(item)->getAttachedTo() && (startZone == currentZone))) { if (!occupied) - currentZone->handleDropEvent(id, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown); + currentZone->handleDropEvent(this, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown); for (int i = 0; i < childDrags.size(); i++) { CardDragItem *c = static_cast(childDrags[i]); if (!(static_cast(c->item)->getAttachedTo() && (startZone == currentZone)) && !c->occupied) - currentZone->handleDropEvent(c->id, startZone, (sp - currentZone->scenePos() + c->getHotSpot()).toPoint(), faceDown); + currentZone->handleDropEvent(static_cast(c), startZone, (sp - currentZone->scenePos() + c->getHotSpot()).toPoint(), faceDown); sc->removeItem(c); } } diff --git a/cockatrice/src/carddragitem.h b/cockatrice/src/carddragitem.h index 82f1d66a..95cc71ce 100644 --- a/cockatrice/src/carddragitem.h +++ b/cockatrice/src/carddragitem.h @@ -13,6 +13,7 @@ private: CardZone *currentZone; public: CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag = 0); + int getId() const { return id; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void updatePosition(const QPointF &cursorScenePos); protected: diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index 1a03db31..7e76cfa7 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -17,91 +17,68 @@ #include "tab_game.h" CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, QGraphicsItem *parent) - : AbstractCardItem(_name, _owner, parent), id(_cardid), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(0), attachedTo(0) + : AbstractCardItem(_name, _owner, parent), zone(0), id(_cardid), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(0), attachedTo(0) { owner->addCard(this); - if (owner->getLocal()) { - aTap = new QAction(this); - aTap->setData(0); - connect(aTap, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - aUntap = new QAction(this); - aUntap->setData(1); - connect(aUntap, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - aDoesntUntap = new QAction(this); - aDoesntUntap->setData(2); - connect(aDoesntUntap, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - aAttach = new QAction(this); - connect(aAttach, SIGNAL(triggered()), owner, SLOT(actAttach())); - aUnattach = new QAction(this); - connect(aUnattach, SIGNAL(triggered()), owner, SLOT(actUnattach())); - aSetPT = new QAction(this); - connect(aSetPT, SIGNAL(triggered()), owner, SLOT(actSetPT())); - aSetAnnotation = new QAction(this); - connect(aSetAnnotation, SIGNAL(triggered()), owner, SLOT(actSetAnnotation())); - aFlip = new QAction(this); - aFlip->setData(3); - connect(aFlip, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - aClone = new QAction(this); - aClone->setData(4); - connect(aClone, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - aMoveToTopLibrary = new QAction(this); - aMoveToTopLibrary->setData(5); - aMoveToBottomLibrary = new QAction(this); - aMoveToBottomLibrary->setData(6); - aMoveToGraveyard = new QAction(this); - aMoveToGraveyard->setData(7); - aMoveToExile = new QAction(this); - aMoveToExile->setData(8); - connect(aMoveToTopLibrary, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - connect(aMoveToBottomLibrary, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - connect(aMoveToGraveyard, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); - connect(aMoveToExile, SIGNAL(triggered()), owner, SLOT(cardMenuAction())); + aTap = new QAction(this); + aTap->setData(0); + connect(aTap, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + aUntap = new QAction(this); + aUntap->setData(1); + connect(aUntap, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + aDoesntUntap = new QAction(this); + aDoesntUntap->setData(2); + connect(aDoesntUntap, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + aAttach = new QAction(this); + connect(aAttach, SIGNAL(triggered()), this, SLOT(actAttach())); + aUnattach = new QAction(this); + connect(aUnattach, SIGNAL(triggered()), this, SLOT(actUnattach())); + aSetPT = new QAction(this); + connect(aSetPT, SIGNAL(triggered()), this, SLOT(actSetPT())); + aSetAnnotation = new QAction(this); + connect(aSetAnnotation, SIGNAL(triggered()), this, SLOT(actSetAnnotation())); + aFlip = new QAction(this); + aFlip->setData(3); + connect(aFlip, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + aClone = new QAction(this); + aClone->setData(4); + connect(aClone, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + aMoveToTopLibrary = new QAction(this); + aMoveToTopLibrary->setData(5); + aMoveToBottomLibrary = new QAction(this); + aMoveToBottomLibrary->setData(6); + aMoveToGraveyard = new QAction(this); + aMoveToGraveyard->setData(7); + aMoveToExile = new QAction(this); + aMoveToExile->setData(8); + connect(aMoveToTopLibrary, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + connect(aMoveToBottomLibrary, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + connect(aMoveToGraveyard, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + connect(aMoveToExile, SIGNAL(triggered()), this, SLOT(cardMenuAction())); + + aPlay = new QAction(this); + connect(aPlay, SIGNAL(triggered()), this, SLOT(actPlay())); - cardMenu = new QMenu; - cardMenu->addAction(aTap); - cardMenu->addAction(aUntap); - cardMenu->addAction(aDoesntUntap); - cardMenu->addAction(aFlip); - cardMenu->addSeparator(); - cardMenu->addAction(aAttach); - cardMenu->addAction(aUnattach); - cardMenu->addSeparator(); - cardMenu->addAction(aSetPT); - cardMenu->addAction(aSetAnnotation); - cardMenu->addSeparator(); - cardMenu->addAction(aClone); - for (int i = 0; i < 3; ++i) { - QAction *tempAddCounter = new QAction(this); - tempAddCounter->setData(9 + i * 1000); - QAction *tempRemoveCounter = new QAction(this); - tempRemoveCounter->setData(10 + i * 1000); - QAction *tempSetCounter = new QAction(this); - tempSetCounter->setData(11 + i * 1000); - aAddCounter.append(tempAddCounter); - aRemoveCounter.append(tempRemoveCounter); - aSetCounter.append(tempSetCounter); - connect(tempAddCounter, SIGNAL(triggered()), owner, SLOT(actCardCounterTrigger())); - connect(tempRemoveCounter, SIGNAL(triggered()), owner, SLOT(actCardCounterTrigger())); - connect(tempSetCounter, SIGNAL(triggered()), owner, SLOT(actCardCounterTrigger())); - - cardMenu->addSeparator(); - cardMenu->addAction(tempAddCounter); - cardMenu->addAction(tempRemoveCounter); - cardMenu->addAction(tempSetCounter); - } - cardMenu->addSeparator(); - - moveMenu = cardMenu->addMenu(QString()); - moveMenu->addAction(aMoveToTopLibrary); - moveMenu->addAction(aMoveToBottomLibrary); - moveMenu->addAction(aMoveToGraveyard); - moveMenu->addAction(aMoveToExile); - - - retranslateUi(); - } else - cardMenu = 0; + for (int i = 0; i < 3; ++i) { + QAction *tempAddCounter = new QAction(this); + tempAddCounter->setData(9 + i * 1000); + QAction *tempRemoveCounter = new QAction(this); + tempRemoveCounter->setData(10 + i * 1000); + QAction *tempSetCounter = new QAction(this); + tempSetCounter->setData(11 + i * 1000); + aAddCounter.append(tempAddCounter); + aRemoveCounter.append(tempRemoveCounter); + aSetCounter.append(tempSetCounter); + connect(tempAddCounter, SIGNAL(triggered()), this, SLOT(actCardCounterTrigger())); + connect(tempRemoveCounter, SIGNAL(triggered()), this, SLOT(actCardCounterTrigger())); + connect(tempSetCounter, SIGNAL(triggered()), this, SLOT(actCardCounterTrigger())); + } + cardMenu = new QMenu; + moveMenu = new QMenu; + + retranslateUi(); + updateCardMenu(); } CardItem::~CardItem() @@ -110,6 +87,8 @@ CardItem::~CardItem() delete cardMenu; cardMenu = 0; + delete moveMenu; + moveMenu = 0; deleteDragItem(); } @@ -139,37 +118,85 @@ void CardItem::deleteLater() AbstractCardItem::deleteLater(); } +void CardItem::setZone(CardZone *_zone) +{ + zone = _zone; + updateCardMenu(); +} + +void CardItem::updateCardMenu() +{ + cardMenu->clear(); + + if (owner->getLocal()) { + if (zone) { + if (zone->getName() == "table") { + cardMenu->addAction(aTap); + cardMenu->addAction(aUntap); + cardMenu->addAction(aDoesntUntap); + cardMenu->addAction(aFlip); + cardMenu->addSeparator(); + cardMenu->addAction(aAttach); + if (attachedTo) + cardMenu->addAction(aUnattach); + cardMenu->addSeparator(); + cardMenu->addAction(aSetPT); + cardMenu->addAction(aSetAnnotation); + cardMenu->addSeparator(); + cardMenu->addAction(aClone); + + for (int i = 0; i < aAddCounter.size(); ++i) { + cardMenu->addSeparator(); + cardMenu->addAction(aAddCounter[i]); + cardMenu->addAction(aRemoveCounter[i]); + cardMenu->addAction(aSetCounter[i]); + } + cardMenu->addSeparator(); + } else { + cardMenu->addAction(aPlay); + } + } + + moveMenu->clear(); + moveMenu->addAction(aMoveToTopLibrary); + moveMenu->addAction(aMoveToBottomLibrary); + moveMenu->addAction(aMoveToGraveyard); + moveMenu->addAction(aMoveToExile); + cardMenu->addMenu(moveMenu); + } +} + void CardItem::retranslateUi() { - if (owner->getLocal()) { - aTap->setText(tr("&Tap")); - aUntap->setText(tr("&Untap")); - aDoesntUntap->setText(tr("Toggle &normal untapping")); - aFlip->setText(tr("&Flip")); - aClone->setText(tr("&Clone")); - aAttach->setText(tr("&Attach to card...")); - aAttach->setShortcut(tr("Ctrl+A")); - aUnattach->setText(tr("Unattac&h")); - aSetPT->setText(tr("Set &P/T...")); - aSetAnnotation->setText(tr("&Set annotation...")); - QStringList counterColors; - counterColors.append(tr("red")); - counterColors.append(tr("yellow")); - counterColors.append(tr("green")); - for (int i = 0; i < aAddCounter.size(); ++i) - aAddCounter[i]->setText(tr("&Add counter (%1)").arg(counterColors[i])); - for (int i = 0; i < aRemoveCounter.size(); ++i) - aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(counterColors[i])); - for (int i = 0; i < aSetCounter.size(); ++i) - aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(counterColors[i])); - aMoveToTopLibrary->setText(tr("&top of library")); - aMoveToBottomLibrary->setText(tr("&bottom of library")); - aMoveToGraveyard->setText(tr("&graveyard")); - aMoveToGraveyard->setShortcut(tr("Ctrl+Del")); - aMoveToExile->setText(tr("&exile")); - - moveMenu->setTitle(tr("&Move to")); - } + aPlay->setText(tr("&Play")); + + aTap->setText(tr("&Tap")); + aUntap->setText(tr("&Untap")); + aDoesntUntap->setText(tr("Toggle &normal untapping")); + aFlip->setText(tr("&Flip")); + aClone->setText(tr("&Clone")); + aAttach->setText(tr("&Attach to card...")); + aAttach->setShortcut(tr("Ctrl+A")); + aUnattach->setText(tr("Unattac&h")); + aSetPT->setText(tr("Set &P/T...")); + aSetAnnotation->setText(tr("&Set annotation...")); + QStringList counterColors; + counterColors.append(tr("red")); + counterColors.append(tr("yellow")); + counterColors.append(tr("green")); + for (int i = 0; i < aAddCounter.size(); ++i) + aAddCounter[i]->setText(tr("&Add counter (%1)").arg(counterColors[i])); + for (int i = 0; i < aRemoveCounter.size(); ++i) + aRemoveCounter[i]->setText(tr("&Remove counter (%1)").arg(counterColors[i])); + for (int i = 0; i < aSetCounter.size(); ++i) + aSetCounter[i]->setText(tr("&Set counters (%1)...").arg(counterColors[i])); + aMoveToTopLibrary->setText(tr("&top of library")); + aMoveToBottomLibrary->setText(tr("&bottom of library")); + aMoveToGraveyard->setText(tr("&graveyard")); + aMoveToGraveyard->setShortcut(tr("Ctrl+Del")); + aMoveToExile->setText(tr("&exile")); + + moveMenu->setTitle(tr("&Move to")); } void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -263,6 +290,8 @@ void CardItem::setAttachedTo(CardItem *_attachedTo) if (zone) zone->reorganizeCards(); + + updateCardMenu(); } void CardItem::resetState() @@ -376,7 +405,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) setCursor(Qt::OpenHandCursor); } -void CardItem::playCard(QGraphicsSceneMouseEvent *event) +void CardItem::playCard(bool faceDown) { // Do nothing if the card belongs to another player if (!owner->getLocal()) @@ -385,22 +414,19 @@ void CardItem::playCard(QGraphicsSceneMouseEvent *event) TableZone *tz = qobject_cast(zone); if (tz) tz->toggleTapped(); - else { - bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier); - bool tapped = info->getCipt(); - - zone->getPlayer()->playCard(this, faceDown, tapped); - } + else + zone->getPlayer()->playCard(this, faceDown, info->getCipt()); } void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::RightButton) { if (cardMenu) - cardMenu->exec(event->screenPos()); + if (!cardMenu->isEmpty()) + cardMenu->exec(event->screenPos()); } else if ((event->button() == Qt::LeftButton) && !settingsCache->getDoubleClickToPlay()) { setCursor(Qt::OpenHandCursor); - playCard(event); + playCard(event->modifiers().testFlag(Qt::ShiftModifier)); } AbstractCardItem::mouseReleaseEvent(event); @@ -409,7 +435,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { if (settingsCache->getDoubleClickToPlay()) - playCard(event); + playCard(event->modifiers().testFlag(Qt::ShiftModifier)); event->accept(); } @@ -423,3 +449,38 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value) } return QGraphicsItem::itemChange(change, value); } + +void CardItem::cardMenuAction() +{ + owner->cardMenuAction(static_cast(sender())); +} + +void CardItem::actAttach() +{ + owner->actAttach(static_cast(sender())); +} + +void CardItem::actUnattach() +{ + owner->actUnattach(static_cast(sender())); +} + +void CardItem::actSetPT() +{ + owner->actSetPT(static_cast(sender())); +} + +void CardItem::actSetAnnotation() +{ + owner->actSetAnnotation(static_cast(sender())); +} + +void CardItem::actCardCounterTrigger() +{ + owner->actCardCounterTrigger(static_cast(sender())); +} + +void CardItem::actPlay() +{ + playCard(false); +} \ No newline at end of file diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index 52642abb..844b3198 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -30,12 +30,21 @@ private: QList attachedCards; QList aAddCounter, aSetCounter, aRemoveCounter; - QAction *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone, + QAction *aPlay, + *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone, *aMoveToTopLibrary, *aMoveToBottomLibrary, *aMoveToGraveyard, *aMoveToExile; QMenu *cardMenu, *moveMenu; - void playCard(QGraphicsSceneMouseEvent *event); + void playCard(bool faceDown); void prepareDelete(); +private slots: + void cardMenuAction(); + void actCardCounterTrigger(); + void actAttach(); + void actUnattach(); + void actSetPT(); + void actSetAnnotation(); + void actPlay(); public slots: void deleteLater(); public: @@ -45,13 +54,14 @@ public: ~CardItem(); void retranslateUi(); CardZone *getZone() const { return zone; } - void setZone(CardZone *_zone) { zone = _zone; } + void setZone(CardZone *_zone); QMenu *getCardMenu() const { return cardMenu; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QPoint getGridPoint() const { return gridPoint; } void setGridPoint(const QPoint &_gridPoint) { gridPoint = _gridPoint; } QPoint getGridPos() const { return gridPoint; } Player *getOwner() const { return owner; } + void setOwner(Player *_owner) { owner = _owner; } int getId() const { return id; } void setId(int _id) { id = _id; } bool getAttacking() const { return attacking; } @@ -75,6 +85,7 @@ public: const QList &getAttachedCards() const { return attachedCards; } void resetState(); void processCardInfo(ServerInfo_Card *info); + void updateCardMenu(); CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown); void deleteDragItem(); diff --git a/cockatrice/src/cardzone.cpp b/cockatrice/src/cardzone.cpp index 6052f34e..bae26ceb 100644 --- a/cockatrice/src/cardzone.cpp +++ b/cockatrice/src/cardzone.cpp @@ -166,7 +166,7 @@ void CardZone::moveAllToZone() // Cards need to be moved in reverse order so that the other // cards' list index doesn't change for (int i = cards.size() - 1; i >= 0; i--) - player->sendGameCommand(new Command_MoveCard(-1, getName(), cards.at(i)->getId(), targetZone, targetX)); + player->sendGameCommand(new Command_MoveCard(-1, getName(), cards.at(i)->getId(), player->getId(), targetZone, targetX)); } QPointF CardZone::closestGridPoint(const QPointF &point) diff --git a/cockatrice/src/cardzone.h b/cockatrice/src/cardzone.h index b8e834f6..e9a04c30 100644 --- a/cockatrice/src/cardzone.h +++ b/cockatrice/src/cardzone.h @@ -12,6 +12,7 @@ class ZoneViewZone; class QMenu; class QAction; class QPainter; +class CardDragItem; class CardZone : public QObject, public AbstractGraphicsItem { Q_OBJECT @@ -34,7 +35,7 @@ public slots: public: enum { Type = typeZone }; int type() const { return Type; } - virtual void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown) = 0; + virtual void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown) = 0; CardZone(Player *_player, const QString &_name, bool _hasCardAttr, bool _isShufflable, bool _contentsKnown, QGraphicsItem *parent = 0, bool isView = false); ~CardZone(); void retranslateUi(); diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp index d3d26924..1b78eb8e 100644 --- a/cockatrice/src/handzone.cpp +++ b/cockatrice/src/handzone.cpp @@ -3,6 +3,7 @@ #include "settingscache.h" #include "player.h" #include "protocol_items.h" +#include "carddragitem.h" HandZone::HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent) : SelectZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight) @@ -36,9 +37,9 @@ void HandZone::addCardImpl(CardItem *card, int x, int /*y*/) card->update(); } -void HandZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) +void HandZone::handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) { - player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), cards.size(), -1, false)); + player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), dragItem->getId(), player->getId(), getName(), cards.size(), -1, false)); } QRectF HandZone::boundingRect() const diff --git a/cockatrice/src/handzone.h b/cockatrice/src/handzone.h index 4a68e59c..cde11e83 100644 --- a/cockatrice/src/handzone.h +++ b/cockatrice/src/handzone.h @@ -14,7 +14,7 @@ public slots: void updateOrientation(); public: HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = 0); - void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown); + void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void reorganizeCards(); diff --git a/cockatrice/src/pilezone.cpp b/cockatrice/src/pilezone.cpp index e3278998..cf57df21 100644 --- a/cockatrice/src/pilezone.cpp +++ b/cockatrice/src/pilezone.cpp @@ -48,9 +48,9 @@ void PileZone::addCardImpl(CardItem *card, int x, int /*y*/) card->setParentItem(this); } -void PileZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) +void PileZone::handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) { - player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), 0, 0, false)); + player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), dragItem->getId(), player->getId(), getName(), 0, 0, false)); } void PileZone::reorganizeCards() diff --git a/cockatrice/src/pilezone.h b/cockatrice/src/pilezone.h index 0b786333..7dbb4699 100644 --- a/cockatrice/src/pilezone.h +++ b/cockatrice/src/pilezone.h @@ -9,7 +9,7 @@ public: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void reorganizeCards(); - void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown); + void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index e265745f..49b1fe97 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -562,7 +562,7 @@ void Player::actMoveTopCardsToGrave() if (number > maxCards) number = maxCards; for (int i = 0; i < number; ++i) - commandList.append(new Command_MoveCard(-1, "deck", 0, "grave", 0, 0, false)); + commandList.append(new Command_MoveCard(-1, "deck", 0, getId(), "grave", 0, 0, false)); sendCommandContainer(new CommandContainer(commandList)); } @@ -577,13 +577,13 @@ void Player::actMoveTopCardsToExile() if (number > maxCards) number = maxCards; for (int i = 0; i < number; ++i) - commandList.append(new Command_MoveCard(-1, "deck", 0, "rfg", 0, 0, false)); + commandList.append(new Command_MoveCard(-1, "deck", 0, getId(), "rfg", 0, 0, false)); sendCommandContainer(new CommandContainer(commandList)); } void Player::actMoveTopCardToBottom() { - sendGameCommand(new Command_MoveCard(-1, "deck", 0, "deck", -1, 0, false)); + sendGameCommand(new Command_MoveCard(-1, "deck", 0, getId(), "deck", -1, 0, false)); } void Player::actUntapAll() @@ -790,7 +790,10 @@ void Player::eventStopDumpZone(Event_StopDumpZone *event) void Player::eventMoveCard(Event_MoveCard *event) { CardZone *startZone = zones.value(event->getStartZone(), 0); - CardZone *targetZone = zones.value(event->getTargetZone(), 0); + Player *targetPlayer = static_cast(parent())->getPlayers().value(event->getTargetPlayerId()); + if (!targetPlayer) + return; + CardZone *targetZone = targetPlayer->getZones().value(event->getTargetZone(), 0); if (!startZone || !targetZone) return; @@ -820,6 +823,13 @@ void Player::eventMoveCard(Event_MoveCard *event) if (startZone != targetZone) { card->setBeingPointedAt(false); card->setHovered(false); + + const QList &attachedCards = card->getAttachedCards(); + for (int i = 0; i < attachedCards.size(); ++i) + attachedCards[i]->setParentItem(targetZone); + + if (startZone->getPlayer() != targetZone->getPlayer()) + card->setOwner(targetZone->getPlayer()); } // The log event has to be sent before the card is added to the target zone @@ -1076,10 +1086,10 @@ void Player::playCard(CardItem *c, bool faceDown, bool tapped) { CardInfo *ci = c->getInfo(); if (ci->getTableRow() == 3) - stack->handleDropEvent(c->getId(), c->getZone(), QPoint(), false); + sendGameCommand(new Command_MoveCard(-1, c->getZone()->getName(), c->getId(), getId(), "stack", 0, 0, false)); else { QPoint gridPoint = QPoint(-1, 2 - ci->getTableRow()); - table->handleDropEventByGrid(c->getId(), c->getZone(), gridPoint, faceDown, tapped); + sendGameCommand(new Command_MoveCard(-1, c->getZone()->getName(), c->getId(), getId(), "table", gridPoint.x(), gridPoint.y(), faceDown, tapped)); } } @@ -1246,9 +1256,8 @@ bool Player::clearCardsToDelete() return true; } -void Player::cardMenuAction() +void Player::cardMenuAction(QAction *a) { - QAction *a = static_cast(sender()); QList sel = scene()->selectedItems(); QList commandList; while (!sel.isEmpty()) { @@ -1276,16 +1285,16 @@ void Player::cardMenuAction() commandList.append(new Command_CreateToken(-1, card->getZone()->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), -1, card->getGridPoint().y())); break; case 5: - commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "deck", 0, 0, false)); + commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), getId(), "deck", 0, 0, false)); break; case 6: - commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "deck", -1, 0, false)); + commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), getId(), "deck", -1, 0, false)); break; case 7: - commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "grave", 0, 0, false)); + commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), getId(), "grave", 0, 0, false)); break; case 8: - commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "rfg", 0, 0, false)); + commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), getId(), "rfg", 0, 0, false)); break; default: ; } @@ -1293,7 +1302,7 @@ void Player::cardMenuAction() sendCommandContainer(new CommandContainer(commandList)); } -void Player::actSetPT() +void Player::actSetPT(QAction * /*a*/) { QString oldPT; QListIterator i(scene()->selectedItems()); @@ -1318,7 +1327,7 @@ void Player::actSetPT() } } -void Player::actSetAnnotation() +void Player::actSetAnnotation(QAction * /*a*/) { QString oldAnnotation; QListIterator i(scene()->selectedItems()); @@ -1344,24 +1353,22 @@ void Player::actSetAnnotation() } } -void Player::actAttach() +void Player::actAttach(QAction *a) { - CardItem *card = static_cast(sender()->parent()); + CardItem *card = static_cast(a->parent()); ArrowAttachItem *arrow = new ArrowAttachItem(card); scene()->addItem(arrow); arrow->grabMouse(); } -void Player::actUnattach() +void Player::actUnattach(QAction *a) { - CardItem *card = static_cast(sender()->parent()); + CardItem *card = static_cast(a->parent()); sendGameCommand(new Command_AttachCard(-1, card->getZone()->getName(), card->getId(), -1, QString(), -1)); } -void Player::actCardCounterTrigger() +void Player::actCardCounterTrigger(QAction *a) { - QAction *a = static_cast(sender()); - int counterId = a->data().toInt() / 1000; int action = a->data().toInt() % 1000; switch (action) { diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index 03974926..904bc549 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -94,12 +94,12 @@ public slots: void actSayMessage(); - void actAttach(); - void actUnattach(); - void actSetPT(); - void actSetAnnotation(); - void cardMenuAction(); - void actCardCounterTrigger(); + void actAttach(QAction *action); + void actUnattach(QAction *action); + void actSetPT(QAction *action); + void actSetAnnotation(QAction *action); + void cardMenuAction(QAction *action); + void actCardCounterTrigger(QAction *action); private slots: void addPlayer(Player *player); diff --git a/cockatrice/src/stackzone.cpp b/cockatrice/src/stackzone.cpp index b21bd77f..fa368d8e 100644 --- a/cockatrice/src/stackzone.cpp +++ b/cockatrice/src/stackzone.cpp @@ -5,6 +5,7 @@ #include "settingscache.h" #include "player.h" #include "protocol_items.h" +#include "carddragitem.h" StackZone::StackZone(Player *_p, int _zoneHeight, QGraphicsItem *parent) : SelectZone(_p, "stack", false, false, true, parent), zoneHeight(_zoneHeight) @@ -51,11 +52,11 @@ void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*optio painter->fillRect(boundingRect(), QBrush(bgPixmap)); } -void StackZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) +void StackZone::handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) { if (startZone == this) return; - player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), 0, 0, false)); + player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), dragItem->getId(), player->getId(), getName(), 0, 0, false)); } void StackZone::reorganizeCards() diff --git a/cockatrice/src/stackzone.h b/cockatrice/src/stackzone.h index 40d67541..5bb11ce6 100644 --- a/cockatrice/src/stackzone.h +++ b/cockatrice/src/stackzone.h @@ -12,7 +12,7 @@ private slots: void updateBgPixmap(); public: StackZone(Player *_p, int _zoneHeight, QGraphicsItem *parent = 0); - void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown); + void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void reorganizeCards(); diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index 5f008262..2551c8cb 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -7,6 +7,7 @@ #include "protocol_items.h" #include "settingscache.h" #include "arrowitem.h" +#include "carddragitem.h" TableZone::TableZone(Player *_p, QGraphicsItem *parent) : SelectZone(_p, "table", true, false, true, parent), active(false) @@ -84,14 +85,14 @@ void TableZone::addCardImpl(CardItem *card, int _x, int _y) card->update(); } -void TableZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown) +void TableZone::handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown) { - handleDropEventByGrid(cardId, startZone, mapToGrid(dropPoint), faceDown); + handleDropEventByGrid(dragItem, startZone, mapToGrid(dropPoint), faceDown); } -void TableZone::handleDropEventByGrid(int cardId, CardZone *startZone, const QPoint &gridPoint, bool faceDown, bool tapped) +void TableZone::handleDropEventByGrid(CardDragItem *dragItem, CardZone *startZone, const QPoint &gridPoint, bool faceDown, bool tapped) { - player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), gridPoint.x(), gridPoint.y(), faceDown, tapped)); + static_cast(dragItem->getItem())->getZone()->getPlayer()->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), dragItem->getId(), player->getId(), getName(), gridPoint.x(), gridPoint.y(), faceDown, tapped)); } void TableZone::reorganizeCards() @@ -223,18 +224,21 @@ CardItem *TableZone::getCardFromCoords(const QPointF &point) const return getCardFromGrid(gridPoint); } -QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const +QPointF TableZone::mapFromGrid(QPoint gridPoint) const { qreal x, y; x = marginX + (gridPoint.x() % 3) * CARD_WIDTH / 3.0; for (int i = 0; i < gridPoint.x() / 3; ++i) x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + paddingX; - y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10; + if (isInverted()) + gridPoint.setY(2 - gridPoint.y()); + y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10; +/* if (isInverted()) y = height - CARD_HEIGHT - y; - +*/ return QPointF(x, y); } @@ -242,9 +246,9 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const { qreal x = mapPoint.x() - marginX; qreal y = mapPoint.y(); - if (isInverted()) +/* if (isInverted()) y = height - y; - y -= boxLineWidth; +*/ y -= boxLineWidth; if (x < 0) x = 0; @@ -256,6 +260,8 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const y = height - CARD_HEIGHT; int resultY = round(y / (CARD_HEIGHT + paddingY + 20)); + if (isInverted()) + resultY = 2 - resultY; int baseX = -1; qreal oldTempX = 0, tempX = 0; diff --git a/cockatrice/src/tablezone.h b/cockatrice/src/tablezone.h index 4eb48ceb..9761f8ea 100644 --- a/cockatrice/src/tablezone.h +++ b/cockatrice/src/tablezone.h @@ -29,11 +29,11 @@ public: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void toggleTapped(); - void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown = false); - void handleDropEventByGrid(int cardId, CardZone *startZone, const QPoint &gridPoint, bool faceDown = false, bool tapped = false); + void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown = false); + void handleDropEventByGrid(CardDragItem *dragItem, CardZone *startZone, const QPoint &gridPoint, bool faceDown = false, bool tapped = false); CardItem *getCardFromGrid(const QPoint &gridPoint) const; CardItem *getCardFromCoords(const QPointF &point) const; - QPointF mapFromGrid(const QPoint &gridPoint) const; + QPointF mapFromGrid(QPoint gridPoint) const; QPoint mapToGrid(const QPointF &mapPoint) const; QPointF closestGridPoint(const QPointF &point); CardItem *takeCard(int position, int cardId, bool canResize = true); diff --git a/cockatrice/src/zoneviewzone.cpp b/cockatrice/src/zoneviewzone.cpp index 18166308..bcf59775 100644 --- a/cockatrice/src/zoneviewzone.cpp +++ b/cockatrice/src/zoneviewzone.cpp @@ -3,6 +3,7 @@ #include "zoneviewzone.h" #include "player.h" #include "protocol_items.h" +#include "carddragitem.h" ZoneViewZone::ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards, QGraphicsItem *parent) : SelectZone(_p, _origZone->getName(), false, false, true, parent, true), bRect(QRectF()), minRows(0), numberCards(_numberCards), origZone(_origZone), sortByName(false), sortByType(false) @@ -122,9 +123,9 @@ void ZoneViewZone::addCardImpl(CardItem *card, int x, int /*y*/) card->update(); } -void ZoneViewZone::handleDropEvent(int cardId, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) +void ZoneViewZone::handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &/*dropPoint*/, bool /*faceDown*/) { - player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), cardId, getName(), 0, 0, false)); + player->sendGameCommand(new Command_MoveCard(-1, startZone->getName(), dragItem->getId(), player->getId(), getName(), 0, 0, false)); } void ZoneViewZone::removeCard(int position) diff --git a/cockatrice/src/zoneviewzone.h b/cockatrice/src/zoneviewzone.h index 52a9aac7..d2208768 100644 --- a/cockatrice/src/zoneviewzone.h +++ b/cockatrice/src/zoneviewzone.h @@ -13,7 +13,7 @@ class ZoneViewZone : public SelectZone, public QGraphicsLayoutItem { private: QRectF bRect, optimumRect; int minRows, numberCards; - void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown); + void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown); CardZone *origZone; bool sortByName, sortByType; public: diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 57a32f63..47b5c000 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -118,11 +118,12 @@ Command_DrawCards::Command_DrawCards(int _gameId, int _number) { insertItem(new SerializableItem_Int("number", _number)); } -Command_MoveCard::Command_MoveCard(int _gameId, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped) +Command_MoveCard::Command_MoveCard(int _gameId, const QString &_startZone, int _cardId, int _targetPlayerId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped) : GameCommand("move_card", _gameId) { insertItem(new SerializableItem_String("start_zone", _startZone)); insertItem(new SerializableItem_Int("card_id", _cardId)); + insertItem(new SerializableItem_Int("target_player_id", _targetPlayerId)); insertItem(new SerializableItem_String("target_zone", _targetZone)); insertItem(new SerializableItem_Int("x", _x)); insertItem(new SerializableItem_Int("y", _y)); @@ -283,13 +284,14 @@ Event_RollDie::Event_RollDie(int _playerId, int _sides, int _value) insertItem(new SerializableItem_Int("sides", _sides)); insertItem(new SerializableItem_Int("value", _value)); } -Event_MoveCard::Event_MoveCard(int _playerId, int _cardId, const QString &_cardName, const QString &_startZone, int _position, const QString &_targetZone, int _x, int _y, int _newCardId, bool _faceDown) +Event_MoveCard::Event_MoveCard(int _playerId, int _cardId, const QString &_cardName, const QString &_startZone, int _position, int _targetPlayerId, const QString &_targetZone, int _x, int _y, int _newCardId, bool _faceDown) : GameEvent("move_card", _playerId) { insertItem(new SerializableItem_Int("card_id", _cardId)); insertItem(new SerializableItem_String("card_name", _cardName)); insertItem(new SerializableItem_String("start_zone", _startZone)); insertItem(new SerializableItem_Int("position", _position)); + insertItem(new SerializableItem_Int("target_player_id", _targetPlayerId)); insertItem(new SerializableItem_String("target_zone", _targetZone)); insertItem(new SerializableItem_Int("x", _x)); insertItem(new SerializableItem_Int("y", _y)); diff --git a/common/protocol_items.dat b/common/protocol_items.dat index bc9a28e5..68b1e568 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -21,7 +21,7 @@ 2:mulligan 2:roll_die:i,sides 2:draw_cards:i,number -2:move_card:s,start_zone:i,card_id:s,target_zone:i,x:i,y:b,face_down:b,tapped +2:move_card:s,start_zone:i,card_id:i,target_player_id:s,target_zone:i,x:i,y:b,face_down:b,tapped 2:flip_card:s,zone:i,card_id:b,face_down 2:attach_card:s,start_zone:i,card_id:i,target_player_id:s,target_zone:i,target_card_id 2:create_token:s,zone:s,card_name:s,color:s,pt:s,annotation:b,destroy:i,x:i,y @@ -46,7 +46,7 @@ 3:game_closed 3:shuffle 3:roll_die:i,sides:i,value -3:move_card:i,card_id:s,card_name:s,start_zone:i,position:s,target_zone:i,x:i,y:i,new_card_id:b,face_down +3:move_card:i,card_id:s,card_name:s,start_zone:i,position:i,target_player_id:s,target_zone:i,x:i,y:i,new_card_id:b,face_down 3:flip_card:s,zone:i,card_id:s,card_name:b,face_down 3:destroy_card:s,zone:i,card_id 3:attach_card:s,start_zone:i,card_id:i,target_player_id:s,target_zone:i,target_card_id diff --git a/common/protocol_items.h b/common/protocol_items.h index 69664127..331c2610 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -192,9 +192,10 @@ public: class Command_MoveCard : public GameCommand { Q_OBJECT public: - Command_MoveCard(int _gameId = -1, const QString &_startZone = QString(), int _cardId = -1, const QString &_targetZone = QString(), int _x = -1, int _y = -1, bool _faceDown = false, bool _tapped = false); + Command_MoveCard(int _gameId = -1, const QString &_startZone = QString(), int _cardId = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _x = -1, int _y = -1, bool _faceDown = false, bool _tapped = false); QString getStartZone() const { return static_cast(itemMap.value("start_zone"))->getData(); }; int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; + int getTargetPlayerId() const { return static_cast(itemMap.value("target_player_id"))->getData(); }; QString getTargetZone() const { return static_cast(itemMap.value("target_zone"))->getData(); }; int getX() const { return static_cast(itemMap.value("x"))->getData(); }; int getY() const { return static_cast(itemMap.value("y"))->getData(); }; @@ -432,11 +433,12 @@ public: class Event_MoveCard : public GameEvent { Q_OBJECT public: - Event_MoveCard(int _playerId = -1, int _cardId = -1, const QString &_cardName = QString(), const QString &_startZone = QString(), int _position = -1, const QString &_targetZone = QString(), int _x = -1, int _y = -1, int _newCardId = -1, bool _faceDown = false); + Event_MoveCard(int _playerId = -1, int _cardId = -1, const QString &_cardName = QString(), const QString &_startZone = QString(), int _position = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _x = -1, int _y = -1, int _newCardId = -1, bool _faceDown = false); int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; QString getCardName() const { return static_cast(itemMap.value("card_name"))->getData(); }; QString getStartZone() const { return static_cast(itemMap.value("start_zone"))->getData(); }; int getPosition() const { return static_cast(itemMap.value("position"))->getData(); }; + int getTargetPlayerId() const { return static_cast(itemMap.value("target_player_id"))->getData(); }; QString getTargetZone() const { return static_cast(itemMap.value("target_zone"))->getData(); }; int getX() const { return static_cast(itemMap.value("x"))->getData(); }; int getY() const { return static_cast(itemMap.value("y"))->getData(); }; diff --git a/common/server_player.cpp b/common/server_player.cpp index 92929554..e7da0d31 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -198,10 +198,13 @@ bool Server_Player::deleteCounter(int counterId) return true; } -ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped) +ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, int targetPlayerId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped) { Server_CardZone *startzone = getZones().value(_startZone); - Server_CardZone *targetzone = getZones().value(_targetZone); + Server_Player *targetPlayer = game->getPlayers().value(targetPlayerId); + if (!targetPlayer) + return RespNameNotFound; + Server_CardZone *targetzone = targetPlayer->getZones().value(_targetZone); if ((!startzone) || (!targetzone)) return RespNameNotFound; @@ -210,12 +213,10 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_sta ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *startzone, int _cardId, Server_CardZone *targetzone, int x, int y, bool faceDown, bool tapped) { - // Collision detection -/* if (targetzone->hasCoords()) - for (int i = 0; i < targetzone->cards.size(); ++i) - if ((targetzone->cards[i]->getX() == x) && (targetzone->cards[i]->getY() == y) && (x != -1)) - return RespContextError; -*/ + // Disallow controller change between different zones. + if ((startzone->getName() != targetzone->getName()) && (startzone->getPlayer() != targetzone->getPlayer())) + return RespContextError; + int position = -1; Server_Card *card = startzone->getCard(_cardId, false, &position); if (!card) @@ -226,15 +227,19 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st int oldX = card->getX(), oldY = card->getY(); - if (startzone != targetzone) { + // Attachment relationships can be retained when moving a card onto the opponent's table + if (startzone->getName() != targetzone->getName()) { // Delete all attachment relationships if (card->getParentCard()) card->setParentCard(0); - const QList &attachedCards = card->getAttachedCards(); + // Make a copy of the list because the original one gets modified during the loop + QList attachedCards = card->getAttachedCards(); for (int i = 0; i < attachedCards.size(); ++i) attachedCards[i]->getZone()->getPlayer()->unattachCard(cont, attachedCards[i]); - + } + + if (startzone != targetzone) { // Delete all arrows from and to the card const QList &players = game->getPlayers().values(); for (int i = 0; i < players.size(); ++i) { @@ -266,7 +271,6 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st card->resetState(); } else -// if (x == -1) x = targetzone->getFreeGridColumn(x, y, card->getName()); targetzone->insertCard(card, x, y); @@ -302,8 +306,8 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st int privatePosition = -1; if (startzone->getType() == HiddenZone) privatePosition = position; - cont->enqueueGameEventPrivate(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); - cont->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); + cont->enqueueGameEventPrivate(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); + cont->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); // Other players do not get to see the start and/or target position of the card if the respective // part of the zone is being looked at. The information is not needed anyway because in hidden zones, @@ -317,9 +321,9 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st x = -1; if ((startzone->getType() == PublicZone) || (targetzone->getType() == PublicZone)) - cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getName(), x, y, card->getId(), faceDown), game->getGameId()); + cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), x, y, card->getId(), faceDown), game->getGameId()); else - cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getName(), x, y, -1, false), game->getGameId()); + cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), x, y, -1, false), game->getGameId()); if (tapped) setCardAttrHelper(cont, targetzone->getName(), card->getId(), "tapped", "1"); @@ -338,7 +342,7 @@ void Server_Player::unattachCard(CommandContainer *cont, Server_Card *card) cont->enqueueGameEventPrivate(new Event_AttachCard(getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId()); cont->enqueueGameEventPublic(new Event_AttachCard(getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId()); - moveCard(cont, zone->getName(), card->getId(), zone->getName(), -1, card->getY(), card->getFaceDown(), card->getTapped()); + moveCard(cont, zone, card->getId(), zone, -1, card->getY(), card->getFaceDown(), card->getTapped()); } ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue) diff --git a/common/server_player.h b/common/server_player.h index 6e17b9c6..7a3138c3 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -74,7 +74,7 @@ public: void clearZones(); void setupZones(); - ResponseCode moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped); + ResponseCode moveCard(CommandContainer *cont, const QString &_startZone, int _cardId, int _targetPlayer, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped); ResponseCode moveCard(CommandContainer *cont, Server_CardZone *startzone, int _cardId, Server_CardZone *targetzone, int x, int y, bool faceDown, bool tapped); void unattachCard(CommandContainer *cont, Server_Card *card); ResponseCode setCardAttrHelper(CommandContainer *cont, const QString &zone, int cardId, const QString &attrName, const QString &attrValue); diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 475c8b46..d641bb86 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -509,10 +509,11 @@ ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, Com return RespContextError; Server_CardZone *hand = player->getZones().value("hand"); + Server_CardZone *deck = player->getZones().value("deck"); while (!hand->cards.isEmpty()) - player->moveCard(cont, "hand", hand->cards.first()->getId(), "deck", 0, 0, false, false); + player->moveCard(cont, hand, hand->cards.first()->getId(), deck, 0, 0, false, false); - player->getZones().value("deck")->shuffle(); + deck->shuffle(); cont->enqueueGameEventPrivate(new Event_Shuffle(player->getPlayerId()), game->getGameId()); cont->enqueueGameEventPublic(new Event_Shuffle(player->getPlayerId()), game->getGameId()); @@ -574,7 +575,7 @@ ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandC if (!game->getGameStarted()) return RespGameNotStarted; - return player->moveCard(cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped()); + return player->moveCard(cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetPlayerId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped()); } ResponseCode Server_ProtocolHandler::cmdFlipCard(Command_FlipCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)