diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 5349b665..16258d50 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -16,6 +16,7 @@ HEADERS += src/counter.h \ src/window_main.h \ src/cardzone.h \ src/player.h \ + src/playertarget.h \ src/cardlist.h \ src/abstractcarditem.h \ src/carditem.h \ @@ -45,6 +46,7 @@ HEADERS += src/counter.h \ src/phasestoolbar.h \ src/gamescene.h \ src/arrowitem.h \ + src/arrowtarget.h \ src/tab.h \ src/tab_server.h \ src/tab_chatchannel.h \ @@ -71,6 +73,7 @@ SOURCES += src/counter.cpp \ src/window_main.cpp \ src/gamesmodel.cpp \ src/player.cpp \ + src/playertarget.cpp \ src/cardzone.cpp \ src/cardlist.cpp \ src/abstractcarditem.cpp \ @@ -101,6 +104,7 @@ SOURCES += src/counter.cpp \ src/phasestoolbar.cpp \ src/gamescene.cpp \ src/arrowitem.cpp \ + src/arrowtarget.cpp \ src/tab_server.cpp \ src/tab_chatchannel.cpp \ src/tab_game.cpp \ diff --git a/cockatrice/src/abstractcarditem.cpp b/cockatrice/src/abstractcarditem.cpp index ccf84f08..b2b474ef 100644 --- a/cockatrice/src/abstractcarditem.cpp +++ b/cockatrice/src/abstractcarditem.cpp @@ -9,7 +9,7 @@ #include AbstractCardItem::AbstractCardItem(const QString &_name, QGraphicsItem *parent) - : AbstractGraphicsItem(parent), info(db->getCard(_name)), name(_name), tapped(false) + : ArrowTarget(parent), info(db->getCard(_name)), name(_name), tapped(false) { setCursor(Qt::OpenHandCursor); setFlag(ItemIsSelectable); @@ -51,7 +51,7 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * } painter->drawPixmap(translatedPixmap->rect(), *translatedPixmap, translatedPixmap->rect()); } else { - QFont f("Serif"); + QFont f("Times"); f.setStyleHint(QFont::Serif); f.setPixelSize(12); painter->setFont(f); diff --git a/cockatrice/src/abstractcarditem.h b/cockatrice/src/abstractcarditem.h index 35e9efda..d3f869f6 100644 --- a/cockatrice/src/abstractcarditem.h +++ b/cockatrice/src/abstractcarditem.h @@ -1,21 +1,14 @@ #ifndef ABSTRACTCARDITEM_H #define ABSTRACTCARDITEM_H -#include "abstractgraphicsitem.h" +#include "arrowtarget.h" class CardInfo; const int CARD_WIDTH = 72; const int CARD_HEIGHT = 102; -enum CardItemType { - typeCard = QGraphicsItem::UserType + 1, - typeCardDrag = QGraphicsItem::UserType + 2, - typeZone = QGraphicsItem::UserType + 3, - typeOther = QGraphicsItem::UserType + 5 -}; - -class AbstractCardItem : public QObject, public AbstractGraphicsItem { +class AbstractCardItem : public QObject, public ArrowTarget { Q_OBJECT protected: CardInfo *info; diff --git a/cockatrice/src/abstractgraphicsitem.h b/cockatrice/src/abstractgraphicsitem.h index cee33ac3..dfed13e0 100644 --- a/cockatrice/src/abstractgraphicsitem.h +++ b/cockatrice/src/abstractgraphicsitem.h @@ -3,6 +3,14 @@ #include +enum GraphicsItemType { + typeCard = QGraphicsItem::UserType + 1, + typeCardDrag = QGraphicsItem::UserType + 2, + typeZone = QGraphicsItem::UserType + 3, + typePlayerTarget = QGraphicsItem::UserType + 4, + typeOther = QGraphicsItem::UserType + 5 +}; + class AbstractGraphicsItem : public QGraphicsItem { protected: void paintNumberEllipse(int number, int radius, const QColor &color, int position, int count, QPainter *painter); diff --git a/cockatrice/src/arrowitem.cpp b/cockatrice/src/arrowitem.cpp index 7b4349cd..f141e589 100644 --- a/cockatrice/src/arrowitem.cpp +++ b/cockatrice/src/arrowitem.cpp @@ -1,4 +1,5 @@ #include "arrowitem.h" +#include "playertarget.h" #include "carditem.h" #include "cardzone.h" #include "player.h" @@ -8,7 +9,7 @@ #include #include -ArrowItem::ArrowItem(Player *_player, int _id, CardItem *_startItem, CardItem *_targetItem, const QColor &_color) +ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color) : QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color), fullColor(true) { setZValue(2000000005); @@ -96,7 +97,7 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event) player->sendGameCommand(new Command_DeleteArrow(-1, id)); } -ArrowDragItem::ArrowDragItem(CardItem *_startItem, const QColor &_color) +ArrowDragItem::ArrowDragItem(ArrowTarget *_startItem, const QColor &_color) : ArrowItem(static_cast(_startItem->parentItem())->getPlayer(), -1, _startItem, 0, _color) { } @@ -111,10 +112,12 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QPointF endPos = event->scenePos(); QList colliding = scene()->items(endPos); - CardItem *cursorItem = 0; + ArrowTarget *cursorItem = 0; for (int i = colliding.size() - 1; i >= 0; i--) - if ((cursorItem = qgraphicsitem_cast(colliding.at(i)))) + if (qgraphicsitem_cast(colliding.at(i)) || qgraphicsitem_cast(colliding.at(i))) { + cursorItem = static_cast(colliding.at(i)); break; + } if ((cursorItem != targetItem) && targetItem) targetItem->setBeingPointedAt(false); if (!cursorItem) { @@ -139,17 +142,35 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (targetItem && (targetItem != startItem)) { targetItem->setBeingPointedAt(false); CardZone *startZone = static_cast(startItem->parentItem()); - CardZone *targetZone = static_cast(targetItem->parentItem()); - player->sendGameCommand(new Command_CreateArrow( - -1, - startZone->getPlayer()->getId(), - startZone->getName(), - startItem->getId(), - targetZone->getPlayer()->getId(), - targetZone->getName(), - targetItem->getId(), - color - )); + // For now, we can safely assume that the start item is always a card. + // The target item can be a player as well. + CardItem *startCard = qgraphicsitem_cast(startItem); + CardItem *targetCard = qgraphicsitem_cast(targetItem); + if (targetCard) { + CardZone *targetZone = static_cast(targetItem->parentItem()); + player->sendGameCommand(new Command_CreateArrow( + -1, + startZone->getPlayer()->getId(), + startZone->getName(), + startCard->getId(), + targetZone->getPlayer()->getId(), + targetZone->getName(), + targetCard->getId(), + color + )); + } else { + PlayerTarget *targetPlayer = qgraphicsitem_cast(targetItem); + player->sendGameCommand(new Command_CreateArrow( + -1, + startZone->getPlayer()->getId(), + startZone->getName(), + startCard->getId(), + static_cast(targetPlayer->parentItem())->getId(), + QString(), + -1, + color + )); + } } deleteLater(); diff --git a/cockatrice/src/arrowitem.h b/cockatrice/src/arrowitem.h index 47fd8585..ffb90d1d 100644 --- a/cockatrice/src/arrowitem.h +++ b/cockatrice/src/arrowitem.h @@ -7,6 +7,7 @@ class CardItem; class QGraphicsSceneMouseEvent; class QMenu; class Player; +class ArrowTarget; class ArrowItem : public QObject, public QGraphicsItem { Q_OBJECT @@ -16,12 +17,12 @@ private: protected: Player *player; int id; - CardItem *startItem, *targetItem; + ArrowTarget *startItem, *targetItem; QColor color; bool fullColor; void mousePressEvent(QGraphicsSceneMouseEvent *event); public: - ArrowItem(Player *_player, int _id, CardItem *_startItem, CardItem *_targetItem, const QColor &color); + ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &color); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QRectF boundingRect() const { return path.boundingRect(); } QPainterPath shape() const { return path; } @@ -29,10 +30,10 @@ public: void updatePath(const QPointF &endPoint); int getId() const { return id; } - void setStartItem(CardItem *_item) { startItem = _item; } - void setTargetItem(CardItem *_item) { targetItem = _item; } - CardItem *getStartItem() const { return startItem; } - CardItem *getTargetItem() const { return targetItem; } + void setStartItem(ArrowTarget *_item) { startItem = _item; } + void setTargetItem(ArrowTarget *_item) { targetItem = _item; } + ArrowTarget *getStartItem() const { return startItem; } + ArrowTarget *getTargetItem() const { return targetItem; } }; class ArrowDragItem : public ArrowItem { @@ -40,7 +41,7 @@ class ArrowDragItem : public ArrowItem { private: QList childArrows; public: - ArrowDragItem(CardItem *_startItem, const QColor &_color); + ArrowDragItem(ArrowTarget *_startItem, const QColor &_color); void addChildArrow(ArrowDragItem *childArrow); protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event); diff --git a/cockatrice/src/arrowtarget.cpp b/cockatrice/src/arrowtarget.cpp new file mode 100644 index 00000000..e333087a --- /dev/null +++ b/cockatrice/src/arrowtarget.cpp @@ -0,0 +1,12 @@ +#include "arrowtarget.h" + +ArrowTarget::ArrowTarget(QGraphicsItem *parent) + : AbstractGraphicsItem(parent), beingPointedAt(false) +{ +} + +void ArrowTarget::setBeingPointedAt(bool _beingPointedAt) +{ + beingPointedAt = _beingPointedAt; + update(); +} diff --git a/cockatrice/src/arrowtarget.h b/cockatrice/src/arrowtarget.h new file mode 100644 index 00000000..8dbed0fb --- /dev/null +++ b/cockatrice/src/arrowtarget.h @@ -0,0 +1,15 @@ +#ifndef ARROWTARGET_H +#define ARROWTARGET_H + +#include "abstractgraphicsitem.h" + +class ArrowTarget : public AbstractGraphicsItem { +private: + bool beingPointedAt; +public: + ArrowTarget(QGraphicsItem *parent = 0); + void setBeingPointedAt(bool _beingPointedAt); + bool getBeingPointedAt() const { return beingPointedAt; } +}; + +#endif \ No newline at end of file diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index 8e771f98..a8353fdf 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), destroyOnZoneChange(false), doesntUntap(false), beingPointedAt(false), dragItem(NULL) + : AbstractCardItem(_name, parent), owner(_owner), id(_cardid), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(NULL) { owner->addCard(this); @@ -117,8 +117,8 @@ void CardItem::retranslateUi() aDoesntUntap->setText(tr("Toggle &normal untapping")); aFlip->setText(tr("&Flip")); aClone->setText(tr("&Clone")); - aAttach->setText(tr("Attach to card...")); - aUnattach->setText(tr("Unattach")); + aAttach->setText(tr("&Attach to card...")); + aUnattach->setText(tr("Unattac&h")); aSetPT->setText(tr("Set &P/T...")); aSetAnnotation->setText(tr("&Set annotation...")); QStringList counterColors; @@ -157,7 +157,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, ++i; } if (!pt.isEmpty()) { - QFont font("Serif"); + QFont font("Times"); font.setPixelSize(16); painter->setFont(font); QPen pen(Qt::white); @@ -168,7 +168,7 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->drawText(QRectF(0, 0, boundingRect().width() - 5, boundingRect().height() - 5), Qt::AlignRight | Qt::AlignBottom, pt); } - if (beingPointedAt) + if (getBeingPointedAt()) painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100))); painter->restore(); } @@ -214,12 +214,6 @@ void CardItem::setPT(const QString &_pt) update(); } -void CardItem::setBeingPointedAt(bool _beingPointedAt) -{ - beingPointedAt = _beingPointedAt; - update(); -} - void CardItem::resetState() { attacking = false; @@ -286,7 +280,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QListIterator itemIterator(scene()->selectedItems()); while (itemIterator.hasNext()) { CardItem *c = qgraphicsitem_cast(itemIterator.next()); - if (!c) + if (!c || (c == this)) continue; if (c->parentItem() != parentItem()) continue; diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index 2a378774..26e218af 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -25,7 +25,6 @@ private: bool destroyOnZoneChange; bool doesntUntap; QPoint gridPoint; - bool beingPointedAt; CardDragItem *dragItem; QList aAddCounter, aSetCounter, aRemoveCounter; @@ -62,7 +61,6 @@ public: 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); diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index f99a439a..759ef1ea 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -212,15 +212,23 @@ void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString 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) +void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget) { - append(tr("%1 points from %2's %3 to %4's %5.") - .arg(sanitizeHtml(player->getName())) - .arg(sanitizeHtml(startPlayer->getName())) - .arg(sanitizeHtml(startCard)) - .arg(sanitizeHtml(targetPlayer->getName())) - .arg(sanitizeHtml(targetCard)) - ); + if (playerTarget) + append(tr("%1 points from %2's %3 to %4.") + .arg(sanitizeHtml(player->getName())) + .arg(sanitizeHtml(startPlayer->getName())) + .arg(sanitizeHtml(startCard)) + .arg(sanitizeHtml(targetPlayer->getName())) + ); + else + append(tr("%1 points from %2's %3 to %4's %5.") + .arg(sanitizeHtml(player->getName())) + .arg(sanitizeHtml(startPlayer->getName())) + .arg(sanitizeHtml(startCard)) + .arg(sanitizeHtml(targetPlayer->getName())) + .arg(sanitizeHtml(targetCard)) + ); } void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue) @@ -323,7 +331,7 @@ void MessageLogWidget::connectToPlayer(Player *player) connect(player, SIGNAL(logSay(Player *, QString)), this, SLOT(logSay(Player *, QString))); connect(player, SIGNAL(logShuffle(Player *)), this, SLOT(logShuffle(Player *))); connect(player, SIGNAL(logRollDie(Player *, int, int)), this, SLOT(logRollDie(Player *, int, int))); - connect(player, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString)), this, SLOT(logCreateArrow(Player *, Player *, QString, Player *, QString))); + connect(player, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString, bool)), this, SLOT(logCreateArrow(Player *, Player *, QString, Player *, QString, bool))); connect(player, SIGNAL(logCreateToken(Player *, QString, QString)), this, SLOT(logCreateToken(Player *, QString, QString))); connect(player, SIGNAL(logSetCounter(Player *, QString, int, int)), this, SLOT(logSetCounter(Player *, QString, int, int))); connect(player, SIGNAL(logSetCardCounter(Player *, QString, int, int, int)), this, SLOT(logSetCardCounter(Player *, QString, int, int, int))); diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index 451558d4..49fde3ee 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -41,7 +41,7 @@ public slots: 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 logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget); 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); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 7fcc1bf8..f1ef06fa 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -1,6 +1,7 @@ #include "player.h" #include "client.h" #include "cardzone.h" +#include "playertarget.h" #include "counter.h" #include "arrowitem.h" #include "zoneviewzone.h" @@ -28,6 +29,9 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG connect(settingsCache, SIGNAL(playerBgPathChanged()), this, SLOT(updateBgPixmap())); updateBgPixmap(); + playerTarget = new PlayerTarget(name, CARD_WIDTH + counterAreaWidth + 5, this); + playerTarget->setPos(QPointF(0, 0)); + QPointF base = QPointF(counterAreaWidth, 50); PileZone *deck = new PileZone(this, "deck", true, false, this); @@ -207,6 +211,7 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG countersMenu = 0; sbMenu = 0; aCreateAnotherToken = 0; + aCardMenu = 0; } rearrangeZones(); @@ -490,7 +495,13 @@ void Player::eventCreateArrows(Event_CreateArrows *event) ArrowItem *arrow = addArrow(eventArrowList[i]); if (!arrow) return; - emit logCreateArrow(this, arrow->getStartItem()->getOwner(), arrow->getStartItem()->getName(), arrow->getTargetItem()->getOwner(), arrow->getTargetItem()->getName()); + + CardItem *startCard = static_cast(arrow->getStartItem()); + CardItem *targetCard = qgraphicsitem_cast(arrow->getTargetItem()); + if (targetCard) + emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), targetCard->getOwner(), targetCard->getName(), false); + else + emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), static_cast(arrow->getTargetItem()->parentItem()), QString(), true); } } @@ -722,20 +733,11 @@ QRectF Player::boundingRect() const void Player::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) { - QString nameStr = getName(); - QFont font("Times"); - font.setPixelSize(20); -// font.setWeight(QFont::Bold); - int totalWidth = CARD_WIDTH + counterAreaWidth + 5; if (bgPixmap.isNull()) painter->fillRect(QRectF(0, 0, totalWidth, boundingRect().height()), QColor(200, 200, 200)); else painter->fillRect(QRectF(0, 0, totalWidth, boundingRect().height()), QBrush(bgPixmap)); - - painter->setFont(font); - painter->setPen(QPen(Qt::black)); - painter->drawText(QRectF(0, 0, totalWidth, 40), Qt::AlignCenter, nameStr); } void Player::processPlayerInfo(ServerInfo_Player *info) @@ -827,20 +829,25 @@ ArrowItem *Player::addArrow(ServerInfo_Arrow *arrow) CardZone *startZone = startPlayer->getZones().value(arrow->getStartZone(), 0); CardZone *targetZone = targetPlayer->getZones().value(arrow->getTargetZone(), 0); - if (!startZone || !targetZone) + if (!startZone || (!targetZone && !arrow->getTargetZone().isEmpty())) return 0; CardItem *startCard = startZone->getCard(arrow->getStartCardId(), QString()); - CardItem *targetCard = targetZone->getCard(arrow->getTargetCardId(), QString()); - if (!startCard || !targetCard) + CardItem *targetCard = 0; + if (targetZone) + targetCard = targetZone->getCard(arrow->getTargetCardId(), QString()); + if (!startCard || (!targetCard && !arrow->getTargetZone().isEmpty())) return 0; - return addArrow(arrow->getId(), startCard, targetCard, arrow->getColor()); + if (targetCard) + return addArrow(arrow->getId(), startCard, targetCard, arrow->getColor()); + else + return addArrow(arrow->getId(), startCard, targetPlayer->getPlayerTarget(), arrow->getColor()); } -ArrowItem *Player::addArrow(int arrowId, CardItem *startCard, CardItem *targetCard, const QColor &color) +ArrowItem *Player::addArrow(int arrowId, CardItem *startCard, ArrowTarget *targetItem, const QColor &color) { - ArrowItem *arrow = new ArrowItem(this, arrowId, startCard, targetCard, color); + ArrowItem *arrow = new ArrowItem(this, arrowId, startCard, targetItem, color); arrows.insert(arrowId, arrow); scene()->addItem(arrow); return arrow; @@ -909,6 +916,7 @@ void Player::cardMenuAction() { QAction *a = static_cast(sender()); QList sel = scene()->selectedItems(); + QList commandList; while (!sel.isEmpty()) { unsigned int i = (unsigned int) (((double) sel.size()) * qrand() / (RAND_MAX + 1.0)); CardItem *card = qgraphicsitem_cast(sel.takeAt(i)); @@ -916,38 +924,39 @@ void Player::cardMenuAction() switch (a->data().toInt()) { case 0: if (!card->getTapped()) - sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast(card->parentItem())->getName(), card->getId(), "tapped", "1")); + commandList.append(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")); + commandList.append(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()))); + commandList.append(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())); + commandList.append(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())); + commandList.append(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)); + commandList.append(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)); + commandList.append(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)); + commandList.append(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)); + commandList.append(new Command_MoveCard(-1, static_cast(card->parentItem())->getName(), card->getId(), "rfg", 0, 0, false)); break; default: ; } } + sendCommandContainer(new CommandContainer(commandList)); } void Player::actSetPT() @@ -1045,12 +1054,15 @@ void Player::actCardCounterTrigger() void Player::setCardMenu(QMenu *menu) { - aCardMenu->setMenu(menu); + if (aCardMenu) + aCardMenu->setMenu(menu); } QMenu *Player::getCardMenu() const { - return aCardMenu->menu(); + if (aCardMenu) + return aCardMenu->menu(); + return 0; } qreal Player::getMinimumWidth() const diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index 3aad6cbc..f5874af3 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -17,6 +17,7 @@ class ArrowItem; class CardZone; class TableZone; class HandZone; +class PlayerTarget; class ServerInfo_Player; class ServerInfo_Arrow; class ServerInfo_Counter; @@ -49,7 +50,7 @@ signals: void logSay(Player *player, QString message); void logShuffle(Player *player); void logRollDie(Player *player, int sides, int roll); - void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard); + void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool _playerTarget); 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); @@ -90,7 +91,6 @@ public slots: void actCardCounterTrigger(); private slots: - void updateBgPixmap(); void updateBoundingRect(); void rearrangeZones(); @@ -104,9 +104,6 @@ private: *aUntapAll, *aRollDie, *aCreateToken, *aCreateAnotherToken, *aCardMenu; - typedef void (Player::*CardMenuHandler)(CardItem *card); - QHash cardMenuHandlers; - int defaultNumberTopCards; QString lastTokenName, lastTokenColor, lastTokenPT, lastTokenAnnotation; bool lastTokenDestroy; @@ -119,6 +116,7 @@ private: QMap zones; TableZone *table; HandZone *hand; + PlayerTarget *playerTarget; void setCardAttrHelper(CardItem *card, const QString &aname, const QString &avalue, bool allCards); @@ -164,9 +162,10 @@ public: void clearCounters(); ArrowItem *addArrow(ServerInfo_Arrow *arrow); - ArrowItem *addArrow(int arrowId, CardItem *startCard, CardItem *targetCard, const QColor &color); + ArrowItem *addArrow(int arrowId, CardItem *startCard, ArrowTarget *targetItem, const QColor &color); void delArrow(int arrowId); void clearArrows(); + PlayerTarget *getPlayerTarget() const { return playerTarget; } Client *client; Player(const QString &_name, int _id, bool _local, Client *_client, TabGame *_parent); diff --git a/cockatrice/src/playertarget.cpp b/cockatrice/src/playertarget.cpp new file mode 100644 index 00000000..aecde601 --- /dev/null +++ b/cockatrice/src/playertarget.cpp @@ -0,0 +1,23 @@ +#include "playertarget.h" +#include + +PlayerTarget::PlayerTarget(const QString &_name, int _maxWidth, QGraphicsItem *parent) + : ArrowTarget(parent), name(_name), maxWidth(_maxWidth) +{ + font = QFont("Times"); + font.setStyleHint(QFont::Serif); + font.setPixelSize(20); +} + +QRectF PlayerTarget::boundingRect() const +{ + return QRectF(0, 0, maxWidth, 30); +} + +void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) +{ + painter->fillRect(boundingRect(), QColor(255, 255, 255, 100)); + painter->setFont(font); + painter->setPen(Qt::black); + painter->drawText(boundingRect(), Qt::AlignCenter, name); +} diff --git a/cockatrice/src/playertarget.h b/cockatrice/src/playertarget.h new file mode 100644 index 00000000..ad9b9b52 --- /dev/null +++ b/cockatrice/src/playertarget.h @@ -0,0 +1,21 @@ +#ifndef PLAYERTARGET_H +#define PLAYERTARGET_H + +#include "arrowtarget.h" +#include + +class PlayerTarget : public ArrowTarget { +private: + QString name; + QFont font; + int maxWidth; +public: + enum { Type = typePlayerTarget }; + int type() const { return Type; } + + PlayerTarget(const QString &_name, int _maxWidth, QGraphicsItem *parent = 0); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); +}; + +#endif \ No newline at end of file diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts index d1578b79..e8d56851 100644 --- a/cockatrice/translations/cockatrice_de.ts +++ b/cockatrice/translations/cockatrice_de.ts @@ -152,115 +152,223 @@ Das Kartenhintergrundbild konnte nicht geladen werden. + + CardItem + + + &Tap + &Tappen + + + + &Untap + E&nttappen + + + + Toggle &normal untapping + N&ormales Enttappen umschalten + + + + &Flip + &Umdrehen + + + + &Clone + &Kopieren + + + + &Attach to card... + &An Karte anlegen... + + + + Unattac&h + &Von Karte lösen + + + + Set &P/T... + &Kampfwerte setzen... + + + + &Set annotation... + &Hinweis setzen... + + + + red + rot + + + + yellow + gelb + + + + green + grün + + + + &Add counter (%1) + Zählmarke &hinzufügen (%1) + + + + &Remove counter (%1) + Zählmarke &entfernen (%1) + + + + &Set counters (%1)... + Zählmarken &setzen (%1)... + + + + &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 + + CardZone - - + + his hand seine Hand - - + + %1's hand %1s Hand - + of his hand seiner Hand - + of %1's hand von %1s Hand - - + + his library seine Bibliothek - - + + %1's library %1s Bibliothek - + of his library seiner Bibliothek - + of %1's library von %1s Bibliothek - - + + his graveyard sein Friedhof - - + + %1's graveyard %1s Friedhof - + of his graveyard seines Friedhofs - + of %1's graveyard von %1s Friedhof - - + + his exile sein Exil - - + + %1's exile %1s Exil - + of his exile seines Exils - + of %1's exile von %1s Exil - - + + his sideboard sein Sideboard - - + + %1's sideboard %1s Sideboard - + of his sideboard seines Sideboards - + of %1's sideboard von %1s Sideboard @@ -607,16 +715,21 @@ + &Destroy token when it leaves the table + Spielstein &zerstören, wenn er das Spielfeld verlässt + + + &OK &OK - + &Cancel A&bbrechen - + Create token Spielstein erstellen @@ -1644,16 +1757,30 @@ - %1 creates token: %2 (%3). - %1 erstellt einen Spielstein: %2 (%3). + %1 destroys %2. + %1 zerstört %2. + %1 creates token: %2%3. + %1 erstellt Token: %2%3. + + + + %1 points from %2's %3 to %4. + %1 zeigt von %2s %3 auf %4. + + + %1 creates token: %2 (%3). + %1 erstellt einen Spielstein: %2 (%3). + + + %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). @@ -1661,7 +1788,7 @@ - + %1 removes %n counter(s) (%2) from %3 (now %4). %1 entfernt eine Marke (%2) von %3 (jetzt %4). @@ -1669,37 +1796,37 @@ - + 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. @@ -1796,7 +1923,7 @@ %1 entfernt %2 Zählmarken von %3 (jetzt %4). - + %1 %2 %3. %1 %2 %3. @@ -1809,17 +1936,17 @@ %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 @@ -1848,57 +1975,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 @@ -1907,7 +2034,7 @@ das Ende-des-Zuges-Segment - + It is now the %1. Es ist nun %1. @@ -1916,12 +2043,12 @@ %1 bewegt %2 %3 nach %4 - + taps tappt - + untaps enttappt @@ -1946,7 +2073,7 @@ %1 entfernt %2 Zählmarken von %3 (jetzt %4) - + his permanents seine bleibenden Karten @@ -1959,12 +2086,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. @@ -2069,41 +2196,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 @@ -2112,32 +2239,32 @@ Zeige ent&fernte Karten - + &View sideboard Zeige &Sideboard - + Player "%1" Spieler "%1" - + Take &mulligan &Mulligan nehmen - + &Hand &Hand - + &Library Bib&liothek - + &Graveyard &Friedhof @@ -2146,80 +2273,78 @@ Entfe&rnte Karten - + &Sideboard &Sideboard - Set &P/T... - &Kampfwerte setzen... + &Kampfwerte setzen... - &Set annotation... - &Hinweis setzen... + &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 @@ -2228,32 +2353,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 @@ -2282,124 +2407,108 @@ Ctrl+L - + R&oll die... &Würfeln... - + Ctrl+I Ctrl+I - + &Create token... Spiels&tein erstellen... - + Ctrl+T Ctrl+T - + C&reate another token &Noch einen Spielstein erstellen - + Ctrl+G Ctrl+G - + S&ay S&agen - + C&ard &Karte - &Tap - &Tappen + &Tappen - &Untap - E&nttappen + E&nttappen - Toggle &normal untapping - &Normales Enttappen umschalten + &Normales Enttappen umschalten - &Flip - &Umdrehen + &Umdrehen - Counters (red) - Marken (rot) + Marken (rot) - Counters (yellow) - Marken (gelb) + Marken (gelb) - Counters (green) - Marken (grün) + Marken (grün) - &Add counter - Zählm&arke hinzufügen + Zählm&arke hinzufügen - &Remove counter - Zählma&rke entfernen + Zählma&rke entfernen - &Set counters... - &Setze Zählmarken... + &Setze Zählmarken... - &top of library - &auf die Bibliothek + &auf die Bibliothek - &bottom of library - &unter die Bibliothek + &unter die Bibliothek - &graveyard - in den &Friedhof + in den &Friedhof - Ctrl+Del - Ctrl+Del + Ctrl+Del - &exile - ins &Exil + ins &Exil - &Move to - &Verschieben + &Verschieben F5 @@ -2426,38 +2535,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 @@ -2470,12 +2579,12 @@ Neue Lebenspunkte insgesamt: - + Roll die Würfeln - + Number of sides: Anzahl der Seiten: diff --git a/cockatrice/translations/cockatrice_en.ts b/cockatrice/translations/cockatrice_en.ts index d17402cc..56bc29d9 100644 --- a/cockatrice/translations/cockatrice_en.ts +++ b/cockatrice/translations/cockatrice_en.ts @@ -117,115 +117,223 @@ + + CardItem + + + &Tap + + + + + &Untap + + + + + Toggle &normal untapping + + + + + &Flip + + + + + &Clone + + + + + &Attach to card... + + + + + Unattac&h + + + + + Set &P/T... + + + + + &Set annotation... + + + + + red + + + + + yellow + + + + + green + + + + + &Add counter (%1) + + + + + &Remove counter (%1) + + + + + &Set counters (%1)... + + + + + &top of library + + + + + &bottom of library + + + + + &graveyard + + + + + Ctrl+Del + + + + + &exile + + + + + &Move to + + + CardZone - - + + his hand - - + + %1's hand - + of his hand - + of %1's hand - - + + his library - - + + %1's library - + of his library - + of %1's library - - + + his graveyard - - + + %1's graveyard - + of his graveyard - + of %1's graveyard - - + + his exile - - + + %1's exile - + of his exile - + of %1's exile - - + + his sideboard - - + + %1's sideboard - + of his sideboard - + of %1's sideboard @@ -515,16 +623,21 @@ + &Destroy token when it leaves the table + + + + &OK - + &Cancel - + Create token @@ -1053,17 +1166,12 @@ - - %1 creates token: %2 (%3). - - - - + %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). @@ -1071,7 +1179,7 @@ - + %1 removes %n counter(s) (%2) from %3 (now %4). %1 removes a counter (%2) from %3 (now %4). @@ -1079,37 +1187,37 @@ - + 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. @@ -1174,27 +1282,42 @@ - + + %1 destroys %2. + + + + + %1 creates token: %2%3. + + + + + %1 points from %2's %3 to %4. + + + + %1 %2 %3. - + %1 is looking at %2. - + %1 stops looking at %2. - + ending phase - + It is now %1's turn. @@ -1204,82 +1327,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 @@ -1368,345 +1491,255 @@ 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 - + C&reate another token - + Ctrl+G - + 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: - + Set power/toughness - + Please enter the new PT: - + Set annotation - + Please enter the new annotation: - + Set counters diff --git a/common/server_arrow.h b/common/server_arrow.h index 67b5b1cd..d82ac6cd 100644 --- a/common/server_arrow.h +++ b/common/server_arrow.h @@ -4,18 +4,20 @@ #include class Server_Card; +class Server_ArrowTarget; class Server_Arrow { private: int id; - Server_Card *startCard, *targetCard; + Server_Card *startCard; + Server_ArrowTarget *targetItem; QColor color; public: - Server_Arrow(int _id, Server_Card *_startCard, Server_Card *_targetCard, const QColor &_color) - : id(_id), startCard(_startCard), targetCard(_targetCard), color(_color) { } + Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const QColor &_color) + : id(_id), startCard(_startCard), targetItem(_targetItem), color(_color) { } int getId() const { return id; } Server_Card *getStartCard() const { return startCard; } - Server_Card *getTargetCard() const { return targetCard; } + Server_ArrowTarget *getTargetItem() const { return targetItem; } QColor getColor() const { return color; } }; diff --git a/common/server_arrowtarget.h b/common/server_arrowtarget.h new file mode 100644 index 00000000..589dfa8a --- /dev/null +++ b/common/server_arrowtarget.h @@ -0,0 +1,10 @@ +#ifndef SERVER_ARROWTARGET_H +#define SERVER_ARROWTARGET_H + +#include + +class Server_ArrowTarget : public QObject { + Q_OBJECT +}; + +#endif \ No newline at end of file diff --git a/common/server_card.h b/common/server_card.h index a22ffcff..9db3f15a 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -20,12 +20,14 @@ #ifndef SERVER_CARD_H #define SERVER_CARD_H +#include "server_arrowtarget.h" #include #include class Server_CardZone; -class Server_Card { +class Server_Card : public Server_ArrowTarget { + Q_OBJECT private: Server_CardZone *zone; int id; diff --git a/common/server_game.cpp b/common/server_game.cpp index 058a5044..93dd54cc 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -197,6 +197,28 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec void Server_Game::removePlayer(Server_Player *player) { players.remove(player->getPlayerId()); + + // Remove all arrows of other players pointing to the player being removed or to one of his cards. + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + QList arrows = p->getArrows().values(); + QList toDelete; + for (int i = 0; i < arrows.size(); ++i) { + Server_Arrow *a = arrows[i]; + Server_Card *targetCard = qobject_cast(a->getTargetItem()); + if (targetCard) { + if (targetCard->getZone()->getPlayer() == player) + toDelete.append(a); + } else if ((static_cast(a->getTargetItem()) == player) || (a->getStartCard()->getZone()->getPlayer() == player)) + toDelete.append(a); + } + for (int i = 0; i < toDelete.size(); ++i) { + sendGameEvent(new Event_DeleteArrow(p->getPlayerId(), toDelete[i]->getId())); + p->deleteArrow(toDelete[i]->getId()); + } + } + sendGameEvent(new Event_Leave(player->getPlayerId())); bool spectator = player->getSpectator(); delete player; @@ -243,16 +265,29 @@ QList Server_Game::getGameState(Server_Player *playerWhosAs QMapIterator arrowIterator(player->getArrows()); while (arrowIterator.hasNext()) { Server_Arrow *arrow = arrowIterator.next().value(); - arrowList.append(new ServerInfo_Arrow( - arrow->getId(), - arrow->getStartCard()->getZone()->getPlayer()->getPlayerId(), - arrow->getStartCard()->getZone()->getName(), - arrow->getStartCard()->getId(), - arrow->getTargetCard()->getZone()->getPlayer()->getPlayerId(), - arrow->getTargetCard()->getZone()->getName(), - arrow->getTargetCard()->getId(), - arrow->getColor() - )); + Server_Card *targetCard = qobject_cast(arrow->getTargetItem()); + if (targetCard) + arrowList.append(new ServerInfo_Arrow( + arrow->getId(), + arrow->getStartCard()->getZone()->getPlayer()->getPlayerId(), + arrow->getStartCard()->getZone()->getName(), + arrow->getStartCard()->getId(), + targetCard->getZone()->getPlayer()->getPlayerId(), + targetCard->getZone()->getName(), + targetCard->getId(), + arrow->getColor() + )); + else + arrowList.append(new ServerInfo_Arrow( + arrow->getId(), + arrow->getStartCard()->getZone()->getPlayer()->getPlayerId(), + arrow->getStartCard()->getZone()->getName(), + arrow->getStartCard()->getId(), + qobject_cast(arrow->getTargetItem())->getPlayerId(), + QString(), + -1, + arrow->getColor() + )); } QList counterList; diff --git a/common/server_player.h b/common/server_player.h index f7865040..70ed9e4a 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -1,7 +1,7 @@ #ifndef PLAYER_H #define PLAYER_H -#include +#include "server_arrowtarget.h" #include #include #include @@ -15,7 +15,7 @@ class Server_ProtocolHandler; class ProtocolItem; class ServerInfo_PlayerProperties; -class Server_Player : public QObject { +class Server_Player : public Server_ArrowTarget { Q_OBJECT private: Server_Game *game; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 9832ae86..c4e62374 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -593,7 +593,7 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player * QMapIterator arrowIterator(players[i]->getArrows()); while (arrowIterator.hasNext()) { Server_Arrow *arrow = arrowIterator.next().value(); - if ((arrow->getStartCard() == card) || (arrow->getTargetCard() == card)) + if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) arrowsToDelete.append(arrow->getId()); } for (int j = 0; j < arrowsToDelete.size(); ++j) @@ -689,21 +689,33 @@ ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, Co if (!startPlayer || !targetPlayer) return RespNameNotFound; Server_CardZone *startZone = startPlayer->getZones().value(cmd->getStartZone()); - Server_CardZone *targetZone = targetPlayer->getZones().value(cmd->getTargetZone()); - if (!startZone || !targetZone) + bool playerTarget = cmd->getTargetZone().isEmpty(); + Server_CardZone *targetZone = 0; + if (!playerTarget) + targetZone = targetPlayer->getZones().value(cmd->getTargetZone()); + if (!startZone || (!targetZone && !playerTarget)) return RespNameNotFound; Server_Card *startCard = startZone->getCard(cmd->getStartCardId(), false); - Server_Card *targetCard = targetZone->getCard(cmd->getTargetCardId(), false); - if (!startCard || !targetCard || (startCard == targetCard)) + Server_Card *targetCard = 0; + if (!playerTarget) + targetCard = targetZone->getCard(cmd->getTargetCardId(), false); + if (!startCard || (!targetCard && !playerTarget) || (startCard == targetCard)) return RespContextError; + + Server_ArrowTarget *targetItem; + if (playerTarget) + targetItem = targetPlayer; + else + targetItem = targetCard; + QMapIterator arrowIterator(player->getArrows()); while (arrowIterator.hasNext()) { Server_Arrow *temp = arrowIterator.next().value(); - if ((temp->getStartCard() == startCard) && (temp->getTargetCard() == targetCard)) + if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) return RespContextError; } - - Server_Arrow *arrow = new Server_Arrow(player->newArrowId(), startCard, targetCard, cmd->getColor()); + + Server_Arrow *arrow = new Server_Arrow(player->newArrowId(), startCard, targetItem, cmd->getColor()); player->addArrow(arrow); game->sendGameEvent(new Event_CreateArrows(player->getPlayerId(), QList() << new ServerInfo_Arrow( arrow->getId(), @@ -711,8 +723,8 @@ ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, Co startZone->getName(), startCard->getId(), targetPlayer->getPlayerId(), - targetZone->getName(), - targetCard->getId(), + cmd->getTargetZone(), + cmd->getTargetCardId(), cmd->getColor() ))); return RespOk; diff --git a/servatrice/servatrice.pro b/servatrice/servatrice.pro index 67166963..60879067 100755 --- a/servatrice/servatrice.pro +++ b/servatrice/servatrice.pro @@ -29,7 +29,8 @@ HEADERS += src/servatrice.h \ ../common/server_counter.h \ ../common/server_game.h \ ../common/server_player.h \ - ../common/server_protocolhandler.h + ../common/server_protocolhandler.h \ + ../common/server_arrowtarget.h SOURCES += src/main.cpp \ src/servatrice.cpp \