From cbf201ed9b766170e0c0284fb98fe10070d966c2 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Sun, 27 Jun 2010 14:50:51 +0200 Subject: [PATCH] optionally destroy tokens on zone change; added multi arrows; card menu changes; arrow fixes; initial commit for attachCard code --- cockatrice/src/arrowitem.cpp | 13 +- cockatrice/src/arrowitem.h | 4 + cockatrice/src/carditem.cpp | 154 +++++++++++++++- cockatrice/src/carditem.h | 12 ++ cockatrice/src/cardzone.cpp | 6 + cockatrice/src/cardzone.h | 1 + cockatrice/src/dlg_create_token.cpp | 9 + cockatrice/src/dlg_create_token.h | 3 + cockatrice/src/messagelogwidget.cpp | 8 +- cockatrice/src/messagelogwidget.h | 1 + cockatrice/src/player.cpp | 275 +++++++++++----------------- cockatrice/src/player.h | 35 ++-- common/protocol_datastructures.cpp | 3 +- common/protocol_datastructures.h | 3 +- common/protocol_item_ids.h | 85 ++++----- common/protocol_items.cpp | 33 +++- common/protocol_items.dat | 7 +- common/protocol_items.h | 39 +++- common/server_card.cpp | 3 +- common/server_card.h | 7 + common/server_game.cpp | 2 +- common/server_protocolhandler.cpp | 47 ++++- common/server_protocolhandler.h | 1 + 23 files changed, 504 insertions(+), 247 deletions(-) diff --git a/cockatrice/src/arrowitem.cpp b/cockatrice/src/arrowitem.cpp index 54af29bf..7b4349cd 100644 --- a/cockatrice/src/arrowitem.cpp +++ b/cockatrice/src/arrowitem.cpp @@ -101,6 +101,11 @@ ArrowDragItem::ArrowDragItem(CardItem *_startItem, const QColor &_color) { } +void ArrowDragItem::addChildArrow(ArrowDragItem *childArrow) +{ + childArrows.append(childArrow); +} + void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QPointF endPos = event->scenePos(); @@ -124,9 +129,12 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) updatePath(); } update(); + + for (int i = 0; i < childArrows.size(); ++i) + childArrows[i]->mouseMoveEvent(event); } -void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/) +void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (targetItem && (targetItem != startItem)) { targetItem->setBeingPointedAt(false); @@ -144,4 +152,7 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/) )); } deleteLater(); + + for (int i = 0; i < childArrows.size(); ++i) + childArrows[i]->mouseReleaseEvent(event); } diff --git a/cockatrice/src/arrowitem.h b/cockatrice/src/arrowitem.h index f6a250ae..47fd8585 100644 --- a/cockatrice/src/arrowitem.h +++ b/cockatrice/src/arrowitem.h @@ -24,6 +24,7 @@ public: ArrowItem(Player *_player, int _id, CardItem *_startItem, CardItem *_targetItem, const QColor &color); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QRectF boundingRect() const { return path.boundingRect(); } + QPainterPath shape() const { return path; } void updatePath(); void updatePath(const QPointF &endPoint); @@ -36,8 +37,11 @@ public: class ArrowDragItem : public ArrowItem { Q_OBJECT +private: + QList childArrows; public: ArrowDragItem(CardItem *_startItem, const QColor &_color); + void addChildArrow(ArrowDragItem *childArrow); protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index 99a4cd6d..8e771f98 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -12,16 +12,135 @@ #include "settingscache.h" CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, QGraphicsItem *parent) - : AbstractCardItem(_name, parent), owner(_owner), id(_cardid), attacking(false), facedown(false), doesntUntap(false), beingPointedAt(false), dragItem(NULL) + : AbstractCardItem(_name, parent), owner(_owner), id(_cardid), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), beingPointedAt(false), dragItem(NULL) { 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())); + + + 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; } CardItem::~CardItem() { + if (owner->getCardMenu() == cardMenu) + owner->setCardMenu(0); + delete cardMenu; + deleteDragItem(); } +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...")); + aUnattach->setText(tr("Unattach")); + 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) { painter->save(); @@ -125,7 +244,9 @@ void CardItem::processCardInfo(ServerInfo_Card *info) setAttacking(info->getAttacking()); setPT(info->getPT()); setAnnotation(info->getAnnotation()); + setColor(info->getColor()); setTapped(info->getTapped()); + setDestroyOnZoneChange(info->getDestroyOnZoneChange()); } CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown) @@ -161,6 +282,19 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) ArrowDragItem *arrow = new ArrowDragItem(this, arrowColor); scene()->addItem(arrow); arrow->grabMouse(); + + QListIterator itemIterator(scene()->selectedItems()); + while (itemIterator.hasNext()) { + CardItem *c = qgraphicsitem_cast(itemIterator.next()); + if (!c) + continue; + if (c->parentItem() != parentItem()) + continue; + + ArrowDragItem *childArrow = new ArrowDragItem(c, arrowColor); + scene()->addItem(childArrow); + arrow->addChildArrow(childArrow); + } } else { if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < 2 * QApplication::startDragDistance()) return; @@ -216,9 +350,10 @@ void CardItem::playCard(QGraphicsSceneMouseEvent *event) void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - if (event->button() == Qt::RightButton) - qgraphicsitem_cast(parentItem())->getPlayer()->showCardMenu(event->screenPos()); - else if ((event->button() == Qt::LeftButton) && !settingsCache->getDoubleClickToPlay()) + if (event->button() == Qt::RightButton) { + if (cardMenu) + cardMenu->exec(event->screenPos()); + } else if ((event->button() == Qt::LeftButton) && !settingsCache->getDoubleClickToPlay()) playCard(event); setCursor(Qt::OpenHandCursor); @@ -230,3 +365,14 @@ void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) playCard(event); event->accept(); } + +QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemSelectedHasChanged) { + if (value == true) + owner->setCardMenu(cardMenu); + else if (owner->getCardMenu() == cardMenu) + owner->setCardMenu(0); + } + return QGraphicsItem::itemChange(change, value); +} diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index fe3afeac..2a378774 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -8,6 +8,7 @@ class CardDragItem; class CardZone; class ServerInfo_Card; class Player; +class QAction; const int MAX_COUNTERS_ON_CARD = 999; @@ -21,17 +22,25 @@ private: QMap counters; QString annotation; QString pt; + bool destroyOnZoneChange; bool doesntUntap; QPoint gridPoint; bool beingPointedAt; CardDragItem *dragItem; + QList aAddCounter, aSetCounter, aRemoveCounter; + QAction *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone, + *aMoveToTopLibrary, *aMoveToBottomLibrary, *aMoveToGraveyard, *aMoveToExile; + QMenu *cardMenu, *moveMenu; + void playCard(QGraphicsSceneMouseEvent *event); public: enum { Type = typeCard }; int type() const { return Type; } CardItem(Player *_owner, const QString &_name = QString(), int _cardid = -1, QGraphicsItem *parent = 0); ~CardItem(); + void retranslateUi(); + 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; } @@ -51,6 +60,8 @@ public: void setDoesntUntap(bool _doesntUntap); QString getPT() const { return pt; } void setPT(const QString &_pt); + bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } + void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } void setBeingPointedAt(bool _beingPointedAt); void resetState(); void processCardInfo(ServerInfo_Card *info); @@ -61,6 +72,7 @@ protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + QVariant itemChange(GraphicsItemChange change, const QVariant &value); }; #endif diff --git a/cockatrice/src/cardzone.cpp b/cockatrice/src/cardzone.cpp index 6cbb4535..ad6f2725 100644 --- a/cockatrice/src/cardzone.cpp +++ b/cockatrice/src/cardzone.cpp @@ -19,6 +19,12 @@ CardZone::~CardZone() clearContents(); } +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++) diff --git a/cockatrice/src/cardzone.h b/cockatrice/src/cardzone.h index 0c60b3ac..331a2feb 100644 --- a/cockatrice/src/cardzone.h +++ b/cockatrice/src/cardzone.h @@ -37,6 +37,7 @@ public: virtual void handleDropEvent(int cardId, 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(); void clearContents(); bool getHasCardAttr() const { return hasCardAttr; } bool getIsShufflable() const { return isShufflable; } diff --git a/cockatrice/src/dlg_create_token.cpp b/cockatrice/src/dlg_create_token.cpp index 01260542..e21c17bb 100644 --- a/cockatrice/src/dlg_create_token.cpp +++ b/cockatrice/src/dlg_create_token.cpp @@ -26,6 +26,9 @@ DlgCreateToken::DlgCreateToken(QWidget *parent) annotationLabel = new QLabel(tr("&Annotation:")); annotationEdit = new QLineEdit; annotationLabel->setBuddy(annotationEdit); + + destroyCheckBox = new QCheckBox(tr("&Destroy token when it leaves the table")); + destroyCheckBox->setChecked(true); okButton = new QPushButton(tr("&OK")); okButton->setDefault(true); @@ -40,6 +43,7 @@ DlgCreateToken::DlgCreateToken(QWidget *parent) grid->addWidget(ptEdit, 2, 1); grid->addWidget(annotationLabel, 3, 0); grid->addWidget(annotationEdit, 3, 1); + grid->addWidget(destroyCheckBox, 4, 0, 1, 2); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); @@ -83,3 +87,8 @@ QString DlgCreateToken::getAnnotation() const { return annotationEdit->text(); } + +bool DlgCreateToken::getDestroy() const +{ + return destroyCheckBox->isChecked(); +} diff --git a/cockatrice/src/dlg_create_token.h b/cockatrice/src/dlg_create_token.h index a328239c..1e2b3b75 100644 --- a/cockatrice/src/dlg_create_token.h +++ b/cockatrice/src/dlg_create_token.h @@ -6,6 +6,7 @@ class QLabel; class QComboBox; +class QCheckBox; class QPushButton; class DlgCreateToken : public QDialog { @@ -16,12 +17,14 @@ public: QString getColor() const; QString getPT() const; QString getAnnotation() const; + bool getDestroy() const; private slots: void actOk(); private: QLabel *nameLabel, *colorLabel, *ptLabel, *annotationLabel; QComboBox *colorEdit; QLineEdit *nameEdit, *ptEdit, *annotationEdit; + QCheckBox *destroyCheckBox; QPushButton *okButton, *cancelButton; }; diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index f8f5a919..f99a439a 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -202,9 +202,14 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s append(finalStr.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(newX)); } +void MessageLogWidget::logDestroyCard(Player *player, QString cardName) +{ + append(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); +} + void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt) { - append(tr("%1 creates token: %2 (%3).").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(pt))); + append(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt)))); } void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard) @@ -327,6 +332,7 @@ void MessageLogWidget::connectToPlayer(Player *player) connect(player, SIGNAL(logSetPT(Player *, QString, QString)), this, SLOT(logSetPT(Player *, QString, QString))); connect(player, SIGNAL(logSetAnnotation(Player *, QString, QString)), this, SLOT(logSetAnnotation(Player *, QString, QString))); connect(player, SIGNAL(logMoveCard(Player *, QString, CardZone *, int, CardZone *, int)), this, SLOT(logMoveCard(Player *, QString, CardZone *, int, CardZone *, int))); + connect(player, SIGNAL(logDestroyCard(Player *, QString)), this, SLOT(logDestroyCard(Player *, QString))); connect(player, SIGNAL(logDumpZone(Player *, CardZone *, int)), this, SLOT(logDumpZone(Player *, CardZone *, int))); connect(player, SIGNAL(logStopDumpZone(Player *, CardZone *)), this, SLOT(logStopDumpZone(Player *, CardZone *))); connect(player, SIGNAL(logDrawCards(Player *, int)), this, SLOT(logDrawCards(Player *, int))); diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index de2f5a91..451558d4 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -39,6 +39,7 @@ public slots: void logRollDie(Player *player, int sides, int roll); void logDrawCards(Player *player, int number); void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX); + void logDestroyCard(Player *player, QString cardName); void logCreateToken(Player *player, QString cardName, QString pt); void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard); void logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index fe5ddb7d..7fcc1bf8 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -20,7 +20,7 @@ #include Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabGame *_parent) - : QObject(_parent), defaultNumberTopCards(3), name(_name), id(_id), active(false), local(_local), mirrored(false), client(_client) + : QObject(_parent), defaultNumberTopCards(3), lastTokenDestroy(true), name(_name), id(_id), active(false), local(_local), mirrored(false), client(_client) { setCacheMode(DeviceCoordinateCache); @@ -200,76 +200,12 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG sayMenu = playerMenu->addMenu(QString()); initSayMenu(); - // Card menu - aTap = new QAction(this); - aUntap = new QAction(this); - aDoesntUntap = new QAction(this); - 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); - aMoveToTopLibrary = new QAction(this); - aMoveToBottomLibrary = new QAction(this); - aMoveToGraveyard = new QAction(this); - aMoveToExile = new QAction(this); - - for (int i = 0; i < 3; ++i) { - QMenu *menu = new QMenu; - QAction *tempAddCounter = new QAction(this); - QAction *tempRemoveCounter = new QAction(this); - QAction *tempSetCounter = new QAction(this); - menu->addAction(tempAddCounter); - menu->addAction(tempRemoveCounter); - menu->addAction(tempSetCounter); - aAddCounter.append(tempAddCounter); - aRemoveCounter.append(tempRemoveCounter); - aSetCounter.append(tempSetCounter); - connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(actCardCounterTrigger(QAction *))); - cardCounterMenus.append(menu); - } - - cardMenu = new QMenu; - cardMenu->addAction(aTap); - cardMenu->addAction(aUntap); - cardMenu->addAction(aDoesntUntap); - cardMenu->addSeparator(); - cardMenu->addAction(aSetPT); - cardMenu->addAction(aSetAnnotation); - cardMenu->addSeparator(); - cardMenu->addAction(aFlip); - cardMenu->addSeparator(); - for (int i = 0; i < cardCounterMenus.size(); ++i) - cardMenu->addMenu(cardCounterMenus[i]); - cardMenu->addSeparator(); - moveMenu = cardMenu->addMenu(QString()); - + aCardMenu = new QAction(this); playerMenu->addSeparator(); - playerMenu->addMenu(cardMenu); - - moveMenu->addAction(aMoveToTopLibrary); - moveMenu->addAction(aMoveToBottomLibrary); - moveMenu->addAction(aMoveToGraveyard); - moveMenu->addAction(aMoveToExile); - - cardMenuHandlers.insert(aTap, &Player::actTap); - cardMenuHandlers.insert(aUntap, &Player::actUntap); - cardMenuHandlers.insert(aDoesntUntap, &Player::actDoesntUntap); - cardMenuHandlers.insert(aFlip, &Player::actFlip); - cardMenuHandlers.insert(aMoveToTopLibrary, &Player::actMoveToTopLibrary); - cardMenuHandlers.insert(aMoveToBottomLibrary, &Player::actMoveToBottomLibrary); - cardMenuHandlers.insert(aMoveToGraveyard, &Player::actMoveToGraveyard); - cardMenuHandlers.insert(aMoveToExile, &Player::actMoveToExile); - - QHashIterator i(cardMenuHandlers); - while (i.hasNext()) { - i.next(); - connect(i.key(), SIGNAL(triggered()), this, SLOT(cardMenuAction())); - } + playerMenu->addAction(aCardMenu); } else { countersMenu = 0; sbMenu = 0; - cardMenu = 0; aCreateAnotherToken = 0; } @@ -290,7 +226,6 @@ Player::~Player() clearCounters(); clearArrows(); delete playerMenu; - delete cardMenu; } void Player::rearrangeZones() @@ -391,30 +326,12 @@ void Player::retranslateUi() while (counterIterator.hasNext()) counterIterator.next().value()->retranslateUi(); - cardMenu->setTitle(tr("C&ard")); - aTap->setText(tr("&Tap")); - aUntap->setText(tr("&Untap")); - aDoesntUntap->setText(tr("Toggle &normal untapping")); - aSetPT->setText(tr("Set &P/T...")); - aSetAnnotation->setText(tr("&Set annotation...")); - aFlip->setText(tr("&Flip")); - cardCounterMenus[0]->setTitle(tr("Counters (red)")); - cardCounterMenus[1]->setTitle(tr("Counters (yellow)")); - cardCounterMenus[2]->setTitle(tr("Counters (green)")); - for (int i = 0; i < aAddCounter.size(); ++i) - aAddCounter[i]->setText(tr("&Add counter")); - for (int i = 0; i < aRemoveCounter.size(); ++i) - aRemoveCounter[i]->setText(tr("&Remove counter")); - for (int i = 0; i < aSetCounter.size(); ++i) - aSetCounter[i]->setText(tr("&Set counters...")); - 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")); + aCardMenu->setText(tr("C&ard")); } + + QMapIterator zoneIterator(zones); + while (zoneIterator.hasNext()) + zoneIterator.next().value()->retranslateUi(); } void Player::initSayMenu() @@ -508,14 +425,15 @@ void Player::actCreateToken() lastTokenColor = dlg.getColor(); lastTokenPT = dlg.getPT(); lastTokenAnnotation = dlg.getAnnotation(); + lastTokenDestroy = dlg.getDestroy(); aCreateAnotherToken->setEnabled(true); - sendGameCommand(new Command_CreateToken(-1, "table", dlg.getName(), dlg.getColor(), dlg.getPT(), dlg.getAnnotation(), -1, 0)); + sendGameCommand(new Command_CreateToken(-1, "table", dlg.getName(), dlg.getColor(), dlg.getPT(), dlg.getAnnotation(), dlg.getDestroy(), -1, 0)); } void Player::actCreateAnotherToken() { - sendGameCommand(new Command_CreateToken(-1, "table", lastTokenName, lastTokenColor, lastTokenPT, lastTokenAnnotation, -1, 0)); + sendGameCommand(new Command_CreateToken(-1, "table", lastTokenName, lastTokenColor, lastTokenPT, lastTokenAnnotation, lastTokenDestroy, -1, 0)); } void Player::actSayMessage() @@ -591,6 +509,7 @@ void Player::eventCreateToken(Event_CreateToken *event) card->setColor(event->getColor()); card->setPT(event->getPt()); card->setAnnotation(event->getAnnotation()); + card->setDestroyOnZoneChange(event->getDestroyOnZoneChange()); emit logCreateToken(this, card->getName(), card->getPT()); zone->addCard(card, true, event->getX(), event->getY()); @@ -732,6 +651,21 @@ void Player::eventMoveCard(Event_MoveCard *event) } } +void Player::eventDestroyCard(Event_DestroyCard *event) +{ + CardZone *zone = zones.value(event->getZone(), 0); + if (!zone) + return; + + CardItem *card = zone->getCard(event->getCardId(), QString()); + if (!card) + return; + + emit logDestroyCard(this, card->getName()); + zone->takeCard(-1, event->getCardId(), QString(), true); + delete card; +} + void Player::eventDrawCards(Event_DrawCards *event) { CardZone *deck = zones.value("deck"); @@ -766,6 +700,7 @@ void Player::processGameEvent(GameEvent *event, GameEventContext *context) case ItemId_Event_DumpZone: eventDumpZone(qobject_cast(event)); break; case ItemId_Event_StopDumpZone: eventStopDumpZone(qobject_cast(event)); break; case ItemId_Event_MoveCard: eventMoveCard(qobject_cast(event)); break; + case ItemId_Event_DestroyCard: eventDestroyCard(qobject_cast(event)); break; case ItemId_Event_DrawCards: eventDrawCards(qobject_cast(event)); break; default: { qDebug() << "unhandled game event"; @@ -773,12 +708,6 @@ void Player::processGameEvent(GameEvent *event, GameEventContext *context) } } -void Player::showCardMenu(const QPoint &p) -{ - if (cardMenu) - cardMenu->exec(p); -} - void Player::setActive(bool _active) { active = _active; @@ -978,36 +907,49 @@ void Player::sendCommandContainer(CommandContainer *cont) void Player::cardMenuAction() { - // Determine the appropriate handler function. - CardMenuHandler handler = cardMenuHandlers.value(static_cast(sender())); - - // The list of selected items is randomly shuffled. + QAction *a = static_cast(sender()); QList sel = scene()->selectedItems(); while (!sel.isEmpty()) { unsigned int i = (unsigned int) (((double) sel.size()) * qrand() / (RAND_MAX + 1.0)); CardItem *card = qgraphicsitem_cast(sel.takeAt(i)); - // For each item, the handler function is called. - (this->*handler)(card); + + switch (a->data().toInt()) { + case 0: + if (!card->getTapped()) + sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "tapped", "1")); + break; + case 1: + if (card->getTapped()) + sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "tapped", "0")); + break; + case 2: + sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "doesnt_untap", QString::number(!card->getDoesntUntap()))); + break; + case 3: { + QString zone = qgraphicsitem_cast(card->parentItem())->getName(); + sendGameCommand(new Command_MoveCard(-1, zone, card->getId(), zone, card->getGridPoint().x(), card->getGridPoint().y(), !card->getFaceDown())); + break; + } + case 4: + sendGameCommand(new Command_CreateToken(-1, static_cast(card->parentItem())->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), -1, card->getGridPoint().y())); + break; + case 5: + sendGameCommand(new Command_MoveCard(-1, static_cast(card->parentItem())->getName(), card->getId(), "deck", 0, 0, false)); + break; + case 6: + sendGameCommand(new Command_MoveCard(-1, static_cast(card->parentItem())->getName(), card->getId(), "deck", -1, 0, false)); + break; + case 7: + sendGameCommand(new Command_MoveCard(-1, static_cast(card->parentItem())->getName(), card->getId(), "grave", 0, 0, false)); + break; + case 8: + sendGameCommand(new Command_MoveCard(-1, static_cast(card->parentItem())->getName(), card->getId(), "rfg", 0, 0, false)); + break; + default: ; + } } } -void Player::actTap(CardItem *card) -{ - if (!card->getTapped()) - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "tapped", "1")); -} - -void Player::actUntap(CardItem *card) -{ - if (card->getTapped()) - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "tapped", "0")); -} - -void Player::actDoesntUntap(CardItem *card) -{ - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "doesnt_untap", QString::number(!card->getDoesntUntap()))); -} - void Player::actSetPT() { QString oldPT; @@ -1051,67 +993,64 @@ void Player::actSetAnnotation() } } -void Player::actFlip(CardItem *card) +void Player::actAttach() { - QString zone = qgraphicsitem_cast(card->parentItem())->getName(); - sendGameCommand(new Command_MoveCard(-1, zone, card->getId(), zone, card->getGridPoint().x(), card->getGridPoint().y(), !card->getFaceDown())); } -void Player::actCardCounterTrigger(QAction *a) +void Player::actUnattach() { - QMenu *menu = static_cast(sender()); - int counterId = cardCounterMenus.indexOf(menu); +} + +void Player::actCardCounterTrigger() +{ + QAction *a = static_cast(sender()); - if (aAddCounter.contains(a)) { - QListIterator i(scene()->selectedItems()); - while (i.hasNext()) { - CardItem *card = static_cast(i.next()); - if (card->getCounters().value(counterId, 0) < MAX_COUNTERS_ON_CARD) - sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) + 1)); + int counterId = a->data().toInt() / 1000; + int action = a->data().toInt() % 1000; + switch (action) { + case 9: { + QListIterator i(scene()->selectedItems()); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + if (card->getCounters().value(counterId, 0) < MAX_COUNTERS_ON_CARD) + sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) + 1)); + } + break; } - } else if (aRemoveCounter.contains(a)) { - QListIterator i(scene()->selectedItems()); - while (i.hasNext()) { - CardItem *card = static_cast(i.next()); - if (card->getCounters().value(counterId, 0)) - sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) - 1)); + case 10: { + QListIterator i(scene()->selectedItems()); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + if (card->getCounters().value(counterId, 0)) + sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) - 1)); + } + break; } - } else if (aSetCounter.contains(a)) { - bool ok; - int number = QInputDialog::getInteger(0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok); - if (!ok) - return; - - QListIterator i(scene()->selectedItems()); - while (i.hasNext()) { - CardItem *card = static_cast(i.next()); - sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), counterId, number)); + case 11: { + bool ok; + int number = QInputDialog::getInteger(0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok); + if (!ok) + return; + + QListIterator i(scene()->selectedItems()); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), counterId, number)); + } + break; } + default: ; } } -void Player::actMoveToTopLibrary(CardItem *card) +void Player::setCardMenu(QMenu *menu) { - CardZone *startZone = qgraphicsitem_cast(card->parentItem()); - sendGameCommand(new Command_MoveCard(-1, startZone->getName(), card->getId(), "deck", 0, 0, false)); + aCardMenu->setMenu(menu); } -void Player::actMoveToBottomLibrary(CardItem *card) +QMenu *Player::getCardMenu() const { - CardZone *startZone = qgraphicsitem_cast(card->parentItem()); - sendGameCommand(new Command_MoveCard(-1, startZone->getName(), card->getId(), "deck", -1, 0, false)); -} - -void Player::actMoveToGraveyard(CardItem *card) -{ - CardZone *startZone = qgraphicsitem_cast(card->parentItem()); - sendGameCommand(new Command_MoveCard(-1, startZone->getName(), card->getId(), "grave", 0, 0, false)); -} - -void Player::actMoveToExile(CardItem *card) -{ - CardZone *startZone = qgraphicsitem_cast(card->parentItem()); - sendGameCommand(new Command_MoveCard(-1, startZone->getName(), card->getId(), "rfg", 0, 0, false)); + return aCardMenu->menu(); } qreal Player::getMinimumWidth() const diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index a563fa53..3aad6cbc 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -38,6 +38,7 @@ class Event_DelCounter; class Event_DumpZone; class Event_StopDumpZone; class Event_MoveCard; +class Event_DestroyCard; class Event_DrawCards; class Player : public QObject, public QGraphicsItem { @@ -52,6 +53,7 @@ signals: void logCreateToken(Player *player, QString cardName, QString pt); void logDrawCards(Player *player, int number); void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX); + void logDestroyCard(Player *player, QString cardName); void logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue); void logSetTapped(Player *player, QString cardName, bool tapped); void logSetCounter(Player *player, QString counterName, int value, int oldValue); @@ -79,44 +81,35 @@ public slots: void actViewSideboard(); void actSayMessage(); -private slots: + + void actAttach(); + void actUnattach(); void actSetPT(); void actSetAnnotation(); + void cardMenuAction(); + void actCardCounterTrigger(); + +private slots: void updateBgPixmap(); void updateBoundingRect(); - void cardMenuAction(); - void actCardCounterTrigger(QAction *a); void rearrangeZones(); private: - QList cardCounterMenus; - QList aAddCounter, aSetCounter, aRemoveCounter; QMenu *playerMenu, *handMenu, *graveMenu, *rfgMenu, *libraryMenu, *sbMenu, *countersMenu, *sayMenu; QAction *aMoveHandToTopLibrary, *aMoveHandToBottomLibrary, *aMoveHandToGrave, *aMoveHandToRfg, *aMoveGraveToTopLibrary, *aMoveGraveToBottomLibrary, *aMoveGraveToHand, *aMoveGraveToRfg, *aMoveRfgToTopLibrary, *aMoveRfgToBottomLibrary, *aMoveRfgToHand, *aMoveRfgToGrave, *aViewLibrary, *aViewTopCards, *aViewGraveyard, *aViewRfg, *aViewSideboard, *aDrawCard, *aDrawCards, *aMulligan, *aShuffle, - *aUntapAll, *aRollDie, *aCreateToken, *aCreateAnotherToken; + *aUntapAll, *aRollDie, *aCreateToken, *aCreateAnotherToken, + *aCardMenu; typedef void (Player::*CardMenuHandler)(CardItem *card); QHash cardMenuHandlers; - QMenu *cardMenu, *moveMenu; - QAction *aTap, *aUntap, *aDoesntUntap, *aSetPT, *aSetAnnotation, *aFlip, - *aMoveToTopLibrary, *aMoveToBottomLibrary, *aMoveToGraveyard, *aMoveToExile; - - void actTap(CardItem *card); - void actUntap(CardItem *card); - void actDoesntUntap(CardItem *card); - void actFlip(CardItem *card); - void actMoveToTopLibrary(CardItem *card); - void actMoveToBottomLibrary(CardItem *card); - void actMoveToGraveyard(CardItem *card); - void actMoveToExile(CardItem *card); - int defaultNumberTopCards; QString lastTokenName, lastTokenColor, lastTokenPT, lastTokenAnnotation; + bool lastTokenDestroy; QString name; int id; bool active; @@ -152,6 +145,7 @@ private: void eventDumpZone(Event_DumpZone *event); void eventStopDumpZone(Event_StopDumpZone *event); void eventMoveCard(Event_MoveCard *event); + void eventDestroyCard(Event_DestroyCard *event); void eventDrawCards(Event_DrawCards *event); public: static const int counterAreaWidth = 65; @@ -186,7 +180,8 @@ public: const QMap &getZones() const { return zones; } const QMap &getArrows() const { return arrows; } TableZone *getTable() const { return table; } - void showCardMenu(const QPoint &p); + void setCardMenu(QMenu *menu); + QMenu *getCardMenu() const; bool getActive() const { return active; } void setActive(bool _active); diff --git a/common/protocol_datastructures.cpp b/common/protocol_datastructures.cpp index 854a6533..30ca8ec1 100644 --- a/common/protocol_datastructures.cpp +++ b/common/protocol_datastructures.cpp @@ -39,7 +39,7 @@ ServerInfo_CardCounter::ServerInfo_CardCounter(int _id, int _value) insertItem(new SerializableItem_Int("value", _value)); } -ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y, bool _tapped, bool _attacking, const QString &_color, const QString &_pt, const QString &_annotation, const QList &_counters) +ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y, bool _tapped, bool _attacking, const QString &_color, const QString &_pt, const QString &_annotation, bool _destroyOnZoneChange, const QList &_counters) : SerializableItem_Map("card") { insertItem(new SerializableItem_Int("id", _id)); @@ -51,6 +51,7 @@ ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y, insertItem(new SerializableItem_String("color", _color)); insertItem(new SerializableItem_String("pt", _pt)); insertItem(new SerializableItem_String("annotation", _annotation)); + insertItem(new SerializableItem_Bool("destroy_on_zone_change", _destroyOnZoneChange)); for (int i = 0; i < _counters.size(); ++i) itemList.append(_counters[i]); diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index 3e9488ca..950b0275 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -62,7 +62,7 @@ public: class ServerInfo_Card : public SerializableItem_Map { public: - ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, bool _tapped = false, bool _attacking = false, const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), const QList &_counterList = QList()); + ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, bool _tapped = false, bool _attacking = false, const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), bool _destroyOnZoneChange = false, const QList &_counterList = QList()); static SerializableItem *newItem() { return new ServerInfo_Card; } int getId() const { return static_cast(itemMap.value("id"))->getData(); } QString getName() const { return static_cast(itemMap.value("name"))->getData(); } @@ -73,6 +73,7 @@ public: QString getColor() const { return static_cast(itemMap.value("color"))->getData(); } QString getPT() const { return static_cast(itemMap.value("pt"))->getData(); } QString getAnnotation() const { return static_cast(itemMap.value("annotation"))->getData(); } + bool getDestroyOnZoneChange() const { return static_cast(itemMap.value("destroy_on_zone_change"))->getData(); } QList getCounters() const { return typecastItemList(); } }; diff --git a/common/protocol_item_ids.h b/common/protocol_item_ids.h index 3bd76e06..efaaa4f7 100644 --- a/common/protocol_item_ids.h +++ b/common/protocol_item_ids.h @@ -20,45 +20,48 @@ ItemId_Command_Mulligan = 1018, ItemId_Command_RollDie = 1019, ItemId_Command_DrawCards = 1020, ItemId_Command_MoveCard = 1021, -ItemId_Command_CreateToken = 1022, -ItemId_Command_CreateArrow = 1023, -ItemId_Command_DeleteArrow = 1024, -ItemId_Command_SetCardAttr = 1025, -ItemId_Command_SetCardCounter = 1026, -ItemId_Command_IncCardCounter = 1027, -ItemId_Command_ReadyStart = 1028, -ItemId_Command_Concede = 1029, -ItemId_Command_IncCounter = 1030, -ItemId_Command_CreateCounter = 1031, -ItemId_Command_SetCounter = 1032, -ItemId_Command_DelCounter = 1033, -ItemId_Command_NextTurn = 1034, -ItemId_Command_SetActivePhase = 1035, -ItemId_Command_DumpZone = 1036, -ItemId_Command_StopDumpZone = 1037, -ItemId_Event_Say = 1038, -ItemId_Event_Leave = 1039, -ItemId_Event_GameClosed = 1040, -ItemId_Event_Shuffle = 1041, -ItemId_Event_RollDie = 1042, -ItemId_Event_MoveCard = 1043, -ItemId_Event_CreateToken = 1044, -ItemId_Event_DeleteArrow = 1045, -ItemId_Event_SetCardAttr = 1046, -ItemId_Event_SetCardCounter = 1047, -ItemId_Event_SetCounter = 1048, -ItemId_Event_DelCounter = 1049, -ItemId_Event_SetActivePlayer = 1050, -ItemId_Event_SetActivePhase = 1051, -ItemId_Event_DumpZone = 1052, -ItemId_Event_StopDumpZone = 1053, -ItemId_Event_ServerMessage = 1054, -ItemId_Event_GameJoined = 1055, -ItemId_Event_ChatJoinChannel = 1056, -ItemId_Event_ChatLeaveChannel = 1057, -ItemId_Event_ChatSay = 1058, -ItemId_Context_ReadyStart = 1059, -ItemId_Context_Concede = 1060, -ItemId_Context_DeckSelect = 1061, -ItemId_Other = 1062 +ItemId_Command_AttachCard = 1022, +ItemId_Command_CreateToken = 1023, +ItemId_Command_CreateArrow = 1024, +ItemId_Command_DeleteArrow = 1025, +ItemId_Command_SetCardAttr = 1026, +ItemId_Command_SetCardCounter = 1027, +ItemId_Command_IncCardCounter = 1028, +ItemId_Command_ReadyStart = 1029, +ItemId_Command_Concede = 1030, +ItemId_Command_IncCounter = 1031, +ItemId_Command_CreateCounter = 1032, +ItemId_Command_SetCounter = 1033, +ItemId_Command_DelCounter = 1034, +ItemId_Command_NextTurn = 1035, +ItemId_Command_SetActivePhase = 1036, +ItemId_Command_DumpZone = 1037, +ItemId_Command_StopDumpZone = 1038, +ItemId_Event_Say = 1039, +ItemId_Event_Leave = 1040, +ItemId_Event_GameClosed = 1041, +ItemId_Event_Shuffle = 1042, +ItemId_Event_RollDie = 1043, +ItemId_Event_MoveCard = 1044, +ItemId_Event_DestroyCard = 1045, +ItemId_Event_AttachCard = 1046, +ItemId_Event_CreateToken = 1047, +ItemId_Event_DeleteArrow = 1048, +ItemId_Event_SetCardAttr = 1049, +ItemId_Event_SetCardCounter = 1050, +ItemId_Event_SetCounter = 1051, +ItemId_Event_DelCounter = 1052, +ItemId_Event_SetActivePlayer = 1053, +ItemId_Event_SetActivePhase = 1054, +ItemId_Event_DumpZone = 1055, +ItemId_Event_StopDumpZone = 1056, +ItemId_Event_ServerMessage = 1057, +ItemId_Event_GameJoined = 1058, +ItemId_Event_ChatJoinChannel = 1059, +ItemId_Event_ChatLeaveChannel = 1060, +ItemId_Event_ChatSay = 1061, +ItemId_Context_ReadyStart = 1062, +ItemId_Context_Concede = 1063, +ItemId_Context_DeckSelect = 1064, +ItemId_Other = 1065 }; diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 33f32133..a2a7b8d0 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -114,7 +114,16 @@ Command_MoveCard::Command_MoveCard(int _gameId, const QString &_startZone, int _ insertItem(new SerializableItem_Bool("face_down", _faceDown)); insertItem(new SerializableItem_Bool("tapped", _tapped)); } -Command_CreateToken::Command_CreateToken(int _gameId, const QString &_zone, const QString &_cardName, const QString &_color, const QString &_pt, const QString &_annotation, int _x, int _y) +Command_AttachCard::Command_AttachCard(int _gameId, const QString &_startZone, int _cardId, int _targetPlayerId, const QString &_targetZone, int _targetCardId) + : GameCommand("attach_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("target_card_id", _targetCardId)); +} +Command_CreateToken::Command_CreateToken(int _gameId, const QString &_zone, const QString &_cardName, const QString &_color, const QString &_pt, const QString &_annotation, bool _destroy, int _x, int _y) : GameCommand("create_token", _gameId) { insertItem(new SerializableItem_String("zone", _zone)); @@ -122,6 +131,7 @@ Command_CreateToken::Command_CreateToken(int _gameId, const QString &_zone, cons insertItem(new SerializableItem_String("color", _color)); insertItem(new SerializableItem_String("pt", _pt)); insertItem(new SerializableItem_String("annotation", _annotation)); + insertItem(new SerializableItem_Bool("destroy", _destroy)); insertItem(new SerializableItem_Int("x", _x)); insertItem(new SerializableItem_Int("y", _y)); } @@ -257,7 +267,22 @@ Event_MoveCard::Event_MoveCard(int _playerId, int _cardId, const QString &_cardN insertItem(new SerializableItem_Int("new_card_id", _newCardId)); insertItem(new SerializableItem_Bool("face_down", _faceDown)); } -Event_CreateToken::Event_CreateToken(int _playerId, const QString &_zone, int _cardId, const QString &_cardName, const QString &_color, const QString &_pt, const QString &_annotation, int _x, int _y) +Event_DestroyCard::Event_DestroyCard(int _playerId, const QString &_zone, int _cardId) + : GameEvent("destroy_card", _playerId) +{ + insertItem(new SerializableItem_String("zone", _zone)); + insertItem(new SerializableItem_Int("card_id", _cardId)); +} +Event_AttachCard::Event_AttachCard(int _playerId, const QString &_startZone, int _cardId, int _targetPlayerId, const QString &_targetZone, int _targetCardId) + : GameEvent("attach_card", _playerId) +{ + 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("target_card_id", _targetCardId)); +} +Event_CreateToken::Event_CreateToken(int _playerId, const QString &_zone, int _cardId, const QString &_cardName, const QString &_color, const QString &_pt, const QString &_annotation, bool _destroyOnZoneChange, int _x, int _y) : GameEvent("create_token", _playerId) { insertItem(new SerializableItem_String("zone", _zone)); @@ -266,6 +291,7 @@ Event_CreateToken::Event_CreateToken(int _playerId, const QString &_zone, int _c insertItem(new SerializableItem_String("color", _color)); insertItem(new SerializableItem_String("pt", _pt)); insertItem(new SerializableItem_String("annotation", _annotation)); + insertItem(new SerializableItem_Bool("destroy_on_zone_change", _destroyOnZoneChange)); insertItem(new SerializableItem_Int("x", _x)); insertItem(new SerializableItem_Int("y", _y)); } @@ -392,6 +418,7 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("cmdroll_die", Command_RollDie::newItem); itemNameHash.insert("cmddraw_cards", Command_DrawCards::newItem); itemNameHash.insert("cmdmove_card", Command_MoveCard::newItem); + itemNameHash.insert("cmdattach_card", Command_AttachCard::newItem); itemNameHash.insert("cmdcreate_token", Command_CreateToken::newItem); itemNameHash.insert("cmdcreate_arrow", Command_CreateArrow::newItem); itemNameHash.insert("cmddelete_arrow", Command_DeleteArrow::newItem); @@ -414,6 +441,8 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("game_eventshuffle", Event_Shuffle::newItem); itemNameHash.insert("game_eventroll_die", Event_RollDie::newItem); itemNameHash.insert("game_eventmove_card", Event_MoveCard::newItem); + itemNameHash.insert("game_eventdestroy_card", Event_DestroyCard::newItem); + itemNameHash.insert("game_eventattach_card", Event_AttachCard::newItem); itemNameHash.insert("game_eventcreate_token", Event_CreateToken::newItem); itemNameHash.insert("game_eventdelete_arrow", Event_DeleteArrow::newItem); itemNameHash.insert("game_eventset_card_attr", Event_SetCardAttr::newItem); diff --git a/common/protocol_items.dat b/common/protocol_items.dat index afedf792..f1b18eab 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -19,7 +19,8 @@ 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:create_token:s,zone:s,card_name:s,color:s,pt:s,annotation:i,x:i,y +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 2:create_arrow:i,start_player_id:s,start_zone:i,start_card_id:i,target_player_id:s,target_zone:i,target_card_id:c,color 2:delete_arrow:i,arrow_id 2:set_card_attr:s,zone:i,card_id:s,attr_name:s,attr_value @@ -41,7 +42,9 @@ 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:create_token:s,zone:i,card_id:s,card_name:s,color:s,pt:s,annotation:i,x:i,y +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 +3:create_token:s,zone:i,card_id:s,card_name:s,color:s,pt:s,annotation:b,destroy_on_zone_change:i,x:i,y 3:delete_arrow:i,arrow_id 3:set_card_attr:s,zone:i,card_id:s,attr_name:s,attr_value 3:set_card_counter:s,zone:i,card_id:i,counter_id:i,counter_value diff --git a/common/protocol_items.h b/common/protocol_items.h index a8fe773a..aa0483a2 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -179,15 +179,28 @@ public: static SerializableItem *newItem() { return new Command_MoveCard; } int getItemId() const { return ItemId_Command_MoveCard; } }; +class Command_AttachCard : public GameCommand { + Q_OBJECT +public: + Command_AttachCard(int _gameId = -1, const QString &_startZone = QString(), int _cardId = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _targetCardId = -1); + 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 getTargetCardId() const { return static_cast(itemMap.value("target_card_id"))->getData(); }; + static SerializableItem *newItem() { return new Command_AttachCard; } + int getItemId() const { return ItemId_Command_AttachCard; } +}; class Command_CreateToken : public GameCommand { Q_OBJECT public: - Command_CreateToken(int _gameId = -1, const QString &_zone = QString(), const QString &_cardName = QString(), const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), int _x = -1, int _y = -1); + Command_CreateToken(int _gameId = -1, const QString &_zone = QString(), const QString &_cardName = QString(), const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), bool _destroy = false, int _x = -1, int _y = -1); QString getZone() const { return static_cast(itemMap.value("zone"))->getData(); }; QString getCardName() const { return static_cast(itemMap.value("card_name"))->getData(); }; QString getColor() const { return static_cast(itemMap.value("color"))->getData(); }; QString getPt() const { return static_cast(itemMap.value("pt"))->getData(); }; QString getAnnotation() const { return static_cast(itemMap.value("annotation"))->getData(); }; + bool getDestroy() const { return static_cast(itemMap.value("destroy"))->getData(); }; int getX() const { return static_cast(itemMap.value("x"))->getData(); }; int getY() const { return static_cast(itemMap.value("y"))->getData(); }; static SerializableItem *newItem() { return new Command_CreateToken; } @@ -388,16 +401,38 @@ public: static SerializableItem *newItem() { return new Event_MoveCard; } int getItemId() const { return ItemId_Event_MoveCard; } }; +class Event_DestroyCard : public GameEvent { + Q_OBJECT +public: + Event_DestroyCard(int _playerId = -1, const QString &_zone = QString(), int _cardId = -1); + QString getZone() const { return static_cast(itemMap.value("zone"))->getData(); }; + int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; + static SerializableItem *newItem() { return new Event_DestroyCard; } + int getItemId() const { return ItemId_Event_DestroyCard; } +}; +class Event_AttachCard : public GameEvent { + Q_OBJECT +public: + Event_AttachCard(int _playerId = -1, const QString &_startZone = QString(), int _cardId = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _targetCardId = -1); + 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 getTargetCardId() const { return static_cast(itemMap.value("target_card_id"))->getData(); }; + static SerializableItem *newItem() { return new Event_AttachCard; } + int getItemId() const { return ItemId_Event_AttachCard; } +}; class Event_CreateToken : public GameEvent { Q_OBJECT public: - Event_CreateToken(int _playerId = -1, const QString &_zone = QString(), int _cardId = -1, const QString &_cardName = QString(), const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), int _x = -1, int _y = -1); + Event_CreateToken(int _playerId = -1, const QString &_zone = QString(), int _cardId = -1, const QString &_cardName = QString(), const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), bool _destroyOnZoneChange = false, int _x = -1, int _y = -1); QString getZone() const { return static_cast(itemMap.value("zone"))->getData(); }; int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; QString getCardName() const { return static_cast(itemMap.value("card_name"))->getData(); }; QString getColor() const { return static_cast(itemMap.value("color"))->getData(); }; QString getPt() const { return static_cast(itemMap.value("pt"))->getData(); }; QString getAnnotation() const { return static_cast(itemMap.value("annotation"))->getData(); }; + bool getDestroyOnZoneChange() const { return static_cast(itemMap.value("destroy_on_zone_change"))->getData(); }; int getX() const { return static_cast(itemMap.value("x"))->getData(); }; int getY() const { return static_cast(itemMap.value("y"))->getData(); }; static SerializableItem *newItem() { return new Event_CreateToken; } diff --git a/common/server_card.cpp b/common/server_card.cpp index a82a8539..f627baa0 100644 --- a/common/server_card.cpp +++ b/common/server_card.cpp @@ -20,7 +20,7 @@ #include "server_card.h" Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y) - : id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), pt(QString()), annotation(QString()), doesntUntap(false) + : id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), pt(QString()), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) { } @@ -39,6 +39,7 @@ void Server_Card::resetState() setColor(QString()); setPT(QString()); setAnnotation(QString()); + setDestroyOnZoneChange(false); setDoesntUntap(false); } diff --git a/common/server_card.h b/common/server_card.h index 1edeefee..a22ffcff 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -38,7 +38,10 @@ private: QString color; QString pt; QString annotation; + bool destroyOnZoneChange; bool doesntUntap; + + Server_Card *parentCard; public: Server_Card(QString _name, int _id, int _coord_x, int _coord_y); ~Server_Card(); @@ -59,6 +62,8 @@ public: QString getPT() const { return pt; } QString getAnnotation() const { return annotation; } bool getDoesntUntap() const { return doesntUntap; } + bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } + Server_Card *getParentCard() const { return parentCard; } void setId(int _id) { id = _id; } void setCoords(int x, int y) { coord_x = x; coord_y = y; } @@ -70,7 +75,9 @@ public: void setColor(const QString &_color) { color = _color; } void setPT(const QString &_pt) { pt = _pt; } void setAnnotation(const QString &_annotation) { annotation = _annotation; } + void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } + void setParentCard(Server_Card *_parentCard) { parentCard = _parentCard; } void resetState(); bool setAttribute(const QString &aname, const QString &avalue, bool allCards); diff --git a/common/server_game.cpp b/common/server_game.cpp index 5eb620d0..058a5044 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -283,7 +283,7 @@ QList Server_Game::getGameState(Server_Player *playerWhosAs cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value())); } - cardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), cardCounterList)); + cardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), cardCounterList)); } } zoneList.append(new ServerInfo_Zone(zone->getName(), zone->getType(), zone->hasCoords(), zone->cards.size(), cardList)); diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 4d69a999..9832ae86 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -95,6 +95,7 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm case ItemId_Command_RollDie: return cmdRollDie(qobject_cast(command), cont, game, player); case ItemId_Command_DrawCards: return cmdDrawCards(qobject_cast(command), cont, game, player); case ItemId_Command_MoveCard: return cmdMoveCard(qobject_cast(command), cont, game, player); + case ItemId_Command_AttachCard: return cmdAttachCard(qobject_cast(command), cont, game, player); case ItemId_Command_CreateToken: return cmdCreateToken(qobject_cast(command), cont, game, player); case ItemId_Command_CreateArrow: return cmdCreateArrow(qobject_cast(command), cont, game, player); case ItemId_Command_DeleteArrow: return cmdDeleteArrow(qobject_cast(command), cont, game, player); @@ -515,6 +516,13 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player * Server_Card *card = startzone->getCard(_cardId, true, &position); if (!card) return RespNameNotFound; + + if (card->getDestroyOnZoneChange() && (startzone != targetzone)) { + cont->enqueueGameEventPrivate(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); + cont->enqueueGameEventPublic(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); + return RespOk; + } + if (!targetzone->hasCoords()) { y = 0; if (x == -1) @@ -601,6 +609,40 @@ ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandC return moveCard(game, player, cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped()); } +ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) +{ + if (player->getSpectator()) + return RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return RespGameNotStarted; + + Server_CardZone *startzone = player->getZones().value(cmd->getStartZone()); + if (!startzone) + return RespNameNotFound; + + Server_Card *card = startzone->getCard(cmd->getCardId(), false); + if (!card) + return RespNameNotFound; + + Server_Player *targetPlayer = game->getPlayer(cmd->getTargetPlayerId()); + if (!targetPlayer) + return RespNameNotFound; + + Server_CardZone *targetzone = targetPlayer->getZones().value(cmd->getTargetZone()); + if (!targetzone) + return RespNameNotFound; + + Server_Card *targetCard = targetzone->getCard(cmd->getTargetCardId(), false); + if (!targetCard) + return RespNameNotFound; + + card->setParentCard(targetCard); + cont->enqueueGameEventPrivate(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId()); + cont->enqueueGameEventPublic(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId()); + return RespOk; +} + ResponseCode Server_ProtocolHandler::cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { if (player->getSpectator()) @@ -626,9 +668,10 @@ ResponseCode Server_ProtocolHandler::cmdCreateToken(Command_CreateToken *cmd, Co card->setPT(cmd->getPt()); card->setColor(cmd->getColor()); card->setAnnotation(cmd->getAnnotation()); + card->setDestroyOnZoneChange(cmd->getDestroy()); zone->insertCard(card, x, y); - game->sendGameEvent(new Event_CreateToken(player->getPlayerId(), zone->getName(), card->getId(), card->getName(), cmd->getColor(), cmd->getPt(), cmd->getAnnotation(), x, y)); + game->sendGameEvent(new Event_CreateToken(player->getPlayerId(), zone->getName(), card->getId(), card->getName(), cmd->getColor(), cmd->getPt(), cmd->getAnnotation(), cmd->getDestroy(), x, y)); return RespOk; } @@ -901,7 +944,7 @@ ResponseCode Server_ProtocolHandler::cmdDumpZone(Command_DumpZone *cmd, CommandC cardCounterIterator.next(); cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value())); } - respCardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), cardCounterList)); + respCardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), cardCounterList)); } } if (zone->getType() == HiddenZone) { diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 012c4039..74704b1b 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -61,6 +61,7 @@ private: ResponseCode cmdDrawCards(Command_DrawCards *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode moveCard(Server_Game *game, Server_Player *player, CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped); ResponseCode cmdMoveCard(Command_MoveCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); + ResponseCode cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdDeleteArrow(Command_DeleteArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);