From df7bcf179df5c1a5fed8c889816e0aa2cf1e4962 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Thu, 17 Jun 2010 20:13:27 +0200 Subject: [PATCH] set p/t, set annotation, multiple counters per card --- cockatrice/src/abstractgraphicsitem.cpp | 30 +- cockatrice/src/abstractgraphicsitem.h | 2 +- cockatrice/src/carditem.cpp | 53 +++- cockatrice/src/carditem.h | 9 +- cockatrice/src/handcounter.cpp | 2 +- cockatrice/src/messagelogwidget.cpp | 36 ++- cockatrice/src/messagelogwidget.h | 4 +- cockatrice/src/pilezone.cpp | 2 +- cockatrice/src/player.cpp | 169 ++++++++--- cockatrice/src/player.h | 17 +- cockatrice/src/window_deckeditor.cpp | 2 +- cockatrice/translations/cockatrice_de.ts | 333 ++++++++++++++-------- cockatrice/translations/cockatrice_en.ts | 347 ++++++++++++++--------- common/protocol.cpp | 1 + common/protocol_datastructures.cpp | 14 +- common/protocol_datastructures.h | 13 +- common/protocol_item_ids.h | 71 ++--- common/protocol_items.cpp | 27 ++ common/protocol_items.dat | 3 + common/protocol_items.h | 33 +++ common/server_card.cpp | 23 +- common/server_card.h | 11 +- common/server_game.cpp | 10 +- common/server_protocolhandler.cpp | 62 +++- common/server_protocolhandler.h | 2 + 25 files changed, 891 insertions(+), 385 deletions(-) diff --git a/cockatrice/src/abstractgraphicsitem.cpp b/cockatrice/src/abstractgraphicsitem.cpp index ca815613..b83b0834 100644 --- a/cockatrice/src/abstractgraphicsitem.cpp +++ b/cockatrice/src/abstractgraphicsitem.cpp @@ -1,33 +1,45 @@ #include "abstractgraphicsitem.h" #include -void AbstractGraphicsItem::paintNumberEllipse(int number, QPainter *painter) +void AbstractGraphicsItem::paintNumberEllipse(int number, int fontSize, const QColor &color, int position, QPainter *painter) { painter->save(); QString numStr = QString::number(number); QFont font("Serif"); - font.setPixelSize(32); + font.setPixelSize(fontSize); font.setWeight(QFont::Bold); QFontMetrics fm(font); - double w = fm.width(numStr) * 1.5; - double h = fm.height() * 1.5; + double w = fm.width(numStr) * 1.3; + double h = fm.height() * 1.3; if (w < h) w = h; painter->setPen(QColor(255, 255, 255, 0)); QRadialGradient grad(QPointF(0.5, 0.5), 0.5); grad.setCoordinateMode(QGradient::ObjectBoundingMode); - grad.setColorAt(0, QColor(255, 255, 255, 200)); - grad.setColorAt(0.7, QColor(255, 255, 255, 200)); - grad.setColorAt(1, QColor(255, 255, 255, 0)); + QColor color1(color), color2(color); + color1.setAlpha(255); + color2.setAlpha(0); + grad.setColorAt(0, color1); + grad.setColorAt(0.8, color1); + grad.setColorAt(1, color2); painter->setBrush(QBrush(grad)); - painter->drawEllipse(QRectF((boundingRect().width() - w) / 2.0, (boundingRect().height() - h) / 2.0, w, h)); + + QRectF textRect; + if (position == -1) + textRect = QRectF((boundingRect().width() - w) / 2.0, (boundingRect().height() - h) / 2.0, w, h); + else { + qreal offset = boundingRect().width() / 20.0; + textRect = QRectF(offset, offset * (position + 1) + h * position, w, h); + } + + painter->drawEllipse(textRect); painter->setPen(Qt::black); painter->setFont(font); - painter->drawText(boundingRect(), Qt::AlignCenter, numStr); + painter->drawText(textRect, Qt::AlignCenter, numStr); painter->restore(); } diff --git a/cockatrice/src/abstractgraphicsitem.h b/cockatrice/src/abstractgraphicsitem.h index af5d9550..3598b1a1 100644 --- a/cockatrice/src/abstractgraphicsitem.h +++ b/cockatrice/src/abstractgraphicsitem.h @@ -5,7 +5,7 @@ class AbstractGraphicsItem : public QGraphicsItem { protected: - void paintNumberEllipse(int number, QPainter *painter); + void paintNumberEllipse(int number, int radius, const QColor &color, int position, QPainter *painter); public: AbstractGraphicsItem(QGraphicsItem *parent = 0) : QGraphicsItem(parent) { } }; diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index 923a2dc9..4c7f164c 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -12,7 +12,7 @@ #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), counters(0), doesntUntap(false), beingPointedAt(false), dragItem(NULL) + : AbstractCardItem(_name, parent), owner(_owner), id(_cardid), attacking(false), facedown(false), doesntUntap(false), beingPointedAt(false), dragItem(NULL) { owner->addCard(this); } @@ -26,8 +26,29 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, { painter->save(); AbstractCardItem::paint(painter, option, widget); - if (counters) - paintNumberEllipse(counters, painter); + + int i = 0; + QMapIterator counterIterator(counters); + while (counterIterator.hasNext()) { + counterIterator.next(); + QColor color; + color.setHsv(counterIterator.key() * 60, 150, 255); + + paintNumberEllipse(counterIterator.value(), 14, color, i, painter); + ++i; + } + if (!pt.isEmpty()) { + QFont font("Serif"); + font.setPixelSize(16); + painter->setFont(font); + QPen pen(Qt::white); + QBrush brush(Qt::black); + painter->setBackground(brush); + painter->setBackgroundMode(Qt::OpaqueMode); + painter->setPen(pen); + + painter->drawText(QRectF(0, 0, boundingRect().width() - 5, boundingRect().height() - 5), Qt::AlignRight | Qt::AlignBottom, pt); + } if (beingPointedAt) painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100))); painter->restore(); @@ -47,15 +68,19 @@ void CardItem::setFaceDown(bool _facedown) update(); } -void CardItem::setCounters(int _counters) +void CardItem::setCounter(int _id, int _value) { - counters = _counters; + if (_value) + counters.insert(_id, _value); + else + counters.remove(_id); update(); } void CardItem::setAnnotation(const QString &_annotation) { annotation = _annotation; + setToolTip(annotation); update(); } @@ -64,6 +89,12 @@ void CardItem::setDoesntUntap(bool _doesntUntap) doesntUntap = _doesntUntap; } +void CardItem::setPT(const QString &_pt) +{ + pt = _pt; + update(); +} + void CardItem::setBeingPointedAt(bool _beingPointedAt) { beingPointedAt = _beingPointedAt; @@ -74,8 +105,9 @@ void CardItem::resetState() { attacking = false; facedown = false; - counters = 0; - annotation = QString(); + counters.clear(); + pt.clear(); + annotation.clear(); setTapped(false); setDoesntUntap(false); update(); @@ -83,10 +115,15 @@ void CardItem::resetState() void CardItem::processCardInfo(ServerInfo_Card *info) { + counters.clear(); + const QList &_counterList = info->getCounters(); + for (int i = 0; i < _counterList.size(); ++i) + counters.insert(_counterList[i]->getId(), _counterList[i]->getValue()); + setId(info->getId()); setName(info->getName()); setAttacking(info->getAttacking()); - setCounters(info->getCounters()); + setPT(info->getPT()); setAnnotation(info->getAnnotation()); setTapped(info->getTapped()); } diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index aff13291..fe3afeac 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -18,8 +18,9 @@ private: int id; bool attacking; bool facedown; - int counters; + QMap counters; QString annotation; + QString pt; bool doesntUntap; QPoint gridPoint; bool beingPointedAt; @@ -42,12 +43,14 @@ public: void setAttacking(bool _attacking); bool getFaceDown() const { return facedown; } void setFaceDown(bool _facedown); - int getCounters() const { return counters; } - void setCounters(int _counters); + const QMap &getCounters() const { return counters; } + void setCounter(int _id, int _value); QString getAnnotation() const { return annotation; } void setAnnotation(const QString &_annotation); bool getDoesntUntap() const { return doesntUntap; } void setDoesntUntap(bool _doesntUntap); + QString getPT() const { return pt; } + void setPT(const QString &_pt); void setBeingPointedAt(bool _beingPointedAt); void resetState(); void processCardInfo(ServerInfo_Card *info); diff --git a/cockatrice/src/handcounter.cpp b/cockatrice/src/handcounter.cpp index dbc85a30..a0e1c415 100644 --- a/cockatrice/src/handcounter.cpp +++ b/cockatrice/src/handcounter.cpp @@ -34,5 +34,5 @@ QRectF HandCounter::boundingRect() const void HandCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { painter->drawPixmap(handImage->rect(), *handImage, handImage->rect()); - paintNumberEllipse(number, painter); + paintNumberEllipse(number, 24, Qt::white, -1, painter); } diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index ffa7b35d..3f546c81 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -218,14 +218,24 @@ void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QStri ); } -void MessageLogWidget::logSetCardCounters(Player *player, QString cardName, int value, int oldValue) +void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue) { - QString finalStr; + QString finalStr, colorStr; + + int delta = abs(oldValue - value); if (value > oldValue) - finalStr = tr("%1 places %2 counters on %3 (now %4)."); + finalStr = tr("%1 places %n counter(s) (%2) on %3 (now %4).", "", delta); else - finalStr = tr("%1 removes %2 counters from %3 (now %4)."); - append(finalStr.arg(sanitizeHtml(player->getName())).arg(abs(oldValue - value)).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(value)); + finalStr = tr("%1 removes %n counter(s) (%2) from %3 (now %4).", "", delta); + + switch (counterId) { + case 0: colorStr = tr("red"); break; + case 1: colorStr = tr("yellow"); break; + case 2: colorStr = tr("green"); break; + default: ; + } + + append(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(value)); } void MessageLogWidget::logSetTapped(Player *player, QString cardName, bool tapped) @@ -240,7 +250,7 @@ void MessageLogWidget::logSetTapped(Player *player, QString cardName, bool tappe void MessageLogWidget::logSetCounter(Player *player, QString counterName, int value, int oldValue) { - append(tr("%1 sets counter \"%2\" to %3 (%4%5).").arg(sanitizeHtml(player->getName())).arg(counterName).arg(value).arg(value > oldValue ? "+" : "").arg(value - oldValue)); + append(tr("%1 sets counter %2 to %3 (%4%5).").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(counterName))).arg(QString("%1").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue)); } void MessageLogWidget::logSetDoesntUntap(Player *player, QString cardName, bool doesntUntap) @@ -253,6 +263,16 @@ void MessageLogWidget::logSetDoesntUntap(Player *player, QString cardName, bool append(finalStr.arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName)))); } +void MessageLogWidget::logSetPT(Player *player, QString cardName, QString newPT) +{ + append(tr("%1 sets PT of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(QString("%1").arg(sanitizeHtml(newPT)))); +} + +void MessageLogWidget::logSetAnnotation(Player *player, QString cardName, QString newAnnotation) +{ + append(tr("%1 sets annotation of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("%1").arg(sanitizeHtml(cardName))).arg(QString("%1").arg(sanitizeHtml(newAnnotation)))); +} + void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards) { if (numberCards != -1) @@ -301,9 +321,11 @@ void MessageLogWidget::connectToPlayer(Player *player) connect(player, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString)), this, SLOT(logCreateArrow(Player *, Player *, QString, Player *, QString))); connect(player, SIGNAL(logCreateToken(Player *, QString)), this, SLOT(logCreateToken(Player *, QString))); connect(player, SIGNAL(logSetCounter(Player *, QString, int, int)), this, SLOT(logSetCounter(Player *, QString, int, int))); - connect(player, SIGNAL(logSetCardCounters(Player *, QString, int, int)), this, SLOT(logSetCardCounters(Player *, QString, int, int))); + connect(player, SIGNAL(logSetCardCounter(Player *, QString, int, int, int)), this, SLOT(logSetCardCounter(Player *, QString, int, int, int))); connect(player, SIGNAL(logSetTapped(Player *, QString, bool)), this, SLOT(logSetTapped(Player *, QString, bool))); connect(player, SIGNAL(logSetDoesntUntap(Player *, QString, bool)), this, SLOT(logSetDoesntUntap(Player *, QString, bool))); + 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(logDumpZone(Player *, CardZone *, int)), this, SLOT(logDumpZone(Player *, CardZone *, int))); connect(player, SIGNAL(logStopDumpZone(Player *, CardZone *)), this, SLOT(logStopDumpZone(Player *, CardZone *))); diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index 90557d04..1e51c85c 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -41,10 +41,12 @@ public slots: void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX); void logCreateToken(Player *player, QString cardName); void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard); - void logSetCardCounters(Player *player, QString cardName, int value, int oldValue); + 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); void logSetDoesntUntap(Player *player, QString cardName, bool doesntUntap); + void logSetPT(Player *player, QString cardName, QString newPT); + void logSetAnnotation(Player *player, QString cardName, QString newAnnotation); void logDumpZone(Player *player, CardZone *zone, int numberCards); void logStopDumpZone(Player *player, CardZone *zone); void logSetActivePlayer(Player *player); diff --git a/cockatrice/src/pilezone.cpp b/cockatrice/src/pilezone.cpp index 6293571c..9d1334b0 100644 --- a/cockatrice/src/pilezone.cpp +++ b/cockatrice/src/pilezone.cpp @@ -28,7 +28,7 @@ void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->restore(); } - paintNumberEllipse(cards.size(), painter); + paintNumberEllipse(cards.size(), 32, Qt::white, -1, painter); painter->drawRect(QRectF(0.5, 0.5, CARD_WIDTH - 1, CARD_HEIGHT - 1)); } diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index eb7dd039..f914b8ba 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -198,26 +198,43 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG 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); - aAddCounter = new QAction(this); - aRemoveCounter = new QAction(this); - aSetCounters = new QAction(this); - connect(aSetCounters, SIGNAL(triggered()), this, SLOT(actSetCounters())); 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(); - cardMenu->addAction(aAddCounter); - cardMenu->addAction(aRemoveCounter); - cardMenu->addAction(aSetCounters); + for (int i = 0; i < cardCounterMenus.size(); ++i) + cardMenu->addMenu(cardCounterMenus[i]); cardMenu->addSeparator(); moveMenu = cardMenu->addMenu(QString()); @@ -233,8 +250,6 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG cardMenuHandlers.insert(aUntap, &Player::actUntap); cardMenuHandlers.insert(aDoesntUntap, &Player::actDoesntUntap); cardMenuHandlers.insert(aFlip, &Player::actFlip); - cardMenuHandlers.insert(aAddCounter, &Player::actAddCounter); - cardMenuHandlers.insert(aRemoveCounter, &Player::actRemoveCounter); cardMenuHandlers.insert(aMoveToTopLibrary, &Player::actMoveToTopLibrary); cardMenuHandlers.insert(aMoveToBottomLibrary, &Player::actMoveToBottomLibrary); cardMenuHandlers.insert(aMoveToGraveyard, &Player::actMoveToGraveyard); @@ -371,10 +386,18 @@ void Player::retranslateUi() 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")); - aAddCounter->setText(tr("&Add counter")); - aRemoveCounter->setText(tr("&Remove counter")); - aSetCounters->setText(tr("&Set counters...")); + 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")); @@ -492,16 +515,16 @@ void Player::setCardAttrHelper(CardItem *card, const QString &aname, const QStri card->setAttacking(avalue == "1"); else if (aname == "facedown") card->setFaceDown(avalue == "1"); - else if (aname == "counters") { - int value = avalue.toInt(); - emit logSetCardCounters(this, card->getName(), value, card->getCounters()); - card->setCounters(value); - } else if (aname == "annotation") + else if (aname == "annotation") { + emit logSetAnnotation(this, card->getName(), avalue); card->setAnnotation(avalue); - else if (aname == "doesnt_untap") { + } else if (aname == "doesnt_untap") { bool value = (avalue == "1"); emit logSetDoesntUntap(this, card->getName(), value); card->setDoesntUntap(value); + } else if (aname == "pt") { + emit logSetPT(this, card->getName(), avalue); + card->setPT(avalue); } } @@ -571,6 +594,21 @@ void Player::eventSetCardAttr(Event_SetCardAttr *event) } } +void Player::eventSetCardCounter(Event_SetCardCounter *event) +{ + CardZone *zone = zones.value(event->getZone(), 0); + if (!zone) + return; + + CardItem *card = zone->getCard(event->getCardId(), QString()); + if (!card) + return; + + int oldValue = card->getCounters().value(event->getCounterId(), 0); + card->setCounter(event->getCounterId(), event->getCounterValue()); + emit logSetCardCounter(this, card->getName(), event->getCounterId(), event->getCounterValue(), oldValue); +} + void Player::eventCreateCounters(Event_CreateCounters *event) { const QList &eventCounterList = event->getCounterList(); @@ -696,6 +734,7 @@ void Player::processGameEvent(GameEvent *event, GameEventContext *context) case ItemId_Event_DeleteArrow: eventDeleteArrow(qobject_cast(event)); break; case ItemId_Event_CreateToken: eventCreateToken(qobject_cast(event)); break; case ItemId_Event_SetCardAttr: eventSetCardAttr(qobject_cast(event)); break; + case ItemId_Event_SetCardCounter: eventSetCardCounter(qobject_cast(event)); break; case ItemId_Event_CreateCounters: eventCreateCounters(qobject_cast(event)); break; case ItemId_Event_SetCounter: eventSetCounter(qobject_cast(event)); break; case ItemId_Event_DelCounter: eventDelCounter(qobject_cast(event)); break; @@ -944,35 +983,85 @@ 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; + QListIterator i(scene()->selectedItems()); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + if (!card->getPT().isEmpty()) + oldPT = card->getPT(); + } + bool ok; + QString pt = QInputDialog::getText(0, tr("Set power/toughness"), tr("Please enter the new PT:"), QLineEdit::Normal, oldPT, &ok); + if (!ok) + return; + + i.toFront(); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "pt", pt)); + } +} + +void Player::actSetAnnotation() +{ + QString oldAnnotation; + QListIterator i(scene()->selectedItems()); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + if (!card->getAnnotation().isEmpty()) + oldAnnotation = card->getAnnotation(); + } + + bool ok; + QString annotation = QInputDialog::getText(0, tr("Set annotation"), tr("Please enter the new annotation:"), QLineEdit::Normal, oldAnnotation, &ok); + if (!ok) + return; + + i.toFront(); + while (i.hasNext()) { + CardItem *card = static_cast(i.next()); + sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "annotation", annotation)); + } +} + void Player::actFlip(CardItem *card) { 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::actAddCounter(CardItem *card) +void Player::actCardCounterTrigger(QAction *a) { - if (card->getCounters() < MAX_COUNTERS_ON_CARD) - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "counters", QString::number(card->getCounters() + 1))); -} - -void Player::actRemoveCounter(CardItem *card) -{ - if (card->getCounters()) - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "counters", QString::number(card->getCounters() - 1))); -} - -void Player::actSetCounters() -{ - 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 *temp = (CardItem *) i.next(); - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(number))); + QMenu *menu = static_cast(sender()); + int counterId = cardCounterMenus.indexOf(menu); + + 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)); + } + } 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)); + } + } 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)); + } } } diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index e9d4da32..ae69497d 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -31,6 +31,7 @@ class Event_CreateArrows; class Event_DeleteArrow; class Event_CreateToken; class Event_SetCardAttr; +class Event_SetCardCounter; class Event_CreateCounters; class Event_SetCounter; class Event_DelCounter; @@ -51,10 +52,12 @@ signals: void logCreateToken(Player *player, QString cardName); void logDrawCards(Player *player, int number); void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX); - void logSetCardCounters(Player *player, QString cardName, int value, int oldValue); + 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); void logSetDoesntUntap(Player *player, QString cardName, bool doesntUntap); + void logSetPT(Player *player, QString cardName, QString newPT); + void logSetAnnotation(Player *player, QString cardName, QString newAnnotation); void logDumpZone(Player *player, CardZone *zone, int numberCards); void logStopDumpZone(Player *player, CardZone *zone); @@ -76,12 +79,17 @@ public slots: void actSayMessage(); private slots: + void actSetPT(); + void actSetAnnotation(); + void updateBgPixmap(); void updateBoundingRect(); void cardMenuAction(); - void actSetCounters(); + 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, @@ -94,15 +102,13 @@ private: QHash cardMenuHandlers; QMenu *cardMenu, *moveMenu; - QAction *aTap, *aUntap, *aDoesntUntap, *aFlip, *aAddCounter, *aRemoveCounter, *aSetCounters, + 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 actAddCounter(CardItem *card); - void actRemoveCounter(CardItem *card); void actMoveToTopLibrary(CardItem *card); void actMoveToBottomLibrary(CardItem *card); void actMoveToGraveyard(CardItem *card); @@ -137,6 +143,7 @@ private: void eventDeleteArrow(Event_DeleteArrow *event); void eventCreateToken(Event_CreateToken *event); void eventSetCardAttr(Event_SetCardAttr *event); + void eventSetCardCounter(Event_SetCardCounter *event); void eventCreateCounters(Event_CreateCounters *event); void eventSetCounter(Event_SetCounter *event); void eventDelCounter(Event_DelCounter *event); diff --git a/cockatrice/src/window_deckeditor.cpp b/cockatrice/src/window_deckeditor.cpp index 47f079a7..c2f2a228 100644 --- a/cockatrice/src/window_deckeditor.cpp +++ b/cockatrice/src/window_deckeditor.cpp @@ -132,7 +132,7 @@ WndDeckEditor::WndDeckEditor(QWidget *parent) aLoadDeckFromClipboard = new QAction(tr("Load deck from cl&ipboard..."), this); connect(aLoadDeckFromClipboard, SIGNAL(triggered()), this, SLOT(actLoadDeckFromClipboard())); aLoadDeckFromClipboard->setShortcuts(QKeySequence::Paste); - aSaveDeckToClipboard = new QAction(tr("Save deck to cl&ipboard"), this); + aSaveDeckToClipboard = new QAction(tr("Save deck to clip&board"), this); connect(aSaveDeckToClipboard, SIGNAL(triggered()), this, SLOT(actSaveDeckToClipboard())); aSaveDeckToClipboard->setShortcuts(QKeySequence::Copy); aPrintDeck = new QAction(tr("&Print deck..."), this); diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts index d5a51e03..5a99f26c 100644 --- a/cockatrice/translations/cockatrice_de.ts +++ b/cockatrice/translations/cockatrice_de.ts @@ -1574,8 +1574,54 @@ %1 points from %2's %3 to %4's %5. %1 zeigt von %2s %3 auf %4s %5. + + + %1 places %n counter(s) (%2) on %3 (now %4). + + %1 legt eine Marke (%2) auf %3 (jetzt %4). + %1 legt %n Marken (%2) auf %3 (jetzt %4). + + + + + %1 removes %n counter(s) (%2) from %3 (now %4). + + %1 entfernt eine Marke (%2) von %3 (jetzt %4). + %1 entfernt %n Marken (%2) von %3 (jetzt %4). + + - + + red + rot + + + + yellow + gelb + + + + green + grün + + + + %1 sets counter %2 to %3 (%4%5). + %1 setzt Zähler %2 auf %3 (%4%5). + + + + %1 sets PT of %2 to %3. + %1 setzt Kampfwerte von %2 auf %3. + + + + %1 sets annotation of %2 to %3. + %1 versieht %2 mit dem Hinweis %3. + + + %1 is looking at the top %2 cards %3. %1 sieht sich die obersten %2 Karten %3 an. @@ -1665,41 +1711,38 @@ %1 erstellt Token: %2. - %1 places %2 counters on %3 (now %4). - %1 legt %2 Zählmarken auf %3 (jetzt %4). + %1 legt %2 Zählmarken auf %3 (jetzt %4). - %1 removes %2 counters from %3 (now %4). - %1 entfernt %2 Zählmarken von %3 (jetzt %4). + %1 entfernt %2 Zählmarken von %3 (jetzt %4). - + %1 %2 %3. %1 %2 %3. - %1 sets counter "%2" to %3 (%4%5). - %1 setzt Zählmarke "%2" auf %3 (%4%5). + %1 setzt Zählmarke "%2" auf %3 (%4%5). %1 is looking at the top %2 cards of %3. %1 sieht sich die obersten %2 Karten %3 an. - + %1 is looking at %2. %1 sieht sich %2 an. - + %1 stops looking at %2. %1 sieht sich %2 nicht mehr an. - + ending phase die Zugendphase @@ -1728,57 +1771,57 @@ %1 sieht sich %2s %3 nicht mehr an - + It is now %1's turn. %1 ist am Zug. - + untap step das Enttappsegment - + upkeep step das Versorgungssegment - + draw step das Ziehsegment - + first main phase die erste Hauptphase - + beginning of combat step das Anfangssegment der Kampfphase - + declare attackers step das Angreifer-Deklarieren-Segment - + declare blockers step das Blocker-Deklarieren-Segment - + combat damage step das Kampfschadenssegment - + end of combat step das Endsegment der Kampfphase - + second main phase die zweite Hauptphase @@ -1787,7 +1830,7 @@ das Ende-des-Zuges-Segment - + It is now the %1. Es ist nun %1. @@ -1796,12 +1839,12 @@ %1 bewegt %2 %3 nach %4 - + taps tappt - + untaps enttappt @@ -1826,7 +1869,7 @@ %1 entfernt %2 Zählmarken von %3 (jetzt %4) - + his permanents seine bleibenden Karten @@ -1839,12 +1882,12 @@ %1 setzt Zähler "%2" auf %3 (%4%5) - + %1 sets %2 to not untap normally. %1 setzt %2 auf explizites Enttappen. - + %1 sets %2 to untap normally. %1 setzt %2 auf normales Enttappen. @@ -1949,41 +1992,41 @@ Player - - - + + + Move to &top of library Oben auf die Biblio&thek legen - - - + + + Move to &bottom of library Unter die &Bibliothek legen - + &View library &Zeige Bibliothek - + F3 F3 - + View &top cards of library... Zeige die oberen Kar&ten der Bibliothek... - + &View graveyard &Zeige Friedhof - + F4 F4 @@ -1992,32 +2035,32 @@ Zeige ent&fernte Karten - + &View sideboard Zeige &Sideboard - + Player "%1" Spieler "%1" - + Take &mulligan &Mulligan nehmen - + &Hand &Hand - + &Library Bib&liothek - + &Graveyard &Friedhof @@ -2026,70 +2069,80 @@ Entfe&rnte Karten - + &Sideboard &Sideboard - + + Set &P/T... + &Kampfwerte setzen... + + + + &Set annotation... + &Hinweis setzen... + + + View top cards of library Zeige die obersten Karten der Bibliothek - + Number of cards: Anzahl der Karten: - + &Draw card Karte &ziehen - + &View exile &Zeige Exil - + &Exile &Exil - - + + Move to &hand auf die &Hand nehmen - - + + Move to g&raveyard auf den &Friedhof legen - - + + Move to &exile ins &Exil schicken - + Ctrl+W Ctrl+W - + Ctrl+D Ctrl+D - + D&raw cards... Ka&rten ziehen... - + Ctrl+E Ctrl+E @@ -2098,32 +2151,32 @@ &Mulligan nehmen... - + Ctrl+M Ctrl+M - + &Shuffle Mi&schen - + Ctrl+S Ctrl+S - + &Counters &Zähler - + &Untap all permanents &Enttappe alle bleibenden Karten - + Ctrl+U Ctrl+U @@ -2152,97 +2205,112 @@ Ctrl+L - + R&oll die... &Würfeln... - + Ctrl+I Ctrl+I - + &Create token... &Token erstellen... - + Ctrl+T Ctrl+T - + S&ay &Sagen - + C&ard &Karte - + &Tap &Tappen - + &Untap E&nttappen - + Toggle &normal untapping &Normales Enttappen umschalten - + &Flip &Umdrehen - + + Counters (red) + Marken (rot) + + + + Counters (yellow) + Marken (gelb) + + + + Counters (green) + Marken (grün) + + + &Add counter Zählm&arke hinzufügen - + &Remove counter Zählma&rke entfernen - + &Set counters... &Setze Zählmarken... - + &top of library &auf die Bibliothek - + &bottom of library &unter die Bibliothek - + &graveyard in den &Friedhof - + Ctrl+Del Ctrl+Del - + &exile ins &Exil - + &Move to &Verschieben @@ -2271,18 +2339,38 @@ F10 - + Draw cards Karten ziehen - - + + Number: Anzahl: - + + Set power/toughness + Kampfwerte setzen + + + + Please enter the new PT: + Bitte die neuen Kampfwerte eingeben: + + + + Set annotation + Hinweis setzen + + + + Please enter the new annotation: + Bitte den Hinweis eingeben: + + + Set counters Setze Zählmarken @@ -2295,22 +2383,22 @@ Neue Lebenspunkte insgesamt: - + Roll die Würfeln - + Number of sides: Anzahl der Seiten: - + Create token Token erstellen - + Name: Name: @@ -2623,7 +2711,7 @@ Bitte geben Sie einen Namen ein: Sind Sie sicher, dass Sie das Spiel verlassen möchten? - + Load deck Deck laden @@ -2702,7 +2790,7 @@ Bitte geben Sie einen Namen ein: Deck &laden... - + &Save deck Deck &speichern @@ -2711,32 +2799,37 @@ Bitte geben Sie einen Namen ein: Deck &speichern unter... - + Save deck &as... Deck s&peichern unter... - + + Save deck to clip&board + Deck in Z&wischenablage speichern + + + &Print deck... Deck &drucken... - + &Close S&chließen - + Ctrl+Q Ctrl+Q - + &Edit sets... &Editionen bearbeiten... - + &Deck &Deck @@ -2745,27 +2838,27 @@ Bitte geben Sie einen Namen ein: &Editionen - + Add card to &maindeck Karte zu&m Hauptdeck hinzufügen - + Return Return - + Enter Enter - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter @@ -2774,7 +2867,7 @@ Bitte geben Sie einen Namen ein: Ctrl+M - + Add card to &sideboard Karte zum &Sideboard hinzufügen @@ -2793,64 +2886,64 @@ Bitte geben Sie einen Namen ein: Suche a&ufheben - + Load deck from cl&ipboard... Deck aus &Zwischenablage laden... - + &Card database &Kartendatenbank - + &Remove row Zeile entfe&rnen - + Del Entf - + &Increment number Anzahl er&höhen - + + + - + &Decrement number Anzahl v&erringern - + - - - + Are you sure? Bist du sicher? - + The decklist has been modified. Do you want to save the changes? Die Deckliste wurde verändert. Willst du die Änderungen speichern? - + Load deck Deck laden - + Save deck Deck speichern diff --git a/cockatrice/translations/cockatrice_en.ts b/cockatrice/translations/cockatrice_en.ts index 191be320..1a5ca6aa 100644 --- a/cockatrice/translations/cockatrice_en.ts +++ b/cockatrice/translations/cockatrice_en.ts @@ -984,8 +984,54 @@ %1 points from %2's %3 to %4's %5. + + + %1 places %n counter(s) (%2) on %3 (now %4). + + %1 places a counter (%2) on %3 (now %4). + %1 places %n counters (%2) on %3 (now %4). + + + + + %1 removes %n counter(s) (%2) from %3 (now %4). + + %1 removes a counter (%2) from %3 (now %4). + %1 removes %n counters (%2) from %3 (now %4). + + - + + red + + + + + yellow + + + + + green + + + + + %1 sets counter %2 to %3 (%4%5). + + + + + %1 sets PT of %2 to %3. + + + + + %1 sets annotation of %2 to %3. + + + + %1 is looking at the top %2 cards %3. @@ -1055,42 +1101,27 @@ - - %1 places %2 counters on %3 (now %4). - - - - - %1 removes %2 counters from %3 (now %4). - - - - + %1 %2 %3. - - %1 sets counter "%2" to %3 (%4%5). - - - - + %1 is looking at %2. - + %1 stops looking at %2. - + ending phase - + It is now %1's turn. @@ -1100,82 +1131,82 @@ - + untap step - + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + It is now the %1. - + taps - + untaps - + %1 sets %2 to not untap normally. - + %1 sets %2 to untap normally. - + his permanents @@ -1264,300 +1295,345 @@ Player - - - + + + Move to &top of library - - - + + + Move to &bottom of library - + &View library - + F3 - + View &top cards of library... - + &View graveyard - + F4 - + &View sideboard - + Player "%1" - + &Hand - + &Library - + &Graveyard - + &Sideboard - + + Set &P/T... + + + + + &Set annotation... + + + + View top cards of library - + Number of cards: - + &Draw card - + &View exile - + &Exile - - + + Move to &hand - - + + Move to g&raveyard - - + + Move to &exile - + Ctrl+W - + Ctrl+D - + D&raw cards... - + Ctrl+E - + Take &mulligan - + Ctrl+M - + &Shuffle - + Ctrl+S - + &Counters - + &Untap all permanents - + Ctrl+U - + R&oll die... - + Ctrl+I - + &Create token... - + Ctrl+T - + S&ay - + C&ard - + &Tap - + &Untap - + Toggle &normal untapping - + &Flip - + + Counters (red) + + + + + Counters (yellow) + + + + + Counters (green) + + + + &Add counter - + &Remove counter - + &Set counters... - + &top of library - + &bottom of library - + &graveyard - + Ctrl+Del - + &exile - + &Move to - + Draw cards - - + + Number: - + Roll die - + Number of sides: - + Create token - + Name: - + + Set power/toughness + + + + + Please enter the new PT: + + + + + Set annotation + + + + + Please enter the new annotation: + + + + Set counters @@ -1845,7 +1921,7 @@ Please enter a name: - + Load deck @@ -1909,82 +1985,87 @@ Please enter a name: - + Load deck from cl&ipboard... - + &Save deck - + Save deck &as... - - &Print deck... - - - - - &Close + + Save deck to clip&board - Ctrl+Q + &Print deck... + &Close + + + + + Ctrl+Q + + + + &Edit sets... - + &Deck - + Load deck - + Save deck - + Add card to &maindeck - + Return - + Enter - + Ctrl+Return - + Ctrl+Enter - + Add card to &sideboard @@ -1999,47 +2080,47 @@ Please enter a name: - + &Card database - + &Remove row - + Del - + &Increment number - + + - + &Decrement number - + - - + Are you sure? - + The decklist has been modified. Do you want to save the changes? diff --git a/common/protocol.cpp b/common/protocol.cpp index ca8ab0ee..23fd6676 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -18,6 +18,7 @@ void ProtocolItem::initializeHash() registerSerializableItem("chat_channel", ServerInfo_ChatChannel::newItem); registerSerializableItem("chat_user", ServerInfo_ChatUser::newItem); registerSerializableItem("game", ServerInfo_Game::newItem); + registerSerializableItem("card_counter", ServerInfo_CardCounter::newItem); registerSerializableItem("card", ServerInfo_Card::newItem); registerSerializableItem("zone", ServerInfo_Zone::newItem); registerSerializableItem("counter", ServerInfo_Counter::newItem); diff --git a/common/protocol_datastructures.cpp b/common/protocol_datastructures.cpp index 38971f78..92c9a55d 100644 --- a/common/protocol_datastructures.cpp +++ b/common/protocol_datastructures.cpp @@ -32,17 +32,27 @@ ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool insertItem(new SerializableItem_Int("spectator_count", _spectatorCount)); } -ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y, int _counters, bool _tapped, bool _attacking, const QString &_annotation) +ServerInfo_CardCounter::ServerInfo_CardCounter(int _id, int _value) + : SerializableItem_Map("card_counter") +{ + insertItem(new SerializableItem_Int("id", _id)); + 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 &_pt, const QString &_annotation, const QList &_counters) : SerializableItem_Map("card") { insertItem(new SerializableItem_Int("id", _id)); insertItem(new SerializableItem_String("name", _name)); insertItem(new SerializableItem_Int("x", _x)); insertItem(new SerializableItem_Int("y", _y)); - insertItem(new SerializableItem_Int("counters", _counters)); insertItem(new SerializableItem_Bool("tapped", _tapped)); insertItem(new SerializableItem_Bool("attacking", _attacking)); + insertItem(new SerializableItem_String("pt", _pt)); insertItem(new SerializableItem_String("annotation", _annotation)); + + for (int i = 0; i < _counters.size(); ++i) + itemList.append(_counters[i]); } ServerInfo_Zone::ServerInfo_Zone(const QString &_name, ZoneType _type, bool _hasCoords, int _cardCount, const QList &_cardList) diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index 7d331498..3266ecdc 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -52,18 +52,27 @@ public: int getSpectatorCount() const { return static_cast(itemMap.value("spectator_count"))->getData(); } }; +class ServerInfo_CardCounter : public SerializableItem_Map { +public: + ServerInfo_CardCounter(int _id = -1, int _value = 0); + static SerializableItem *newItem() { return new ServerInfo_CardCounter; } + int getId() const { return static_cast(itemMap.value("id"))->getData(); } + int getValue() const { return static_cast(itemMap.value("value"))->getData(); } +}; + class ServerInfo_Card : public SerializableItem_Map { public: - ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, int _counters = -1, bool _tapped = false, bool _attacking = false, const QString &_annotation = QString()); + ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, bool _tapped = false, bool _attacking = false, const QString &_pt = QString(), const QString &_annotation = QString(), 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(); } int getX() const { return static_cast(itemMap.value("x"))->getData(); } int getY() const { return static_cast(itemMap.value("y"))->getData(); } - int getCounters() const { return static_cast(itemMap.value("counters"))->getData(); } bool getTapped() const { return static_cast(itemMap.value("tapped"))->getData(); } bool getAttacking() const { return static_cast(itemMap.value("attacking"))->getData(); } + QString getPT() const { return static_cast(itemMap.value("pt"))->getData(); } QString getAnnotation() const { return static_cast(itemMap.value("annotation"))->getData(); } + QList getCounters() const { return typecastItemList(); } }; class ServerInfo_Zone : public SerializableItem_Map { diff --git a/common/protocol_item_ids.h b/common/protocol_item_ids.h index ebae7e78..3bd76e06 100644 --- a/common/protocol_item_ids.h +++ b/common/protocol_item_ids.h @@ -24,38 +24,41 @@ ItemId_Command_CreateToken = 1022, ItemId_Command_CreateArrow = 1023, ItemId_Command_DeleteArrow = 1024, ItemId_Command_SetCardAttr = 1025, -ItemId_Command_ReadyStart = 1026, -ItemId_Command_Concede = 1027, -ItemId_Command_IncCounter = 1028, -ItemId_Command_CreateCounter = 1029, -ItemId_Command_SetCounter = 1030, -ItemId_Command_DelCounter = 1031, -ItemId_Command_NextTurn = 1032, -ItemId_Command_SetActivePhase = 1033, -ItemId_Command_DumpZone = 1034, -ItemId_Command_StopDumpZone = 1035, -ItemId_Event_Say = 1036, -ItemId_Event_Leave = 1037, -ItemId_Event_GameClosed = 1038, -ItemId_Event_Shuffle = 1039, -ItemId_Event_RollDie = 1040, -ItemId_Event_MoveCard = 1041, -ItemId_Event_CreateToken = 1042, -ItemId_Event_DeleteArrow = 1043, -ItemId_Event_SetCardAttr = 1044, -ItemId_Event_SetCounter = 1045, -ItemId_Event_DelCounter = 1046, -ItemId_Event_SetActivePlayer = 1047, -ItemId_Event_SetActivePhase = 1048, -ItemId_Event_DumpZone = 1049, -ItemId_Event_StopDumpZone = 1050, -ItemId_Event_ServerMessage = 1051, -ItemId_Event_GameJoined = 1052, -ItemId_Event_ChatJoinChannel = 1053, -ItemId_Event_ChatLeaveChannel = 1054, -ItemId_Event_ChatSay = 1055, -ItemId_Context_ReadyStart = 1056, -ItemId_Context_Concede = 1057, -ItemId_Context_DeckSelect = 1058, -ItemId_Other = 1059 +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 }; diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 7f681569..57ac1aeb 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -147,6 +147,22 @@ Command_SetCardAttr::Command_SetCardAttr(int _gameId, const QString &_zone, int insertItem(new SerializableItem_String("attr_name", _attrName)); insertItem(new SerializableItem_String("attr_value", _attrValue)); } +Command_SetCardCounter::Command_SetCardCounter(int _gameId, const QString &_zone, int _cardId, int _counterId, int _counterValue) + : GameCommand("set_card_counter", _gameId) +{ + insertItem(new SerializableItem_String("zone", _zone)); + insertItem(new SerializableItem_Int("card_id", _cardId)); + insertItem(new SerializableItem_Int("counter_id", _counterId)); + insertItem(new SerializableItem_Int("counter_value", _counterValue)); +} +Command_IncCardCounter::Command_IncCardCounter(int _gameId, const QString &_zone, int _cardId, int _counterId, int _counterDelta) + : GameCommand("inc_card_counter", _gameId) +{ + insertItem(new SerializableItem_String("zone", _zone)); + insertItem(new SerializableItem_Int("card_id", _cardId)); + insertItem(new SerializableItem_Int("counter_id", _counterId)); + insertItem(new SerializableItem_Int("counter_delta", _counterDelta)); +} Command_ReadyStart::Command_ReadyStart(int _gameId, bool _ready) : GameCommand("ready_start", _gameId) { @@ -262,6 +278,14 @@ Event_SetCardAttr::Event_SetCardAttr(int _playerId, const QString &_zone, int _c insertItem(new SerializableItem_String("attr_name", _attrName)); insertItem(new SerializableItem_String("attr_value", _attrValue)); } +Event_SetCardCounter::Event_SetCardCounter(int _playerId, const QString &_zone, int _cardId, int _counterId, int _counterValue) + : GameEvent("set_card_counter", _playerId) +{ + insertItem(new SerializableItem_String("zone", _zone)); + insertItem(new SerializableItem_Int("card_id", _cardId)); + insertItem(new SerializableItem_Int("counter_id", _counterId)); + insertItem(new SerializableItem_Int("counter_value", _counterValue)); +} Event_SetCounter::Event_SetCounter(int _playerId, int _counterId, int _value) : GameEvent("set_counter", _playerId) { @@ -368,6 +392,8 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("cmdcreate_arrow", Command_CreateArrow::newItem); itemNameHash.insert("cmddelete_arrow", Command_DeleteArrow::newItem); itemNameHash.insert("cmdset_card_attr", Command_SetCardAttr::newItem); + itemNameHash.insert("cmdset_card_counter", Command_SetCardCounter::newItem); + itemNameHash.insert("cmdinc_card_counter", Command_IncCardCounter::newItem); itemNameHash.insert("cmdready_start", Command_ReadyStart::newItem); itemNameHash.insert("cmdconcede", Command_Concede::newItem); itemNameHash.insert("cmdinc_counter", Command_IncCounter::newItem); @@ -387,6 +413,7 @@ void ProtocolItem::initializeHashAuto() 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); + itemNameHash.insert("game_eventset_card_counter", Event_SetCardCounter::newItem); itemNameHash.insert("game_eventset_counter", Event_SetCounter::newItem); itemNameHash.insert("game_eventdel_counter", Event_DelCounter::newItem); itemNameHash.insert("game_eventset_active_player", Event_SetActivePlayer::newItem); diff --git a/common/protocol_items.dat b/common/protocol_items.dat index 0f511799..1fbb8f86 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -23,6 +23,8 @@ 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 +2:set_card_counter:s,zone:i,card_id:i,counter_id:i,counter_value +2:inc_card_counter:s,zone:i,card_id:i,counter_id:i,counter_delta 2:ready_start:b,ready 2:concede 2:inc_counter:i,counter_id:i,delta @@ -42,6 +44,7 @@ 3:create_token:s,zone:i,card_id:s,card_name:s,pt: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 3:set_counter:i,counter_id:i,value 3:del_counter:i,counter_id 3:set_active_player:i,active_player_id diff --git a/common/protocol_items.h b/common/protocol_items.h index 43d8afd4..94d1a653 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -224,6 +224,28 @@ public: static SerializableItem *newItem() { return new Command_SetCardAttr; } int getItemId() const { return ItemId_Command_SetCardAttr; } }; +class Command_SetCardCounter : public GameCommand { + Q_OBJECT +public: + Command_SetCardCounter(int _gameId = -1, const QString &_zone = QString(), int _cardId = -1, int _counterId = -1, int _counterValue = -1); + QString getZone() const { return static_cast(itemMap.value("zone"))->getData(); }; + int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; + int getCounterId() const { return static_cast(itemMap.value("counter_id"))->getData(); }; + int getCounterValue() const { return static_cast(itemMap.value("counter_value"))->getData(); }; + static SerializableItem *newItem() { return new Command_SetCardCounter; } + int getItemId() const { return ItemId_Command_SetCardCounter; } +}; +class Command_IncCardCounter : public GameCommand { + Q_OBJECT +public: + Command_IncCardCounter(int _gameId = -1, const QString &_zone = QString(), int _cardId = -1, int _counterId = -1, int _counterDelta = -1); + QString getZone() const { return static_cast(itemMap.value("zone"))->getData(); }; + int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; + int getCounterId() const { return static_cast(itemMap.value("counter_id"))->getData(); }; + int getCounterDelta() const { return static_cast(itemMap.value("counter_delta"))->getData(); }; + static SerializableItem *newItem() { return new Command_IncCardCounter; } + int getItemId() const { return ItemId_Command_IncCardCounter; } +}; class Command_ReadyStart : public GameCommand { Q_OBJECT public: @@ -396,6 +418,17 @@ public: static SerializableItem *newItem() { return new Event_SetCardAttr; } int getItemId() const { return ItemId_Event_SetCardAttr; } }; +class Event_SetCardCounter : public GameEvent { + Q_OBJECT +public: + Event_SetCardCounter(int _playerId = -1, const QString &_zone = QString(), int _cardId = -1, int _counterId = -1, int _counterValue = -1); + QString getZone() const { return static_cast(itemMap.value("zone"))->getData(); }; + int getCardId() const { return static_cast(itemMap.value("card_id"))->getData(); }; + int getCounterId() const { return static_cast(itemMap.value("counter_id"))->getData(); }; + int getCounterValue() const { return static_cast(itemMap.value("counter_value"))->getData(); }; + static SerializableItem *newItem() { return new Event_SetCardCounter; } + int getItemId() const { return ItemId_Event_SetCardCounter; } +}; class Event_SetCounter : public GameEvent { Q_OBJECT public: diff --git a/common/server_card.cpp b/common/server_card.cpp index 505c70d4..451dd0f9 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), counters(0), tapped(false), attacking(false), facedown(false), annotation(QString()), doesntUntap(false) + : id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), pt(QString()), annotation(QString()), doesntUntap(false) { } @@ -32,23 +32,18 @@ Server_Card::~Server_Card() void Server_Card::resetState() { setCoords(0, 0); - setCounters(0); + counters.clear(); setTapped(false); setAttacking(false); setFaceDown(false); + setPT(QString()); setAnnotation(QString()); setDoesntUntap(false); } bool Server_Card::setAttribute(const QString &aname, const QString &avalue, bool allCards) { - if (aname == "counters") { - bool ok; - int tmp_int = avalue.toInt(&ok); - if (!ok) - return false; - setCounters(tmp_int); - } else if (aname == "tapped") { + if (aname == "tapped") { bool value = avalue == "1"; if (!(!value && allCards && doesntUntap)) setTapped(value); @@ -56,6 +51,8 @@ bool Server_Card::setAttribute(const QString &aname, const QString &avalue, bool setAttacking(avalue == "1"); } else if (aname == "facedown") { setFaceDown(avalue == "1"); + } else if (aname == "pt") { + setPT(avalue); } else if (aname == "annotation") { setAnnotation(avalue); } else if (aname == "doesnt_untap") { @@ -65,3 +62,11 @@ bool Server_Card::setAttribute(const QString &aname, const QString &avalue, bool return true; } + +void Server_Card::setCounter(int id, int value) +{ + if (value) + counters.insert(id, value); + else + counters.remove(id); +} diff --git a/common/server_card.h b/common/server_card.h index f8090701..0b62780c 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -21,6 +21,7 @@ #define SERVER_CARD_H #include +#include class Server_CardZone; @@ -30,10 +31,11 @@ private: int id; int coord_x, coord_y; QString name; - int counters; + QMap counters; bool tapped; bool attacking; bool facedown; + QString pt; QString annotation; bool doesntUntap; public: @@ -47,20 +49,23 @@ public: int getX() const { return coord_x; } int getY() const { return coord_y; } QString getName() const { return name; } - int getCounters() const { return counters; } + const QMap &getCounters() const { return counters; } + int getCounter(int id) const { return counters.value(id, 0); } bool getTapped() const { return tapped; } bool getAttacking() const { return attacking; } bool getFaceDown() const { return facedown; } + QString getPT() const { return pt; } QString getAnnotation() const { return annotation; } bool getDoesntUntap() const { return doesntUntap; } void setId(int _id) { id = _id; } void setCoords(int x, int y) { coord_x = x; coord_y = y; } void setName(const QString &_name) { name = _name; } - void setCounters(int _counters) { counters = _counters; } + void setCounter(int id, int value); void setTapped(bool _tapped) { tapped = _tapped; } void setAttacking(bool _attacking) { attacking = _attacking; } void setFaceDown(bool _facedown) { facedown = _facedown; } + void setPT(const QString &_pt) { pt = _pt; } void setAnnotation(const QString &_annotation) { annotation = _annotation; } void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } diff --git a/common/server_game.cpp b/common/server_game.cpp index 44a57088..4a8f8b5d 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -275,7 +275,15 @@ QList Server_Game::getGameState(Server_Player *playerWhosAs while (cardIterator.hasNext()) { Server_Card *card = cardIterator.next(); QString displayedName = card->getFaceDown() ? QString() : card->getName(); - cardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getCounters(), card->getTapped(), card->getAttacking(), card->getAnnotation())); + + QList cardCounterList; + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + 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->getPT(), card->getAnnotation(), 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 0d549591..742cdda3 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -99,6 +99,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm case ItemId_Command_CreateArrow: return cmdCreateArrow(qobject_cast(command), cont, game, player); case ItemId_Command_DeleteArrow: return cmdDeleteArrow(qobject_cast(command), cont, game, player); case ItemId_Command_SetCardAttr: return cmdSetCardAttr(qobject_cast(command), cont, game, player); + case ItemId_Command_SetCardCounter: return cmdSetCardCounter(qobject_cast(command), cont, game, player); + case ItemId_Command_IncCardCounter: return cmdIncCardCounter(qobject_cast(command), cont, game, player); case ItemId_Command_IncCounter: return cmdIncCounter(qobject_cast(command), cont, game, player); case ItemId_Command_CreateCounter: return cmdCreateCounter(qobject_cast(command), cont, game, player); case ItemId_Command_SetCounter: return cmdSetCounter(qobject_cast(command), cont, game, player); @@ -682,8 +684,6 @@ ResponseCode Server_ProtocolHandler::setCardAttrHelper(CommandContainer *cont, S if (!game->getGameStarted()) return RespGameNotStarted; - // zone, card id, attr name, attr value - // card id = -1 => affects all cards in the specified zone Server_CardZone *zone = player->getZones().value(zoneName); if (!zone) return RespNameNotFound; @@ -710,6 +710,53 @@ ResponseCode Server_ProtocolHandler::cmdSetCardAttr(Command_SetCardAttr *cmd, Co return setCardAttrHelper(cont, game, player, cmd->getZone(), cmd->getCardId(), cmd->getAttrName(), cmd->getAttrValue()); } +ResponseCode Server_ProtocolHandler::cmdSetCardCounter(Command_SetCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) +{ + if (player->getSpectator()) + return RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return RespGameNotStarted; + + Server_CardZone *zone = player->getZones().value(cmd->getZone()); + if (!zone) + return RespNameNotFound; + + Server_Card *card = zone->getCard(cmd->getCardId(), false); + if (!card) + return RespNameNotFound; + + card->setCounter(cmd->getCounterId(), cmd->getCounterValue()); + + cont->enqueueGameEventPrivate(new Event_SetCardCounter(player->getPlayerId(), zone->getName(), card->getId(), cmd->getCounterId(), cmd->getCounterValue()), game->getGameId()); + cont->enqueueGameEventPublic(new Event_SetCardCounter(player->getPlayerId(), zone->getName(), card->getId(), cmd->getCounterId(), cmd->getCounterValue()), game->getGameId()); + return RespOk; +} + +ResponseCode Server_ProtocolHandler::cmdIncCardCounter(Command_IncCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) +{ + if (player->getSpectator()) + return RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return RespGameNotStarted; + + Server_CardZone *zone = player->getZones().value(cmd->getZone()); + if (!zone) + return RespNameNotFound; + + Server_Card *card = zone->getCard(cmd->getCardId(), false); + if (!card) + return RespNameNotFound; + + int newValue = card->getCounter(cmd->getCounterId()) + cmd->getCounterDelta(); + card->setCounter(cmd->getCounterId(), newValue); + + cont->enqueueGameEventPrivate(new Event_SetCardCounter(player->getPlayerId(), zone->getName(), card->getId(), cmd->getCounterId(), newValue), game->getGameId()); + cont->enqueueGameEventPublic(new Event_SetCardCounter(player->getPlayerId(), zone->getName(), card->getId(), cmd->getCounterId(), newValue), game->getGameId()); + return RespOk; +} + ResponseCode Server_ProtocolHandler::cmdIncCounter(Command_IncCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { if (player->getSpectator()) @@ -833,8 +880,15 @@ ResponseCode Server_ProtocolHandler::cmdDumpZone(Command_DumpZone *cmd, CommandC QString displayedName = card->getFaceDown() ? QString() : card->getName(); if (zone->getType() == HiddenZone) respCardList.append(new ServerInfo_Card(i, displayedName)); - else - respCardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getCounters(), card->getTapped(), card->getAttacking(), card->getAnnotation())); + else { + QList cardCounterList; + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + 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->getPT(), card->getAnnotation(), cardCounterList)); + } } if (zone->getType() == HiddenZone) { zone->setCardsBeingLookedAt(numberCards); diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 73a316c1..012c4039 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -66,6 +66,8 @@ private: ResponseCode cmdDeleteArrow(Command_DeleteArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode setCardAttrHelper(CommandContainer *cont, Server_Game *game, Server_Player *player, const QString &zone, int cardId, const QString &attrName, const QString &attrValue); ResponseCode cmdSetCardAttr(Command_SetCardAttr *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); + ResponseCode cmdSetCardCounter(Command_SetCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); + ResponseCode cmdIncCardCounter(Command_IncCardCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdIncCounter(Command_IncCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateCounter(Command_CreateCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdSetCounter(Command_SetCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);