arrows can target players; card attachment works

This commit is contained in:
Max-Wilhelm Bruker 2010-07-17 18:24:14 +02:00
parent 61b82bd6f9
commit 614f106304
32 changed files with 885 additions and 402 deletions

View file

@ -8,8 +8,8 @@
#include "main.h" #include "main.h"
#include <QDebug> #include <QDebug>
AbstractCardItem::AbstractCardItem(const QString &_name, QGraphicsItem *parent) AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, QGraphicsItem *parent)
: ArrowTarget(parent), info(db->getCard(_name)), name(_name), tapped(false) : ArrowTarget(_owner, parent), info(db->getCard(_name)), name(_name), tapped(false)
{ {
setCursor(Qt::OpenHandCursor); setCursor(Qt::OpenHandCursor);
setFlag(ItemIsSelectable); setFlag(ItemIsSelectable);

View file

@ -4,6 +4,7 @@
#include "arrowtarget.h" #include "arrowtarget.h"
class CardInfo; class CardInfo;
class Player;
const int CARD_WIDTH = 72; const int CARD_WIDTH = 72;
const int CARD_HEIGHT = 102; const int CARD_HEIGHT = 102;
@ -22,7 +23,7 @@ signals:
public: public:
enum { Type = typeCard }; enum { Type = typeCard };
int type() const { return Type; } int type() const { return Type; }
AbstractCardItem(const QString &_name = QString(), QGraphicsItem *parent = 0); AbstractCardItem(const QString &_name = QString(), Player *_owner = 0, QGraphicsItem *parent = 0);
~AbstractCardItem(); ~AbstractCardItem();
QRectF boundingRect() const; QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

View file

@ -8,15 +8,34 @@
#include <QPainter> #include <QPainter>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QDebug>
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_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) : QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color), fullColor(true)
{ {
setZValue(2000000005); setZValue(2000000005);
if (startItem)
startItem->addArrowFrom(this);
if (targetItem)
targetItem->addArrowTo(this);
if (startItem && targetItem) if (startItem && targetItem)
updatePath(); updatePath();
} }
ArrowItem::~ArrowItem()
{
qDebug() << "ArrowItem destructor";
if (startItem)
startItem->removeArrowFrom(this);
if (targetItem) {
targetItem->setBeingPointedAt(false);
targetItem->removeArrowTo(this);
}
}
void ArrowItem::updatePath() void ArrowItem::updatePath()
{ {
QPointF endPoint = targetItem->mapToScene(QPointF(targetItem->boundingRect().width() / 2, targetItem->boundingRect().height() / 2)); QPointF endPoint = targetItem->mapToScene(QPointF(targetItem->boundingRect().width() / 2, targetItem->boundingRect().height() / 2));
@ -97,8 +116,8 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
player->sendGameCommand(new Command_DeleteArrow(-1, id)); player->sendGameCommand(new Command_DeleteArrow(-1, id));
} }
ArrowDragItem::ArrowDragItem(ArrowTarget *_startItem, const QColor &_color) ArrowDragItem::ArrowDragItem(Player *_owner, ArrowTarget *_startItem, const QColor &_color)
: ArrowItem(static_cast<CardZone *>(_startItem->parentItem())->getPlayer(), -1, _startItem, 0, _color) : ArrowItem(_owner, -1, _startItem, 0, _color)
{ {
} }
@ -118,17 +137,23 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
cursorItem = static_cast<ArrowTarget *>(colliding.at(i)); cursorItem = static_cast<ArrowTarget *>(colliding.at(i));
break; break;
} }
if ((cursorItem != targetItem) && targetItem) if ((cursorItem != targetItem) && targetItem) {
targetItem->setBeingPointedAt(false); targetItem->setBeingPointedAt(false);
targetItem->removeArrowTo(this);
}
if (!cursorItem) { if (!cursorItem) {
fullColor = false; fullColor = false;
targetItem = 0; targetItem = 0;
updatePath(endPos); updatePath(endPos);
} else { } else {
fullColor = true; if (cursorItem != targetItem) {
if (cursorItem != startItem) fullColor = true;
cursorItem->setBeingPointedAt(true); if (cursorItem != startItem) {
targetItem = cursorItem; cursorItem->setBeingPointedAt(true);
cursorItem->addArrowTo(this);
}
targetItem = cursorItem;
}
updatePath(); updatePath();
} }
update(); update();
@ -140,14 +165,13 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
if (targetItem && (targetItem != startItem)) { if (targetItem && (targetItem != startItem)) {
targetItem->setBeingPointedAt(false); CardZone *startZone = static_cast<CardItem *>(startItem)->getZone();
CardZone *startZone = static_cast<CardZone *>(startItem->parentItem());
// For now, we can safely assume that the start item is always a card. // For now, we can safely assume that the start item is always a card.
// The target item can be a player as well. // The target item can be a player as well.
CardItem *startCard = qgraphicsitem_cast<CardItem *>(startItem); CardItem *startCard = qgraphicsitem_cast<CardItem *>(startItem);
CardItem *targetCard = qgraphicsitem_cast<CardItem *>(targetItem); CardItem *targetCard = qgraphicsitem_cast<CardItem *>(targetItem);
if (targetCard) { if (targetCard) {
CardZone *targetZone = static_cast<CardZone *>(targetItem->parentItem()); CardZone *targetZone = targetCard->getZone();
player->sendGameCommand(new Command_CreateArrow( player->sendGameCommand(new Command_CreateArrow(
-1, -1,
startZone->getPlayer()->getId(), startZone->getPlayer()->getId(),
@ -165,7 +189,7 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
startZone->getPlayer()->getId(), startZone->getPlayer()->getId(),
startZone->getName(), startZone->getName(),
startCard->getId(), startCard->getId(),
static_cast<Player *>(targetPlayer->parentItem())->getId(), targetPlayer->getOwner()->getId(),
QString(), QString(),
-1, -1,
color color
@ -177,3 +201,55 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
for (int i = 0; i < childArrows.size(); ++i) for (int i = 0; i < childArrows.size(); ++i)
childArrows[i]->mouseReleaseEvent(event); childArrows[i]->mouseReleaseEvent(event);
} }
ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
: ArrowItem(_startItem->getOwner(), -1, _startItem, 0, Qt::green)
{
}
void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QPointF endPos = event->scenePos();
QList<QGraphicsItem *> colliding = scene()->items(endPos);
ArrowTarget *cursorItem = 0;
for (int i = colliding.size() - 1; i >= 0; i--)
if (qgraphicsitem_cast<CardItem *>(colliding.at(i))) {
cursorItem = static_cast<ArrowTarget *>(colliding.at(i));
break;
}
if ((cursorItem != targetItem) && targetItem)
targetItem->setBeingPointedAt(false);
if (!cursorItem) {
fullColor = false;
targetItem = 0;
updatePath(endPos);
} else {
fullColor = true;
if (cursorItem != startItem)
cursorItem->setBeingPointedAt(true);
targetItem = cursorItem;
updatePath();
}
update();
}
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
{
if (targetItem && (targetItem != startItem)) {
CardItem *startCard = qgraphicsitem_cast<CardItem *>(startItem);
CardZone *startZone = startCard->getZone();
CardItem *targetCard = qgraphicsitem_cast<CardItem *>(targetItem);
CardZone *targetZone = targetCard->getZone();
player->sendGameCommand(new Command_AttachCard(
-1,
startZone->getName(),
startCard->getId(),
targetZone->getPlayer()->getId(),
targetZone->getName(),
targetCard->getId()
));
}
deleteLater();
}

View file

@ -23,6 +23,7 @@ protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event);
public: public:
ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &color); ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &color);
~ArrowItem();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QRectF boundingRect() const { return path.boundingRect(); } QRectF boundingRect() const { return path.boundingRect(); }
QPainterPath shape() const { return path; } QPainterPath shape() const { return path; }
@ -30,6 +31,7 @@ public:
void updatePath(const QPointF &endPoint); void updatePath(const QPointF &endPoint);
int getId() const { return id; } int getId() const { return id; }
Player *getPlayer() const { return player; }
void setStartItem(ArrowTarget *_item) { startItem = _item; } void setStartItem(ArrowTarget *_item) { startItem = _item; }
void setTargetItem(ArrowTarget *_item) { targetItem = _item; } void setTargetItem(ArrowTarget *_item) { targetItem = _item; }
ArrowTarget *getStartItem() const { return startItem; } ArrowTarget *getStartItem() const { return startItem; }
@ -41,11 +43,20 @@ class ArrowDragItem : public ArrowItem {
private: private:
QList<ArrowDragItem *> childArrows; QList<ArrowDragItem *> childArrows;
public: public:
ArrowDragItem(ArrowTarget *_startItem, const QColor &_color); ArrowDragItem(Player *_owner, ArrowTarget *_startItem, const QColor &_color);
void addChildArrow(ArrowDragItem *childArrow); void addChildArrow(ArrowDragItem *childArrow);
protected: protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
}; };
class ArrowAttachItem : public ArrowItem {
Q_OBJECT
public:
ArrowAttachItem(ArrowTarget *_startItem);
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
#endif // ARROWITEM_H #endif // ARROWITEM_H

View file

@ -1,10 +1,20 @@
#include "arrowtarget.h" #include "arrowtarget.h"
#include "arrowitem.h"
#include "player.h"
ArrowTarget::ArrowTarget(QGraphicsItem *parent) ArrowTarget::ArrowTarget(Player *_owner, QGraphicsItem *parent)
: AbstractGraphicsItem(parent), beingPointedAt(false) : AbstractGraphicsItem(parent), owner(_owner), beingPointedAt(false)
{ {
} }
ArrowTarget::~ArrowTarget()
{
while (!arrowsFrom.isEmpty())
arrowsFrom.first()->getPlayer()->delArrow(arrowsFrom.first()->getId());
while (!arrowsTo.isEmpty())
arrowsTo.first()->getPlayer()->delArrow(arrowsTo.first()->getId());
}
void ArrowTarget::setBeingPointedAt(bool _beingPointedAt) void ArrowTarget::setBeingPointedAt(bool _beingPointedAt)
{ {
beingPointedAt = _beingPointedAt; beingPointedAt = _beingPointedAt;

View file

@ -2,14 +2,33 @@
#define ARROWTARGET_H #define ARROWTARGET_H
#include "abstractgraphicsitem.h" #include "abstractgraphicsitem.h"
#include <QList>
class Player;
class ArrowItem;
class ArrowTarget : public AbstractGraphicsItem { class ArrowTarget : public AbstractGraphicsItem {
protected:
Player *owner;
private: private:
bool beingPointedAt; bool beingPointedAt;
QList<ArrowItem *> arrowsFrom, arrowsTo;
public: public:
ArrowTarget(QGraphicsItem *parent = 0); ArrowTarget(Player *_owner, QGraphicsItem *parent = 0);
~ArrowTarget();
Player *getOwner() const { return owner; }
void setBeingPointedAt(bool _beingPointedAt); void setBeingPointedAt(bool _beingPointedAt);
bool getBeingPointedAt() const { return beingPointedAt; } bool getBeingPointedAt() const { return beingPointedAt; }
const QList<ArrowItem *> &getArrowsFrom() const { return arrowsFrom; }
void addArrowFrom(ArrowItem *arrow) { arrowsFrom.append(arrow); }
void removeArrowFrom(ArrowItem *arrow) { arrowsFrom.removeAt(arrowsFrom.indexOf(arrow)); }
const QList<ArrowItem *> &getArrowsTo() const { return arrowsTo; }
void addArrowTo(ArrowItem *arrow) { arrowsTo.append(arrow); }
void removeArrowTo(ArrowItem *arrow) { arrowsTo.removeAt(arrowsTo.indexOf(arrow)); }
}; };
#endif #endif

View file

@ -6,7 +6,7 @@
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QCursor> #include <QCursor>
CardDragItem::CardDragItem(AbstractCardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag) CardDragItem::CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag)
: AbstractCardDragItem(_item, _hotSpot, parentDrag), id(_id), faceDown(_faceDown), currentZone(0) : AbstractCardDragItem(_item, _hotSpot, parentDrag), id(_id), faceDown(_faceDown), currentZone(0)
{ {
} }
@ -53,7 +53,7 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
sc->removeItem(this); sc->removeItem(this);
if (currentZone) { if (currentZone) {
CardZone *startZone = qgraphicsitem_cast<CardZone *>(item->parentItem()); CardZone *startZone = static_cast<CardItem *>(item)->getZone();
currentZone->handleDropEvent(id, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown); currentZone->handleDropEvent(id, startZone, (sp - currentZone->scenePos()).toPoint(), faceDown);
for (int i = 0; i < childDrags.size(); i++) { for (int i = 0; i < childDrags.size(); i++) {
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]); CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);

View file

@ -3,13 +3,15 @@
#include "abstractcarddragitem.h" #include "abstractcarddragitem.h"
class CardItem;
class CardDragItem : public AbstractCardDragItem { class CardDragItem : public AbstractCardDragItem {
private: private:
int id; int id;
bool faceDown; bool faceDown;
CardZone *currentZone; CardZone *currentZone;
public: public:
CardDragItem(AbstractCardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag = 0); CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, AbstractCardDragItem *parentDrag = 0);
void updatePosition(const QPointF &cursorScenePos); void updatePosition(const QPointF &cursorScenePos);
protected: protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

View file

@ -10,9 +10,10 @@
#include "main.h" #include "main.h"
#include "protocol_datastructures.h" #include "protocol_datastructures.h"
#include "settingscache.h" #include "settingscache.h"
#include "tab_game.h"
CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, QGraphicsItem *parent) 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), dragItem(NULL) : AbstractCardItem(_name, _owner, parent), id(_cardid), attacking(false), facedown(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(0), attachedTo(0)
{ {
owner->addCard(this); owner->addCard(this);
@ -106,6 +107,14 @@ CardItem::~CardItem()
owner->setCardMenu(0); owner->setCardMenu(0);
delete cardMenu; delete cardMenu;
while (!attachedCards.isEmpty()) {
attachedCards.first()->setZone(0); // so that it won't try to call reorganizeCards()
attachedCards.first()->setAttachedTo(0);
}
if (attachedTo)
attachedTo->removeAttachedCard(this);
deleteDragItem(); deleteDragItem();
} }
@ -118,6 +127,7 @@ void CardItem::retranslateUi()
aFlip->setText(tr("&Flip")); aFlip->setText(tr("&Flip"));
aClone->setText(tr("&Clone")); aClone->setText(tr("&Clone"));
aAttach->setText(tr("&Attach to card...")); aAttach->setText(tr("&Attach to card..."));
aAttach->setShortcut(tr("Ctrl+A"));
aUnattach->setText(tr("Unattac&h")); aUnattach->setText(tr("Unattac&h"));
aSetPT->setText(tr("Set &P/T...")); aSetPT->setText(tr("Set &P/T..."));
aSetAnnotation->setText(tr("&Set annotation...")); aSetAnnotation->setText(tr("&Set annotation..."));
@ -214,6 +224,23 @@ void CardItem::setPT(const QString &_pt)
update(); update();
} }
void CardItem::setAttachedTo(CardItem *_attachedTo)
{
if (attachedTo)
attachedTo->removeAttachedCard(this);
gridPoint.setX(-1);
attachedTo = _attachedTo;
if (attachedTo) {
attachedTo->addAttachedCard(this);
if (zone != attachedTo->getZone())
attachedTo->getZone()->reorganizeCards();
}
if (zone)
zone->reorganizeCards();
}
void CardItem::resetState() void CardItem::resetState()
{ {
attacking = false; attacking = false;
@ -221,6 +248,8 @@ void CardItem::resetState()
counters.clear(); counters.clear();
pt.clear(); pt.clear();
annotation.clear(); annotation.clear();
attachedTo = 0;
attachedCards.clear();
setTapped(false); setTapped(false);
setDoesntUntap(false); setDoesntUntap(false);
update(); update();
@ -273,7 +302,8 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
else if (event->modifiers().testFlag(Qt::ShiftModifier)) else if (event->modifiers().testFlag(Qt::ShiftModifier))
arrowColor = Qt::green; arrowColor = Qt::green;
ArrowDragItem *arrow = new ArrowDragItem(this, arrowColor); Player *arrowOwner = static_cast<TabGame *>(owner->parent())->getActiveLocalPlayer();
ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor);
scene()->addItem(arrow); scene()->addItem(arrow);
arrow->grabMouse(); arrow->grabMouse();
@ -282,10 +312,10 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
CardItem *c = qgraphicsitem_cast<CardItem *>(itemIterator.next()); CardItem *c = qgraphicsitem_cast<CardItem *>(itemIterator.next());
if (!c || (c == this)) if (!c || (c == this))
continue; continue;
if (c->parentItem() != parentItem()) if (c->getZone() != zone)
continue; continue;
ArrowDragItem *childArrow = new ArrowDragItem(c, arrowColor); ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor);
scene()->addItem(childArrow); scene()->addItem(childArrow);
arrow->addChildArrow(childArrow); arrow->addChildArrow(childArrow);
} }
@ -300,8 +330,6 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
createDragItem(id, event->pos(), event->scenePos(), faceDown); createDragItem(id, event->pos(), event->scenePos(), faceDown);
dragItem->grabMouse(); dragItem->grabMouse();
CardZone *zone = static_cast<CardZone *>(parentItem());
QList<QGraphicsItem *> sel = scene()->selectedItems(); QList<QGraphicsItem *> sel = scene()->selectedItems();
int j = 0; int j = 0;
for (int i = 0; i < sel.size(); i++) { for (int i = 0; i < sel.size(); i++) {
@ -324,9 +352,8 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
void CardItem::playCard(QGraphicsSceneMouseEvent *event) void CardItem::playCard(QGraphicsSceneMouseEvent *event)
{ {
CardZone *zone = static_cast<CardZone *>(parentItem());
// Do nothing if the card belongs to another player // Do nothing if the card belongs to another player
if (!zone->getPlayer()->getLocal()) if (!owner->getLocal())
return; return;
TableZone *tz = qobject_cast<TableZone *>(zone); TableZone *tz = qobject_cast<TableZone *>(zone);

View file

@ -15,7 +15,7 @@ const int MAX_COUNTERS_ON_CARD = 999;
class CardItem : public AbstractCardItem { class CardItem : public AbstractCardItem {
Q_OBJECT Q_OBJECT
private: private:
Player *owner; CardZone *zone;
int id; int id;
bool attacking; bool attacking;
bool facedown; bool facedown;
@ -26,6 +26,8 @@ private:
bool doesntUntap; bool doesntUntap;
QPoint gridPoint; QPoint gridPoint;
CardDragItem *dragItem; CardDragItem *dragItem;
CardItem *attachedTo;
QList<CardItem *> attachedCards;
QList<QAction *> aAddCounter, aSetCounter, aRemoveCounter; QList<QAction *> aAddCounter, aSetCounter, aRemoveCounter;
QAction *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone, QAction *aTap, *aUntap, *aDoesntUntap, *aAttach, *aUnattach, *aSetPT, *aSetAnnotation, *aFlip, *aClone,
@ -39,6 +41,8 @@ public:
CardItem(Player *_owner, const QString &_name = QString(), int _cardid = -1, QGraphicsItem *parent = 0); CardItem(Player *_owner, const QString &_name = QString(), int _cardid = -1, QGraphicsItem *parent = 0);
~CardItem(); ~CardItem();
void retranslateUi(); void retranslateUi();
CardZone *getZone() const { return zone; }
void setZone(CardZone *_zone) { zone = _zone; }
QMenu *getCardMenu() const { return cardMenu; } QMenu *getCardMenu() const { return cardMenu; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QPoint getGridPoint() const { return gridPoint; } QPoint getGridPoint() const { return gridPoint; }
@ -61,6 +65,11 @@ public:
void setPT(const QString &_pt); void setPT(const QString &_pt);
bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } bool getDestroyOnZoneChange() const { return destroyOnZoneChange; }
void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; }
CardItem *getAttachedTo() const { return attachedTo; }
void setAttachedTo(CardItem *_attachedTo);
void addAttachedCard(CardItem *card) { attachedCards.append(card); }
void removeAttachedCard(CardItem *card) { attachedCards.removeAt(attachedCards.indexOf(card)); }
const QList<CardItem *> &getAttachedCards() const { return attachedCards; }
void resetState(); void resetState();
void processCardInfo(ServerInfo_Card *info); void processCardInfo(ServerInfo_Card *info);

View file

@ -27,8 +27,15 @@ void CardZone::retranslateUi()
void CardZone::clearContents() void CardZone::clearContents()
{ {
for (int i = 0; i < cards.size(); i++) for (int i = 0; i < cards.size(); i++) {
// If an incorrectly implemented server doesn't return attached cards to whom they belong before dropping a player,
// we have to return them to avoid a crash.
const QList<CardItem *> &attachedCards = cards[i]->getAttachedCards();
for (int j = 0; j < attachedCards.size(); ++j)
attachedCards[j]->setParentItem(attachedCards[j]->getZone());
delete cards.at(i); delete cards.at(i);
}
cards.clear(); cards.clear();
emit cardCountChanged(); emit cardCountChanged();
} }
@ -93,6 +100,7 @@ void CardZone::addCard(CardItem *card, bool reorganize, int x, int y)
if ((x <= view->getCards().size()) || (view->getNumberCards() == -1)) if ((x <= view->getCards().size()) || (view->getNumberCards() == -1))
view->addCard(new CardItem(player, card->getName(), card->getId()), reorganize, x, y); view->addCard(new CardItem(player, card->getName(), card->getId()), reorganize, x, y);
card->setZone(this);
addCardImpl(card, x, y); addCardImpl(card, x, y);
if (reorganize) if (reorganize)

View file

@ -60,7 +60,7 @@ void DeckViewCardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
} }
DeckViewCard::DeckViewCard(const QString &_name, const QString &_originZone, QGraphicsItem *parent) DeckViewCard::DeckViewCard(const QString &_name, const QString &_originZone, QGraphicsItem *parent)
: AbstractCardItem(_name, parent), originZone(_originZone), dragItem(0) : AbstractCardItem(_name, 0, parent), originZone(_originZone), dragItem(0)
{ {
} }

View file

@ -207,6 +207,16 @@ void MessageLogWidget::logDestroyCard(Player *player, QString cardName)
append(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName)))); append(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
} }
void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName)
{
append(tr("%1 attaches %2 to %3's %4.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(targetCardName))));
}
void MessageLogWidget::logUnattachCard(Player *player, QString cardName)
{
append(tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
}
void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt) void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt)
{ {
append(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt)))); append(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt))));
@ -341,6 +351,8 @@ void MessageLogWidget::connectToPlayer(Player *player)
connect(player, SIGNAL(logSetAnnotation(Player *, QString, QString)), this, SLOT(logSetAnnotation(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(logMoveCard(Player *, QString, CardZone *, int, CardZone *, int)), this, SLOT(logMoveCard(Player *, QString, CardZone *, int, CardZone *, int)));
connect(player, SIGNAL(logDestroyCard(Player *, QString)), this, SLOT(logDestroyCard(Player *, QString))); connect(player, SIGNAL(logDestroyCard(Player *, QString)), this, SLOT(logDestroyCard(Player *, QString)));
connect(player, SIGNAL(logAttachCard(Player *, QString, Player *, QString)), this, SLOT(logAttachCard(Player *, QString, Player *, QString)));
connect(player, SIGNAL(logUnattachCard(Player *, QString)), this, SLOT(logUnattachCard(Player *, QString)));
connect(player, SIGNAL(logDumpZone(Player *, CardZone *, int)), this, SLOT(logDumpZone(Player *, 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 *))); connect(player, SIGNAL(logStopDumpZone(Player *, CardZone *)), this, SLOT(logStopDumpZone(Player *, CardZone *)));
connect(player, SIGNAL(logDrawCards(Player *, int)), this, SLOT(logDrawCards(Player *, int))); connect(player, SIGNAL(logDrawCards(Player *, int)), this, SLOT(logDrawCards(Player *, int)));

View file

@ -40,6 +40,8 @@ public slots:
void logDrawCards(Player *player, int number); void logDrawCards(Player *player, int number);
void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX); void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX);
void logDestroyCard(Player *player, QString cardName); void logDestroyCard(Player *player, QString cardName);
void logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName);
void logUnattachCard(Player *player, QString cardName);
void logCreateToken(Player *player, QString cardName, QString pt); void logCreateToken(Player *player, QString cardName, QString pt);
void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget); 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 logSetCardCounter(Player *player, QString cardName, int counterId, int value, int oldValue);

View file

@ -224,12 +224,13 @@ Player::~Player()
static_cast<GameScene *>(scene())->removePlayer(this); static_cast<GameScene *>(scene())->removePlayer(this);
clearArrows();
QMapIterator<QString, CardZone *> i(zones); QMapIterator<QString, CardZone *> i(zones);
while (i.hasNext()) while (i.hasNext())
delete i.next().value(); delete i.next().value();
clearCounters(); clearCounters();
clearArrows();
delete playerMenu; delete playerMenu;
} }
@ -501,7 +502,7 @@ void Player::eventCreateArrows(Event_CreateArrows *event)
if (targetCard) if (targetCard)
emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), targetCard->getOwner(), targetCard->getName(), false); emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), targetCard->getOwner(), targetCard->getName(), false);
else else
emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), static_cast<Player *>(arrow->getTargetItem()->parentItem()), QString(), true); emit logCreateArrow(this, startCard->getOwner(), startCard->getName(), arrow->getTargetItem()->getOwner(), QString(), true);
} }
} }
@ -677,6 +678,43 @@ void Player::eventDestroyCard(Event_DestroyCard *event)
delete card; delete card;
} }
void Player::eventAttachCard(Event_AttachCard *event)
{
const QMap<int, Player *> &playerList = static_cast<TabGame *>(parent())->getPlayers();
int targetPlayerId = event->getTargetPlayerId();
Player *targetPlayer = 0;
CardZone *targetZone = 0;
CardItem *targetCard = 0;
if (targetPlayerId != -1)
targetPlayer = playerList.value(targetPlayerId, 0);
if (targetPlayer)
targetZone = targetPlayer->getZones().value(event->getTargetZone(), 0);
if (targetZone)
targetCard = targetZone->getCard(event->getTargetCardId(), QString());
CardZone *startZone = getZones().value(event->getStartZone(), 0);
if (!startZone)
return;
CardItem *startCard = startZone->getCard(event->getCardId(), QString());
if (!startCard)
return;
if (targetZone)
startCard->setParentItem(targetZone);
else
startCard->setParentItem(startZone);
startCard->setAttachedTo(targetCard);
startZone->reorganizeCards();
if ((startZone != targetZone) && targetZone)
targetZone->reorganizeCards();
if (targetCard)
emit logAttachCard(this, startCard->getName(), targetPlayer, targetCard->getName());
else
emit logUnattachCard(this, startCard->getName());
}
void Player::eventDrawCards(Event_DrawCards *event) void Player::eventDrawCards(Event_DrawCards *event)
{ {
CardZone *deck = zones.value("deck"); CardZone *deck = zones.value("deck");
@ -712,6 +750,7 @@ void Player::processGameEvent(GameEvent *event, GameEventContext *context)
case ItemId_Event_StopDumpZone: eventStopDumpZone(qobject_cast<Event_StopDumpZone *>(event)); break; case ItemId_Event_StopDumpZone: eventStopDumpZone(qobject_cast<Event_StopDumpZone *>(event)); break;
case ItemId_Event_MoveCard: eventMoveCard(qobject_cast<Event_MoveCard *>(event)); break; case ItemId_Event_MoveCard: eventMoveCard(qobject_cast<Event_MoveCard *>(event)); break;
case ItemId_Event_DestroyCard: eventDestroyCard(qobject_cast<Event_DestroyCard *>(event)); break; case ItemId_Event_DestroyCard: eventDestroyCard(qobject_cast<Event_DestroyCard *>(event)); break;
case ItemId_Event_AttachCard: eventAttachCard(qobject_cast<Event_AttachCard *>(event)); break;
case ItemId_Event_DrawCards: eventDrawCards(qobject_cast<Event_DrawCards *>(event)); break; case ItemId_Event_DrawCards: eventDrawCards(qobject_cast<Event_DrawCards *>(event)); break;
default: { default: {
qDebug() << "unhandled game event"; qDebug() << "unhandled game event";
@ -746,8 +785,12 @@ void Player::processPlayerInfo(ServerInfo_Player *info)
while (zoneIt.hasNext()) while (zoneIt.hasNext())
zoneIt.next().value()->clearContents(); zoneIt.next().value()->clearContents();
for (int i = 0; i < info->getZoneList().size(); ++i) { clearCounters();
ServerInfo_Zone *zoneInfo = info->getZoneList()[i]; clearArrows();
QList<ServerInfo_Zone *> zl = info->getZoneList();
for (int i = 0; i < zl.size(); ++i) {
ServerInfo_Zone *zoneInfo = zl[i];
CardZone *zone = zones.value(zoneInfo->getName(), 0); CardZone *zone = zones.value(zoneInfo->getName(), 0);
if (!zone) if (!zone)
continue; continue;
@ -766,14 +809,38 @@ void Player::processPlayerInfo(ServerInfo_Player *info)
zone->reorganizeCards(); zone->reorganizeCards();
} }
clearCounters(); QList<ServerInfo_Counter *> cl = info->getCounterList();
for (int i = 0; i < info->getCounterList().size(); ++i) { for (int i = 0; i < cl.size(); ++i) {
addCounter(info->getCounterList().at(i)); addCounter(cl.at(i));
} }
clearArrows(); QList<ServerInfo_Arrow *> al = info->getArrowList();
for (int i = 0; i < info->getArrowList().size(); ++i) for (int i = 0; i < al.size(); ++i)
addArrow(info->getArrowList().at(i)); addArrow(al.at(i));
}
void Player::processCardAttachment(ServerInfo_Player *info)
{
QList<ServerInfo_Zone *> zl = info->getZoneList();
for (int i = 0; i < zl.size(); ++i) {
ServerInfo_Zone *zoneInfo = zl[i];
CardZone *zone = zones.value(zoneInfo->getName(), 0);
if (!zone)
continue;
const QList<ServerInfo_Card *> &cardList = zoneInfo->getCardList();
for (int j = 0; j < cardList.size(); ++j) {
ServerInfo_Card *cardInfo = cardList[j];
if (cardInfo->getAttachPlayerId() != -1) {
CardItem *startCard = zone->getCard(cardInfo->getId(), QString());
CardItem *targetCard = static_cast<TabGame *>(parent())->getCard(cardInfo->getAttachPlayerId(), cardInfo->getAttachZone(), cardInfo->getAttachCardId());
if (!targetCard)
continue;
startCard->setAttachedTo(targetCard);
}
}
}
} }
void Player::addCard(CardItem *c) void Player::addCard(CardItem *c)
@ -924,34 +991,34 @@ void Player::cardMenuAction()
switch (a->data().toInt()) { switch (a->data().toInt()) {
case 0: case 0:
if (!card->getTapped()) if (!card->getTapped())
commandList.append(new Command_SetCardAttr(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "tapped", "1")); commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "tapped", "1"));
break; break;
case 1: case 1:
if (card->getTapped()) if (card->getTapped())
commandList.append(new Command_SetCardAttr(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "tapped", "0")); commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "tapped", "0"));
break; break;
case 2: case 2:
commandList.append(new Command_SetCardAttr(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "doesnt_untap", QString::number(!card->getDoesntUntap()))); commandList.append(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "doesnt_untap", QString::number(!card->getDoesntUntap())));
break; break;
case 3: { case 3: {
QString zone = qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(); QString zone = card->getZone()->getName();
commandList.append(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; break;
} }
case 4: case 4:
commandList.append(new Command_CreateToken(-1, static_cast<CardZone *>(card->parentItem())->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), -1, card->getGridPoint().y())); commandList.append(new Command_CreateToken(-1, card->getZone()->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), -1, card->getGridPoint().y()));
break; break;
case 5: case 5:
commandList.append(new Command_MoveCard(-1, static_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "deck", 0, 0, false)); commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "deck", 0, 0, false));
break; break;
case 6: case 6:
commandList.append(new Command_MoveCard(-1, static_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "deck", -1, 0, false)); commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "deck", -1, 0, false));
break; break;
case 7: case 7:
commandList.append(new Command_MoveCard(-1, static_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "grave", 0, 0, false)); commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "grave", 0, 0, false));
break; break;
case 8: case 8:
commandList.append(new Command_MoveCard(-1, static_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "rfg", 0, 0, false)); commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), "rfg", 0, 0, false));
break; break;
default: ; default: ;
} }
@ -976,7 +1043,7 @@ void Player::actSetPT()
i.toFront(); i.toFront();
while (i.hasNext()) { while (i.hasNext()) {
CardItem *card = static_cast<CardItem *>(i.next()); CardItem *card = static_cast<CardItem *>(i.next());
sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "pt", pt)); sendGameCommand(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "pt", pt));
} }
} }
@ -998,16 +1065,22 @@ void Player::actSetAnnotation()
i.toFront(); i.toFront();
while (i.hasNext()) { while (i.hasNext()) {
CardItem *card = static_cast<CardItem *>(i.next()); CardItem *card = static_cast<CardItem *>(i.next());
sendGameCommand(new Command_SetCardAttr(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), "annotation", annotation)); sendGameCommand(new Command_SetCardAttr(-1, card->getZone()->getName(), card->getId(), "annotation", annotation));
} }
} }
void Player::actAttach() void Player::actAttach()
{ {
CardItem *card = static_cast<CardItem *>(sender()->parent());
ArrowAttachItem *arrow = new ArrowAttachItem(card);
scene()->addItem(arrow);
arrow->grabMouse();
} }
void Player::actUnattach() void Player::actUnattach()
{ {
CardItem *card = static_cast<CardItem *>(sender()->parent());
sendGameCommand(new Command_AttachCard(-1, card->getZone()->getName(), card->getId(), -1, QString(), -1));
} }
void Player::actCardCounterTrigger() void Player::actCardCounterTrigger()
@ -1022,7 +1095,7 @@ void Player::actCardCounterTrigger()
while (i.hasNext()) { while (i.hasNext()) {
CardItem *card = static_cast<CardItem *>(i.next()); CardItem *card = static_cast<CardItem *>(i.next());
if (card->getCounters().value(counterId, 0) < MAX_COUNTERS_ON_CARD) if (card->getCounters().value(counterId, 0) < MAX_COUNTERS_ON_CARD)
sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) + 1)); sendGameCommand(new Command_SetCardCounter(-1, card->getZone()->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) + 1));
} }
break; break;
} }
@ -1031,7 +1104,7 @@ void Player::actCardCounterTrigger()
while (i.hasNext()) { while (i.hasNext()) {
CardItem *card = static_cast<CardItem *>(i.next()); CardItem *card = static_cast<CardItem *>(i.next());
if (card->getCounters().value(counterId, 0)) if (card->getCounters().value(counterId, 0))
sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) - 1)); sendGameCommand(new Command_SetCardCounter(-1, card->getZone()->getName(), card->getId(), counterId, card->getCounters().value(counterId, 0) - 1));
} }
break; break;
} }
@ -1044,7 +1117,7 @@ void Player::actCardCounterTrigger()
QListIterator<QGraphicsItem *> i(scene()->selectedItems()); QListIterator<QGraphicsItem *> i(scene()->selectedItems());
while (i.hasNext()) { while (i.hasNext()) {
CardItem *card = static_cast<CardItem *>(i.next()); CardItem *card = static_cast<CardItem *>(i.next());
sendGameCommand(new Command_SetCardCounter(-1, qgraphicsitem_cast<CardZone *>(card->parentItem())->getName(), card->getId(), counterId, number)); sendGameCommand(new Command_SetCardCounter(-1, card->getZone()->getName(), card->getId(), counterId, number));
} }
break; break;
} }

View file

@ -40,6 +40,7 @@ class Event_DumpZone;
class Event_StopDumpZone; class Event_StopDumpZone;
class Event_MoveCard; class Event_MoveCard;
class Event_DestroyCard; class Event_DestroyCard;
class Event_AttachCard;
class Event_DrawCards; class Event_DrawCards;
class Player : public QObject, public QGraphicsItem { class Player : public QObject, public QGraphicsItem {
@ -55,6 +56,8 @@ signals:
void logDrawCards(Player *player, int number); void logDrawCards(Player *player, int number);
void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX); void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX);
void logDestroyCard(Player *player, QString cardName); void logDestroyCard(Player *player, QString cardName);
void logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName);
void logUnattachCard(Player *player, QString cardName);
void logSetCardCounter(Player *player, QString cardName, int counterId, 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 logSetTapped(Player *player, QString cardName, bool tapped);
void logSetCounter(Player *player, QString counterName, int value, int oldValue); void logSetCounter(Player *player, QString counterName, int value, int oldValue);
@ -144,6 +147,7 @@ private:
void eventStopDumpZone(Event_StopDumpZone *event); void eventStopDumpZone(Event_StopDumpZone *event);
void eventMoveCard(Event_MoveCard *event); void eventMoveCard(Event_MoveCard *event);
void eventDestroyCard(Event_DestroyCard *event); void eventDestroyCard(Event_DestroyCard *event);
void eventAttachCard(Event_AttachCard *event);
void eventDrawCards(Event_DrawCards *event); void eventDrawCards(Event_DrawCards *event);
public: public:
static const int counterAreaWidth = 65; static const int counterAreaWidth = 65;
@ -189,6 +193,8 @@ public:
void processSceneSizeChange(const QSizeF &newSize); void processSceneSizeChange(const QSizeF &newSize);
void processPlayerInfo(ServerInfo_Player *info); void processPlayerInfo(ServerInfo_Player *info);
void processCardAttachment(ServerInfo_Player *info);
void processGameEvent(GameEvent *event, GameEventContext *context); void processGameEvent(GameEvent *event, GameEventContext *context);
void sendGameCommand(GameCommand *command); void sendGameCommand(GameCommand *command);
void sendCommandContainer(CommandContainer *cont); void sendCommandContainer(CommandContainer *cont);

View file

@ -1,8 +1,9 @@
#include "playertarget.h" #include "playertarget.h"
#include "player.h"
#include <QPainter> #include <QPainter>
PlayerTarget::PlayerTarget(const QString &_name, int _maxWidth, QGraphicsItem *parent) PlayerTarget::PlayerTarget(const QString &_name, int _maxWidth, Player *_owner)
: ArrowTarget(parent), name(_name), maxWidth(_maxWidth) : ArrowTarget(_owner, _owner), name(_name), maxWidth(_maxWidth)
{ {
font = QFont("Times"); font = QFont("Times");
font.setStyleHint(QFont::Serif); font.setStyleHint(QFont::Serif);

View file

@ -4,6 +4,8 @@
#include "arrowtarget.h" #include "arrowtarget.h"
#include <QFont> #include <QFont>
class Player;
class PlayerTarget : public ArrowTarget { class PlayerTarget : public ArrowTarget {
private: private:
QString name; QString name;
@ -13,7 +15,7 @@ public:
enum { Type = typePlayerTarget }; enum { Type = typePlayerTarget };
int type() const { return Type; } int type() const { return Type; }
PlayerTarget(const QString &_name, int _maxWidth, QGraphicsItem *parent = 0); PlayerTarget(const QString &_name, int _maxWidth, Player *parent = 0);
QRectF boundingRect() const; QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
}; };

View file

@ -316,7 +316,8 @@ void TabGame::startGame()
void TabGame::stopGame() void TabGame::stopGame()
{ {
currentPhase = -1; currentPhase = -1;
activePlayer = -1;
playerListWidget->setActivePlayer(-1); playerListWidget->setActivePlayer(-1);
playerListWidget->setGameStarted(false); playerListWidget->setGameStarted(false);
started = false; started = false;
@ -365,6 +366,16 @@ void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventCont
} }
} }
} }
for (int i = 0; i < plList.size(); ++i) {
ServerInfo_Player *pl = plList[i];
ServerInfo_PlayerProperties *prop = pl->getProperties();
if (!prop->getSpectator()) {
Player *player = players.value(prop->getPlayerId(), 0);
if (!player)
continue;
player->processCardAttachment(pl);
}
}
if (event->getGameStarted() && !started) { if (event->getGameStarted() && !started) {
startGame(); startGame();
if (!resuming) if (!resuming)
@ -444,6 +455,7 @@ Player *TabGame::setActivePlayer(int id)
Player *player = players.value(id, 0); Player *player = players.value(id, 0);
if (!player) if (!player)
return 0; return 0;
activePlayer = id;
playerListWidget->setActivePlayer(id); playerListWidget->setActivePlayer(id);
QMapIterator<int, Player *> i(players); QMapIterator<int, Player *> i(players);
while (i.hasNext()) { while (i.hasNext()) {
@ -547,3 +559,33 @@ void TabGame::sideboardPlanChanged()
QList<MoveCardToZone *> newPlan = deckView->getSideboardPlan(); QList<MoveCardToZone *> newPlan = deckView->getSideboardPlan();
client->sendCommand(new Command_SetSideboardPlan(gameId, newPlan)); client->sendCommand(new Command_SetSideboardPlan(gameId, newPlan));
} }
CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const
{
Player *player = players.value(playerId, 0);
if (!player)
return 0;
CardZone *zone = player->getZones().value(zoneName, 0);
if (!zone)
return 0;
return zone->getCard(cardId, QString());
}
Player *TabGame::getActiveLocalPlayer() const
{
Player *active = players.value(activePlayer, 0);
if (active)
if (active->getLocal())
return active;
QMapIterator<int, Player *> playerIterator(players);
while (playerIterator.hasNext()) {
Player *temp = playerIterator.next().value();
if (temp->getLocal())
return temp;
}
return 0;
}

View file

@ -66,6 +66,7 @@ private:
bool started; bool started;
bool resuming; bool resuming;
int currentPhase; int currentPhase;
int activePlayer;
QPushButton *loadLocalButton, *loadRemoteButton; QPushButton *loadLocalButton, *loadRemoteButton;
ReadyStartButton *readyStartButton; ReadyStartButton *readyStartButton;
@ -123,11 +124,13 @@ public:
~TabGame(); ~TabGame();
void retranslateUi(); void retranslateUi();
const QMap<int, Player *> &getPlayers() const { return players; } const QMap<int, Player *> &getPlayers() const { return players; }
CardItem *getCard(int playerId, const QString &zoneName, int cardId) const;
int getGameId() const { return gameId; } int getGameId() const { return gameId; }
QString getTabText() const { return tr("Game %1: %2").arg(gameId).arg(gameDescription); } QString getTabText() const { return tr("Game %1: %2").arg(gameId).arg(gameDescription); }
bool getSpectator() const { return spectator; } bool getSpectator() const { return spectator; }
bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } bool getSpectatorsCanTalk() const { return spectatorsCanTalk; }
bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; }
Player *getActiveLocalPlayer() const;
void processGameEventContainer(GameEventContainer *cont); void processGameEventContainer(GameEventContainer *cont);
public slots: public slots:

View file

@ -4,6 +4,7 @@
#include "client.h" #include "client.h"
#include "protocol_items.h" #include "protocol_items.h"
#include "settingscache.h" #include "settingscache.h"
#include "arrowitem.h"
TableZone::TableZone(Player *_p, QGraphicsItem *parent) TableZone::TableZone(Player *_p, QGraphicsItem *parent)
: CardZone(_p, "table", true, false, true, parent), active(false) : CardZone(_p, "table", true, false, true, parent), active(false)
@ -91,17 +92,61 @@ void TableZone::handleDropEventByGrid(int cardId, CardZone *startZone, const QPo
void TableZone::reorganizeCards() void TableZone::reorganizeCards()
{ {
QList<ArrowItem *> arrowsToUpdate;
// Calculate table grid distortion so that the mapping functions work properly
gridPointWidth.clear();
for (int i = 0; i < cards.size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
QPointF mapPoint = mapFromGrid(cards[i]->getGridPos()); QPoint gridPoint = cards[i]->getGridPos();
if (gridPoint.x() == -1)
continue;
gridPointWidth.insert(gridPoint.x() + gridPoint.y() * 1000, CARD_WIDTH * (1 + cards[i]->getAttachedCards().size() / 3.0));
}
for (int i = 0; i < cards.size(); ++i) {
QPoint gridPoint = cards[i]->getGridPos();
if (gridPoint.x() == -1)
continue;
QPointF mapPoint = mapFromGrid(gridPoint);
qreal x = mapPoint.x(); qreal x = mapPoint.x();
qreal y = mapPoint.y(); qreal y = mapPoint.y();
if (player->getMirrored()) if (player->getMirrored())
y = height - CARD_HEIGHT - y; y = height - CARD_HEIGHT - y;
cards[i]->setPos(x, y);
cards[i]->setZValue((y + CARD_HEIGHT) * 10000000 + x + 1000); int numberAttachedCards = cards[i]->getAttachedCards().size();
qreal actualX = x + numberAttachedCards * CARD_WIDTH / 3.0;
qreal actualY = y;
if (numberAttachedCards)
actualY += 5;
cards[i]->setPos(actualX, actualY);
cards[i]->setZValue((actualY + CARD_HEIGHT) * 10000000 + (actualX + 1) * 10000);
QListIterator<CardItem *> attachedCardIterator(cards[i]->getAttachedCards());
int j = 0;
while (attachedCardIterator.hasNext()) {
++j;
CardItem *attachedCard = attachedCardIterator.next();
qreal childX = actualX - j * CARD_WIDTH / 3.0;
qreal childY = y - 5;
attachedCard->setPos(childX, childY);
attachedCard->setZValue((childY + CARD_HEIGHT) * 10000000 + (childX + 1) * 10000);
arrowsToUpdate.append(attachedCard->getArrowsFrom());
arrowsToUpdate.append(attachedCard->getArrowsTo());
}
arrowsToUpdate.append(cards[i]->getArrowsFrom());
arrowsToUpdate.append(cards[i]->getArrowsTo());
} }
QSetIterator<ArrowItem *> arrowIterator(QSet<ArrowItem *>::fromList(arrowsToUpdate));
while (arrowIterator.hasNext())
arrowIterator.next()->updatePath();
resizeToContents(); resizeToContents();
update(); update();
} }
@ -164,11 +209,16 @@ QPointF TableZone::mapFromGrid(const QPoint &gridPoint) const
marginX + (CARD_WIDTH * gridPoint.x() + CARD_WIDTH * (gridPoint.x() / 3)) / 2, marginX + (CARD_WIDTH * gridPoint.x() + CARD_WIDTH * (gridPoint.x() / 3)) / 2,
boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y() + (gridPoint.x() % 3 * CARD_HEIGHT) / 3 boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y() + (gridPoint.x() % 3 * CARD_HEIGHT) / 3
); );
else else {
qreal x = marginX + 0.5 * CARD_WIDTH * gridPoint.x();
for (int i = 0; i < gridPoint.x(); ++i)
x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH);
return QPointF( return QPointF(
marginX + 3 * CARD_WIDTH * gridPoint.x() / 2, x,
boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y() boxLineWidth + (CARD_HEIGHT + paddingY) * gridPoint.y()
); );
}
} }
QPoint TableZone::mapToGrid(const QPointF &mapPoint) const QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
@ -184,18 +234,22 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
else if (y > height - CARD_HEIGHT) else if (y > height - CARD_HEIGHT)
y = height - CARD_HEIGHT; y = height - CARD_HEIGHT;
QPoint result = QPoint( int resultY = (int) (y / (CARD_HEIGHT + paddingY));
(int) (x / (1.5 * CARD_WIDTH)),
(int) (y / (CARD_HEIGHT + paddingY))
);
if ((result.y() == 3) && (settingsCache->getEconomicGrid())) if ((resultY == 3) && (settingsCache->getEconomicGrid()))
return QPoint( return QPoint(
(int) (x * 2 / CARD_WIDTH - floor(x / (2 * CARD_WIDTH))), (int) (x * 2 / CARD_WIDTH - floor(x / (2 * CARD_WIDTH))),
3 3
); );
else else {
return result; int resultX = -1;
qreal tempX = 0;
do {
++resultX;
tempX += gridPointWidth.value(resultY * 1000 + resultX, CARD_WIDTH) + 0.5 * CARD_WIDTH;
} while (tempX < x + 1);
return QPoint(resultX, resultY);
}
} }
QPointF TableZone::closestGridPoint(const QPointF &point) QPointF TableZone::closestGridPoint(const QPointF &point)

View file

@ -13,6 +13,7 @@ private:
static const int marginX = 20; static const int marginX = 20;
static const int minWidth = 20 * CARD_WIDTH / 2; static const int minWidth = 20 * CARD_WIDTH / 2;
QMap<int, int> gridPointWidth;
int width, height; int width, height;
int currentMinimumWidth; int currentMinimumWidth;
QPixmap bgPixmap; QPixmap bgPixmap;

View file

@ -155,107 +155,112 @@
<context> <context>
<name>CardItem</name> <name>CardItem</name>
<message> <message>
<location filename="../src/carditem.cpp" line="115"/> <location filename="../src/carditem.cpp" line="124"/>
<source>&amp;Tap</source> <source>&amp;Tap</source>
<translation>&amp;Tappen</translation> <translation>&amp;Tappen</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="116"/> <location filename="../src/carditem.cpp" line="125"/>
<source>&amp;Untap</source> <source>&amp;Untap</source>
<translation>E&amp;nttappen</translation> <translation>E&amp;nttappen</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="117"/> <location filename="../src/carditem.cpp" line="126"/>
<source>Toggle &amp;normal untapping</source> <source>Toggle &amp;normal untapping</source>
<translation>N&amp;ormales Enttappen umschalten</translation> <translation>N&amp;ormales Enttappen umschalten</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="118"/> <location filename="../src/carditem.cpp" line="127"/>
<source>&amp;Flip</source> <source>&amp;Flip</source>
<translation>&amp;Umdrehen</translation> <translation>&amp;Umdrehen</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="119"/> <location filename="../src/carditem.cpp" line="128"/>
<source>&amp;Clone</source> <source>&amp;Clone</source>
<translation>&amp;Kopieren</translation> <translation>&amp;Kopieren</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="120"/> <location filename="../src/carditem.cpp" line="129"/>
<source>&amp;Attach to card...</source> <source>&amp;Attach to card...</source>
<translation>&amp;An Karte anlegen...</translation> <translation>&amp;An Karte anlegen...</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="121"/> <location filename="../src/carditem.cpp" line="130"/>
<source>Ctrl+A</source>
<translation>Ctrl+A</translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="131"/>
<source>Unattac&amp;h</source> <source>Unattac&amp;h</source>
<translation>&amp;Von Karte lösen</translation> <translation>&amp;Von Karte lösen</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="122"/> <location filename="../src/carditem.cpp" line="132"/>
<source>Set &amp;P/T...</source> <source>Set &amp;P/T...</source>
<translation>&amp;Kampfwerte setzen...</translation> <translation>&amp;Kampfwerte setzen...</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="123"/> <location filename="../src/carditem.cpp" line="133"/>
<source>&amp;Set annotation...</source> <source>&amp;Set annotation...</source>
<translation>&amp;Hinweis setzen...</translation> <translation>&amp;Hinweis setzen...</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="125"/> <location filename="../src/carditem.cpp" line="135"/>
<source>red</source> <source>red</source>
<translation>rot</translation> <translation>rot</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="126"/> <location filename="../src/carditem.cpp" line="136"/>
<source>yellow</source> <source>yellow</source>
<translation>gelb</translation> <translation>gelb</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="127"/> <location filename="../src/carditem.cpp" line="137"/>
<source>green</source> <source>green</source>
<translation>grün</translation> <translation>grün</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="129"/> <location filename="../src/carditem.cpp" line="139"/>
<source>&amp;Add counter (%1)</source> <source>&amp;Add counter (%1)</source>
<translation>Zählmarke &amp;hinzufügen (%1)</translation> <translation>Zählmarke &amp;hinzufügen (%1)</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="131"/> <location filename="../src/carditem.cpp" line="141"/>
<source>&amp;Remove counter (%1)</source> <source>&amp;Remove counter (%1)</source>
<translation>Zählmarke &amp;entfernen (%1)</translation> <translation>Zählmarke &amp;entfernen (%1)</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="133"/> <location filename="../src/carditem.cpp" line="143"/>
<source>&amp;Set counters (%1)...</source> <source>&amp;Set counters (%1)...</source>
<translation>Zählmarken &amp;setzen (%1)...</translation> <translation>Zählmarken &amp;setzen (%1)...</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="134"/> <location filename="../src/carditem.cpp" line="144"/>
<source>&amp;top of library</source> <source>&amp;top of library</source>
<translation>&amp;auf die Bibliothek</translation> <translation>&amp;auf die Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="135"/> <location filename="../src/carditem.cpp" line="145"/>
<source>&amp;bottom of library</source> <source>&amp;bottom of library</source>
<translation>&amp;unter die Bibliothek</translation> <translation>&amp;unter die Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="136"/> <location filename="../src/carditem.cpp" line="146"/>
<source>&amp;graveyard</source> <source>&amp;graveyard</source>
<translation>in den &amp;Friedhof</translation> <translation>in den &amp;Friedhof</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="137"/> <location filename="../src/carditem.cpp" line="147"/>
<source>Ctrl+Del</source> <source>Ctrl+Del</source>
<translation>Ctrl+Del</translation> <translation>Ctrl+Del</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="138"/> <location filename="../src/carditem.cpp" line="148"/>
<source>&amp;exile</source> <source>&amp;exile</source>
<translation>ins &amp;Exil</translation> <translation>ins &amp;Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="140"/> <location filename="../src/carditem.cpp" line="150"/>
<source>&amp;Move to</source> <source>&amp;Move to</source>
<translation>&amp;Verschieben</translation> <translation>&amp;Verschieben</translation>
</message> </message>
@ -263,112 +268,112 @@
<context> <context>
<name>CardZone</name> <name>CardZone</name>
<message> <message>
<location filename="../src/cardzone.cpp" line="41"/> <location filename="../src/cardzone.cpp" line="48"/>
<location filename="../src/cardzone.cpp" line="43"/> <location filename="../src/cardzone.cpp" line="50"/>
<source>his hand</source> <source>his hand</source>
<translation>seine Hand</translation> <translation>seine Hand</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="41"/> <location filename="../src/cardzone.cpp" line="48"/>
<location filename="../src/cardzone.cpp" line="43"/> <location filename="../src/cardzone.cpp" line="50"/>
<source>%1&apos;s hand</source> <source>%1&apos;s hand</source>
<translation>%1s Hand</translation> <translation>%1s Hand</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="42"/> <location filename="../src/cardzone.cpp" line="49"/>
<source>of his hand</source> <source>of his hand</source>
<translation>seiner Hand</translation> <translation>seiner Hand</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="42"/> <location filename="../src/cardzone.cpp" line="49"/>
<source>of %1&apos;s hand</source> <source>of %1&apos;s hand</source>
<translation>von %1s Hand</translation> <translation>von %1s Hand</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="47"/> <location filename="../src/cardzone.cpp" line="54"/>
<location filename="../src/cardzone.cpp" line="49"/> <location filename="../src/cardzone.cpp" line="56"/>
<source>his library</source> <source>his library</source>
<translation>seine Bibliothek</translation> <translation>seine Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="47"/> <location filename="../src/cardzone.cpp" line="54"/>
<location filename="../src/cardzone.cpp" line="49"/> <location filename="../src/cardzone.cpp" line="56"/>
<source>%1&apos;s library</source> <source>%1&apos;s library</source>
<translation>%1s Bibliothek</translation> <translation>%1s Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="48"/> <location filename="../src/cardzone.cpp" line="55"/>
<source>of his library</source> <source>of his library</source>
<translation>seiner Bibliothek</translation> <translation>seiner Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="48"/> <location filename="../src/cardzone.cpp" line="55"/>
<source>of %1&apos;s library</source> <source>of %1&apos;s library</source>
<translation>von %1s Bibliothek</translation> <translation>von %1s Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="53"/> <location filename="../src/cardzone.cpp" line="60"/>
<location filename="../src/cardzone.cpp" line="55"/> <location filename="../src/cardzone.cpp" line="62"/>
<source>his graveyard</source> <source>his graveyard</source>
<translation>sein Friedhof</translation> <translation>sein Friedhof</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="53"/> <location filename="../src/cardzone.cpp" line="60"/>
<location filename="../src/cardzone.cpp" line="55"/> <location filename="../src/cardzone.cpp" line="62"/>
<source>%1&apos;s graveyard</source> <source>%1&apos;s graveyard</source>
<translation>%1s Friedhof</translation> <translation>%1s Friedhof</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="54"/> <location filename="../src/cardzone.cpp" line="61"/>
<source>of his graveyard</source> <source>of his graveyard</source>
<translation>seines Friedhofs</translation> <translation>seines Friedhofs</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="54"/> <location filename="../src/cardzone.cpp" line="61"/>
<source>of %1&apos;s graveyard</source> <source>of %1&apos;s graveyard</source>
<translation>von %1s Friedhof</translation> <translation>von %1s Friedhof</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="59"/> <location filename="../src/cardzone.cpp" line="66"/>
<location filename="../src/cardzone.cpp" line="61"/> <location filename="../src/cardzone.cpp" line="68"/>
<source>his exile</source> <source>his exile</source>
<translation>sein Exil</translation> <translation>sein Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="59"/> <location filename="../src/cardzone.cpp" line="66"/>
<location filename="../src/cardzone.cpp" line="61"/> <location filename="../src/cardzone.cpp" line="68"/>
<source>%1&apos;s exile</source> <source>%1&apos;s exile</source>
<translation>%1s Exil</translation> <translation>%1s Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="60"/> <location filename="../src/cardzone.cpp" line="67"/>
<source>of his exile</source> <source>of his exile</source>
<translation>seines Exils</translation> <translation>seines Exils</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="60"/> <location filename="../src/cardzone.cpp" line="67"/>
<source>of %1&apos;s exile</source> <source>of %1&apos;s exile</source>
<translation>von %1s Exil</translation> <translation>von %1s Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="65"/> <location filename="../src/cardzone.cpp" line="72"/>
<location filename="../src/cardzone.cpp" line="67"/> <location filename="../src/cardzone.cpp" line="74"/>
<source>his sideboard</source> <source>his sideboard</source>
<translation>sein Sideboard</translation> <translation>sein Sideboard</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="65"/> <location filename="../src/cardzone.cpp" line="72"/>
<location filename="../src/cardzone.cpp" line="67"/> <location filename="../src/cardzone.cpp" line="74"/>
<source>%1&apos;s sideboard</source> <source>%1&apos;s sideboard</source>
<translation>%1s Sideboard</translation> <translation>%1s Sideboard</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="66"/> <location filename="../src/cardzone.cpp" line="73"/>
<source>of his sideboard</source> <source>of his sideboard</source>
<translation>seines Sideboards</translation> <translation>seines Sideboards</translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="66"/> <location filename="../src/cardzone.cpp" line="73"/>
<source>of %1&apos;s sideboard</source> <source>of %1&apos;s sideboard</source>
<translation>von %1s Sideboard</translation> <translation>von %1s Sideboard</translation>
</message> </message>
@ -1762,11 +1767,21 @@
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="212"/> <location filename="../src/messagelogwidget.cpp" line="212"/>
<source>%1 attaches %2 to %3&apos;s %4.</source>
<translation>%1 legt %2 an %3s %4 an.</translation>
</message>
<message>
<location filename="../src/messagelogwidget.cpp" line="217"/>
<source>%1 unattaches %2.</source>
<translation>%1 löst %2 ab.</translation>
</message>
<message>
<location filename="../src/messagelogwidget.cpp" line="222"/>
<source>%1 creates token: %2%3.</source> <source>%1 creates token: %2%3.</source>
<translation>%1 erstellt Token: %2%3.</translation> <translation>%1 erstellt Token: %2%3.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="218"/> <location filename="../src/messagelogwidget.cpp" line="228"/>
<source>%1 points from %2&apos;s %3 to %4.</source> <source>%1 points from %2&apos;s %3 to %4.</source>
<translation>%1 zeigt von %2s %3 auf %4.</translation> <translation>%1 zeigt von %2s %3 auf %4.</translation>
</message> </message>
@ -1775,12 +1790,12 @@
<translation type="obsolete">%1 erstellt einen Spielstein: %2 (%3).</translation> <translation type="obsolete">%1 erstellt einen Spielstein: %2 (%3).</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="225"/> <location filename="../src/messagelogwidget.cpp" line="235"/>
<source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source> <source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source>
<translation>%1 zeigt von %2s %3 auf %4s %5.</translation> <translation>%1 zeigt von %2s %3 auf %4s %5.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<location filename="../src/messagelogwidget.cpp" line="240"/> <location filename="../src/messagelogwidget.cpp" line="250"/>
<source>%1 places %n counter(s) (%2) on %3 (now %4).</source> <source>%1 places %n counter(s) (%2) on %3 (now %4).</source>
<translation> <translation>
<numerusform>%1 legt eine Marke (%2) auf %3 (jetzt %4).</numerusform> <numerusform>%1 legt eine Marke (%2) auf %3 (jetzt %4).</numerusform>
@ -1788,7 +1803,7 @@
</translation> </translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<location filename="../src/messagelogwidget.cpp" line="242"/> <location filename="../src/messagelogwidget.cpp" line="252"/>
<source>%1 removes %n counter(s) (%2) from %3 (now %4).</source> <source>%1 removes %n counter(s) (%2) from %3 (now %4).</source>
<translation> <translation>
<numerusform>%1 entfernt eine Marke (%2) von %3 (jetzt %4).</numerusform> <numerusform>%1 entfernt eine Marke (%2) von %3 (jetzt %4).</numerusform>
@ -1796,37 +1811,37 @@
</translation> </translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="245"/> <location filename="../src/messagelogwidget.cpp" line="255"/>
<source>red</source> <source>red</source>
<translation>rot</translation> <translation>rot</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="246"/> <location filename="../src/messagelogwidget.cpp" line="256"/>
<source>yellow</source> <source>yellow</source>
<translation>gelb</translation> <translation>gelb</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="247"/> <location filename="../src/messagelogwidget.cpp" line="257"/>
<source>green</source> <source>green</source>
<translation>grün</translation> <translation>grün</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="266"/> <location filename="../src/messagelogwidget.cpp" line="276"/>
<source>%1 sets counter %2 to %3 (%4%5).</source> <source>%1 sets counter %2 to %3 (%4%5).</source>
<translation>%1 setzt Zähler %2 auf %3 (%4%5).</translation> <translation>%1 setzt Zähler %2 auf %3 (%4%5).</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="281"/> <location filename="../src/messagelogwidget.cpp" line="291"/>
<source>%1 sets PT of %2 to %3.</source> <source>%1 sets PT of %2 to %3.</source>
<translation>%1 setzt Kampfwerte von %2 auf %3.</translation> <translation>%1 setzt Kampfwerte von %2 auf %3.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="286"/> <location filename="../src/messagelogwidget.cpp" line="296"/>
<source>%1 sets annotation of %2 to %3.</source> <source>%1 sets annotation of %2 to %3.</source>
<translation>%1 versieht %2 mit dem Hinweis %3.</translation> <translation>%1 versieht %2 mit dem Hinweis %3.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="292"/> <location filename="../src/messagelogwidget.cpp" line="302"/>
<source>%1 is looking at the top %2 cards %3.</source> <source>%1 is looking at the top %2 cards %3.</source>
<translation>%1 sieht sich die obersten %2 Karten %3 an.</translation> <translation>%1 sieht sich die obersten %2 Karten %3 an.</translation>
</message> </message>
@ -1923,7 +1938,7 @@
<translation type="obsolete">%1 entfernt %2 Zählmarken von %3 (jetzt %4).</translation> <translation type="obsolete">%1 entfernt %2 Zählmarken von %3 (jetzt %4).</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="261"/> <location filename="../src/messagelogwidget.cpp" line="271"/>
<source>%1 %2 %3.</source> <source>%1 %2 %3.</source>
<translation>%1 %2 %3.</translation> <translation>%1 %2 %3.</translation>
</message> </message>
@ -1936,17 +1951,17 @@
<translation type="obsolete">%1 sieht sich die obersten %2 Karten %3 an.</translation> <translation type="obsolete">%1 sieht sich die obersten %2 Karten %3 an.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="294"/> <location filename="../src/messagelogwidget.cpp" line="304"/>
<source>%1 is looking at %2.</source> <source>%1 is looking at %2.</source>
<translation>%1 sieht sich %2 an.</translation> <translation>%1 sieht sich %2 an.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="300"/> <location filename="../src/messagelogwidget.cpp" line="310"/>
<source>%1 stops looking at %2.</source> <source>%1 stops looking at %2.</source>
<translation>%1 sieht sich %2 nicht mehr an.</translation> <translation>%1 sieht sich %2 nicht mehr an.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="324"/> <location filename="../src/messagelogwidget.cpp" line="334"/>
<source>ending phase</source> <source>ending phase</source>
<translation>die Zugendphase</translation> <translation>die Zugendphase</translation>
</message> </message>
@ -1975,57 +1990,57 @@
<translation type="obsolete">%1 sieht sich %2s %3 nicht mehr an</translation> <translation type="obsolete">%1 sieht sich %2s %3 nicht mehr an</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="306"/> <location filename="../src/messagelogwidget.cpp" line="316"/>
<source>It is now %1&apos;s turn.</source> <source>It is now %1&apos;s turn.</source>
<translation>%1 ist am Zug.</translation> <translation>%1 ist am Zug.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="314"/> <location filename="../src/messagelogwidget.cpp" line="324"/>
<source>untap step</source> <source>untap step</source>
<translation>das Enttappsegment</translation> <translation>das Enttappsegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="315"/> <location filename="../src/messagelogwidget.cpp" line="325"/>
<source>upkeep step</source> <source>upkeep step</source>
<translation>das Versorgungssegment</translation> <translation>das Versorgungssegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="316"/> <location filename="../src/messagelogwidget.cpp" line="326"/>
<source>draw step</source> <source>draw step</source>
<translation>das Ziehsegment</translation> <translation>das Ziehsegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="317"/> <location filename="../src/messagelogwidget.cpp" line="327"/>
<source>first main phase</source> <source>first main phase</source>
<translation>die erste Hauptphase</translation> <translation>die erste Hauptphase</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="318"/> <location filename="../src/messagelogwidget.cpp" line="328"/>
<source>beginning of combat step</source> <source>beginning of combat step</source>
<translation>das Anfangssegment der Kampfphase</translation> <translation>das Anfangssegment der Kampfphase</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="319"/> <location filename="../src/messagelogwidget.cpp" line="329"/>
<source>declare attackers step</source> <source>declare attackers step</source>
<translation>das Angreifer-Deklarieren-Segment</translation> <translation>das Angreifer-Deklarieren-Segment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="320"/> <location filename="../src/messagelogwidget.cpp" line="330"/>
<source>declare blockers step</source> <source>declare blockers step</source>
<translation>das Blocker-Deklarieren-Segment</translation> <translation>das Blocker-Deklarieren-Segment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="321"/> <location filename="../src/messagelogwidget.cpp" line="331"/>
<source>combat damage step</source> <source>combat damage step</source>
<translation>das Kampfschadenssegment</translation> <translation>das Kampfschadenssegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="322"/> <location filename="../src/messagelogwidget.cpp" line="332"/>
<source>end of combat step</source> <source>end of combat step</source>
<translation>das Endsegment der Kampfphase</translation> <translation>das Endsegment der Kampfphase</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="323"/> <location filename="../src/messagelogwidget.cpp" line="333"/>
<source>second main phase</source> <source>second main phase</source>
<translation>die zweite Hauptphase</translation> <translation>die zweite Hauptphase</translation>
</message> </message>
@ -2034,7 +2049,7 @@
<translation type="obsolete">das Ende-des-Zuges-Segment</translation> <translation type="obsolete">das Ende-des-Zuges-Segment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="326"/> <location filename="../src/messagelogwidget.cpp" line="336"/>
<source>It is now the %1.</source> <source>It is now the %1.</source>
<translation>Es ist nun %1.</translation> <translation>Es ist nun %1.</translation>
</message> </message>
@ -2043,12 +2058,12 @@
<translation type="obsolete">%1 bewegt %2 %3 nach %4</translation> <translation type="obsolete">%1 bewegt %2 %3 nach %4</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="261"/> <location filename="../src/messagelogwidget.cpp" line="271"/>
<source>taps</source> <source>taps</source>
<translation>tappt</translation> <translation>tappt</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="261"/> <location filename="../src/messagelogwidget.cpp" line="271"/>
<source>untaps</source> <source>untaps</source>
<translation>enttappt</translation> <translation>enttappt</translation>
</message> </message>
@ -2073,7 +2088,7 @@
<translation type="obsolete">%1 entfernt %2 Zählmarken von %3 (jetzt %4)</translation> <translation type="obsolete">%1 entfernt %2 Zählmarken von %3 (jetzt %4)</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="258"/> <location filename="../src/messagelogwidget.cpp" line="268"/>
<source>his permanents</source> <source>his permanents</source>
<translation>seine bleibenden Karten</translation> <translation>seine bleibenden Karten</translation>
</message> </message>
@ -2086,12 +2101,12 @@
<translation type="obsolete">%1 setzt Zähler &quot;%2&quot; auf %3 (%4%5)</translation> <translation type="obsolete">%1 setzt Zähler &quot;%2&quot; auf %3 (%4%5)</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="273"/> <location filename="../src/messagelogwidget.cpp" line="283"/>
<source>%1 sets %2 to not untap normally.</source> <source>%1 sets %2 to not untap normally.</source>
<translation>%1 setzt %2 auf explizites Enttappen.</translation> <translation>%1 setzt %2 auf explizites Enttappen.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="275"/> <location filename="../src/messagelogwidget.cpp" line="285"/>
<source>%1 sets %2 to untap normally.</source> <source>%1 sets %2 to untap normally.</source>
<translation>%1 setzt %2 auf normales Enttappen.</translation> <translation>%1 setzt %2 auf normales Enttappen.</translation>
</message> </message>
@ -2196,41 +2211,41 @@
<context> <context>
<name>Player</name> <name>Player</name>
<message> <message>
<location filename="../src/player.cpp" line="288"/> <location filename="../src/player.cpp" line="289"/>
<location filename="../src/player.cpp" line="292"/> <location filename="../src/player.cpp" line="293"/>
<location filename="../src/player.cpp" line="296"/> <location filename="../src/player.cpp" line="297"/>
<source>Move to &amp;top of library</source> <source>Move to &amp;top of library</source>
<translation>Oben auf die Biblio&amp;thek legen</translation> <translation>Oben auf die Biblio&amp;thek legen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="289"/> <location filename="../src/player.cpp" line="290"/>
<location filename="../src/player.cpp" line="293"/> <location filename="../src/player.cpp" line="294"/>
<location filename="../src/player.cpp" line="297"/> <location filename="../src/player.cpp" line="298"/>
<source>Move to &amp;bottom of library</source> <source>Move to &amp;bottom of library</source>
<translation>Unter die &amp;Bibliothek legen</translation> <translation>Unter die &amp;Bibliothek legen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="300"/> <location filename="../src/player.cpp" line="301"/>
<source>&amp;View library</source> <source>&amp;View library</source>
<translation>&amp;Zeige Bibliothek</translation> <translation>&amp;Zeige Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="301"/> <location filename="../src/player.cpp" line="302"/>
<source>F3</source> <source>F3</source>
<translation>F3</translation> <translation>F3</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="302"/> <location filename="../src/player.cpp" line="303"/>
<source>View &amp;top cards of library...</source> <source>View &amp;top cards of library...</source>
<translation>Zeige die oberen Kar&amp;ten der Bibliothek...</translation> <translation>Zeige die oberen Kar&amp;ten der Bibliothek...</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="281"/> <location filename="../src/player.cpp" line="282"/>
<source>&amp;View graveyard</source> <source>&amp;View graveyard</source>
<translation>&amp;Zeige Friedhof</translation> <translation>&amp;Zeige Friedhof</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="304"/> <location filename="../src/player.cpp" line="305"/>
<source>F4</source> <source>F4</source>
<translation>F4</translation> <translation>F4</translation>
</message> </message>
@ -2239,32 +2254,32 @@
<translation type="obsolete">Zeige ent&amp;fernte Karten</translation> <translation type="obsolete">Zeige ent&amp;fernte Karten</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="305"/> <location filename="../src/player.cpp" line="306"/>
<source>&amp;View sideboard</source> <source>&amp;View sideboard</source>
<translation>Zeige &amp;Sideboard</translation> <translation>Zeige &amp;Sideboard</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="283"/> <location filename="../src/player.cpp" line="284"/>
<source>Player &quot;%1&quot;</source> <source>Player &quot;%1&quot;</source>
<translation>Spieler &quot;%1&quot;</translation> <translation>Spieler &quot;%1&quot;</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="310"/> <location filename="../src/player.cpp" line="311"/>
<source>Take &amp;mulligan</source> <source>Take &amp;mulligan</source>
<translation>&amp;Mulligan nehmen</translation> <translation>&amp;Mulligan nehmen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="315"/> <location filename="../src/player.cpp" line="316"/>
<source>&amp;Hand</source> <source>&amp;Hand</source>
<translation>&amp;Hand</translation> <translation>&amp;Hand</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="317"/> <location filename="../src/player.cpp" line="318"/>
<source>&amp;Library</source> <source>&amp;Library</source>
<translation>Bib&amp;liothek</translation> <translation>Bib&amp;liothek</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="284"/> <location filename="../src/player.cpp" line="285"/>
<source>&amp;Graveyard</source> <source>&amp;Graveyard</source>
<translation>&amp;Friedhof</translation> <translation>&amp;Friedhof</translation>
</message> </message>
@ -2273,7 +2288,7 @@
<translation type="obsolete">Entfe&amp;rnte Karten</translation> <translation type="obsolete">Entfe&amp;rnte Karten</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="316"/> <location filename="../src/player.cpp" line="317"/>
<source>&amp;Sideboard</source> <source>&amp;Sideboard</source>
<translation>&amp;Sideboard</translation> <translation>&amp;Sideboard</translation>
</message> </message>
@ -2286,65 +2301,65 @@
<translation type="obsolete">&amp;Hinweis setzen...</translation> <translation type="obsolete">&amp;Hinweis setzen...</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="366"/> <location filename="../src/player.cpp" line="367"/>
<source>View top cards of library</source> <source>View top cards of library</source>
<translation>Zeige die obersten Karten der Bibliothek</translation> <translation>Zeige die obersten Karten der Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="366"/> <location filename="../src/player.cpp" line="367"/>
<source>Number of cards:</source> <source>Number of cards:</source>
<translation>Anzahl der Karten:</translation> <translation>Anzahl der Karten:</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="306"/> <location filename="../src/player.cpp" line="307"/>
<source>&amp;Draw card</source> <source>&amp;Draw card</source>
<translation>Karte &amp;ziehen</translation> <translation>Karte &amp;ziehen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="282"/> <location filename="../src/player.cpp" line="283"/>
<source>&amp;View exile</source> <source>&amp;View exile</source>
<translation>&amp;Zeige Exil</translation> <translation>&amp;Zeige Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="285"/> <location filename="../src/player.cpp" line="286"/>
<source>&amp;Exile</source> <source>&amp;Exile</source>
<translation>&amp;Exil</translation> <translation>&amp;Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="294"/> <location filename="../src/player.cpp" line="295"/>
<location filename="../src/player.cpp" line="298"/> <location filename="../src/player.cpp" line="299"/>
<source>Move to &amp;hand</source> <source>Move to &amp;hand</source>
<translation>auf die &amp;Hand nehmen</translation> <translation>auf die &amp;Hand nehmen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="290"/> <location filename="../src/player.cpp" line="291"/>
<location filename="../src/player.cpp" line="299"/> <location filename="../src/player.cpp" line="300"/>
<source>Move to g&amp;raveyard</source> <source>Move to g&amp;raveyard</source>
<translation>auf den &amp;Friedhof legen</translation> <translation>auf den &amp;Friedhof legen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="291"/> <location filename="../src/player.cpp" line="292"/>
<location filename="../src/player.cpp" line="295"/> <location filename="../src/player.cpp" line="296"/>
<source>Move to &amp;exile</source> <source>Move to &amp;exile</source>
<translation>ins &amp;Exil schicken</translation> <translation>ins &amp;Exil schicken</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="303"/> <location filename="../src/player.cpp" line="304"/>
<source>Ctrl+W</source> <source>Ctrl+W</source>
<translation>Ctrl+W</translation> <translation>Ctrl+W</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="307"/> <location filename="../src/player.cpp" line="308"/>
<source>Ctrl+D</source> <source>Ctrl+D</source>
<translation>Ctrl+D</translation> <translation>Ctrl+D</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="308"/> <location filename="../src/player.cpp" line="309"/>
<source>D&amp;raw cards...</source> <source>D&amp;raw cards...</source>
<translation>Ka&amp;rten ziehen...</translation> <translation>Ka&amp;rten ziehen...</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="309"/> <location filename="../src/player.cpp" line="310"/>
<source>Ctrl+E</source> <source>Ctrl+E</source>
<translation>Ctrl+E</translation> <translation>Ctrl+E</translation>
</message> </message>
@ -2353,32 +2368,32 @@
<translation type="obsolete">&amp;Mulligan nehmen...</translation> <translation type="obsolete">&amp;Mulligan nehmen...</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="311"/> <location filename="../src/player.cpp" line="312"/>
<source>Ctrl+M</source> <source>Ctrl+M</source>
<translation>Ctrl+M</translation> <translation>Ctrl+M</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="312"/> <location filename="../src/player.cpp" line="313"/>
<source>&amp;Shuffle</source> <source>&amp;Shuffle</source>
<translation>Mi&amp;schen</translation> <translation>Mi&amp;schen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="313"/> <location filename="../src/player.cpp" line="314"/>
<source>Ctrl+S</source> <source>Ctrl+S</source>
<translation>Ctrl+S</translation> <translation>Ctrl+S</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="318"/> <location filename="../src/player.cpp" line="319"/>
<source>&amp;Counters</source> <source>&amp;Counters</source>
<translation>&amp;Zähler</translation> <translation>&amp;Zähler</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="320"/> <location filename="../src/player.cpp" line="321"/>
<source>&amp;Untap all permanents</source> <source>&amp;Untap all permanents</source>
<translation>&amp;Enttappe alle bleibenden Karten</translation> <translation>&amp;Enttappe alle bleibenden Karten</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="321"/> <location filename="../src/player.cpp" line="322"/>
<source>Ctrl+U</source> <source>Ctrl+U</source>
<translation>Ctrl+U</translation> <translation>Ctrl+U</translation>
</message> </message>
@ -2407,42 +2422,42 @@
<translation type="obsolete">Ctrl+L</translation> <translation type="obsolete">Ctrl+L</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="322"/> <location filename="../src/player.cpp" line="323"/>
<source>R&amp;oll die...</source> <source>R&amp;oll die...</source>
<translation>&amp;Würfeln...</translation> <translation>&amp;Würfeln...</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="323"/> <location filename="../src/player.cpp" line="324"/>
<source>Ctrl+I</source> <source>Ctrl+I</source>
<translation>Ctrl+I</translation> <translation>Ctrl+I</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="324"/> <location filename="../src/player.cpp" line="325"/>
<source>&amp;Create token...</source> <source>&amp;Create token...</source>
<translation>Spiels&amp;tein erstellen...</translation> <translation>Spiels&amp;tein erstellen...</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="325"/> <location filename="../src/player.cpp" line="326"/>
<source>Ctrl+T</source> <source>Ctrl+T</source>
<translation>Ctrl+T</translation> <translation>Ctrl+T</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="326"/> <location filename="../src/player.cpp" line="327"/>
<source>C&amp;reate another token</source> <source>C&amp;reate another token</source>
<translation>&amp;Noch einen Spielstein erstellen</translation> <translation>&amp;Noch einen Spielstein erstellen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="327"/> <location filename="../src/player.cpp" line="328"/>
<source>Ctrl+G</source> <source>Ctrl+G</source>
<translation>Ctrl+G</translation> <translation>Ctrl+G</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="328"/> <location filename="../src/player.cpp" line="329"/>
<source>S&amp;ay</source> <source>S&amp;ay</source>
<translation>S&amp;agen</translation> <translation>S&amp;agen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="334"/> <location filename="../src/player.cpp" line="335"/>
<source>C&amp;ard</source> <source>C&amp;ard</source>
<translation>&amp;Karte</translation> <translation>&amp;Karte</translation>
</message> </message>
@ -2535,38 +2550,38 @@
<translation type="obsolete">F10</translation> <translation type="obsolete">F10</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="405"/> <location filename="../src/player.cpp" line="406"/>
<source>Draw cards</source> <source>Draw cards</source>
<translation>Karten ziehen</translation> <translation>Karten ziehen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="405"/> <location filename="../src/player.cpp" line="406"/>
<location filename="../src/player.cpp" line="1040"/> <location filename="../src/player.cpp" line="1113"/>
<source>Number:</source> <source>Number:</source>
<translation>Anzahl:</translation> <translation>Anzahl:</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="972"/> <location filename="../src/player.cpp" line="1039"/>
<source>Set power/toughness</source> <source>Set power/toughness</source>
<translation>Kampfwerte setzen</translation> <translation>Kampfwerte setzen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="972"/> <location filename="../src/player.cpp" line="1039"/>
<source>Please enter the new PT:</source> <source>Please enter the new PT:</source>
<translation>Bitte die neuen Kampfwerte eingeben:</translation> <translation>Bitte die neuen Kampfwerte eingeben:</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="994"/> <location filename="../src/player.cpp" line="1061"/>
<source>Set annotation</source> <source>Set annotation</source>
<translation>Hinweis setzen</translation> <translation>Hinweis setzen</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="994"/> <location filename="../src/player.cpp" line="1061"/>
<source>Please enter the new annotation:</source> <source>Please enter the new annotation:</source>
<translation>Bitte den Hinweis eingeben:</translation> <translation>Bitte den Hinweis eingeben:</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="1040"/> <location filename="../src/player.cpp" line="1113"/>
<source>Set counters</source> <source>Set counters</source>
<translation>Setze Zählmarken</translation> <translation>Setze Zählmarken</translation>
</message> </message>
@ -2579,12 +2594,12 @@
<translation type="obsolete">Neue Lebenspunkte insgesamt:</translation> <translation type="obsolete">Neue Lebenspunkte insgesamt:</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="418"/> <location filename="../src/player.cpp" line="419"/>
<source>Roll die</source> <source>Roll die</source>
<translation>Würfeln</translation> <translation>Würfeln</translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="418"/> <location filename="../src/player.cpp" line="419"/>
<source>Number of sides:</source> <source>Number of sides:</source>
<translation>Anzahl der Seiten:</translation> <translation>Anzahl der Seiten:</translation>
</message> </message>
@ -2905,12 +2920,12 @@ Bitte geben Sie einen Namen ein:</translation>
<translation>Sind Sie sicher, dass Sie das Spiel verlassen möchten?</translation> <translation>Sind Sie sicher, dass Sie das Spiel verlassen möchten?</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="493"/> <location filename="../src/tab_game.cpp" line="505"/>
<source>Load deck</source> <source>Load deck</source>
<translation>Deck laden</translation> <translation>Deck laden</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.h" line="127"/> <location filename="../src/tab_game.h" line="129"/>
<source>Game %1: %2</source> <source>Game %1: %2</source>
<translation>Spiel %1: %2</translation> <translation>Spiel %1: %2</translation>
</message> </message>

View file

@ -120,107 +120,112 @@
<context> <context>
<name>CardItem</name> <name>CardItem</name>
<message> <message>
<location filename="../src/carditem.cpp" line="115"/> <location filename="../src/carditem.cpp" line="124"/>
<source>&amp;Tap</source> <source>&amp;Tap</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="116"/> <location filename="../src/carditem.cpp" line="125"/>
<source>&amp;Untap</source> <source>&amp;Untap</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="117"/> <location filename="../src/carditem.cpp" line="126"/>
<source>Toggle &amp;normal untapping</source> <source>Toggle &amp;normal untapping</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="118"/> <location filename="../src/carditem.cpp" line="127"/>
<source>&amp;Flip</source> <source>&amp;Flip</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="119"/> <location filename="../src/carditem.cpp" line="128"/>
<source>&amp;Clone</source> <source>&amp;Clone</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="120"/> <location filename="../src/carditem.cpp" line="129"/>
<source>&amp;Attach to card...</source> <source>&amp;Attach to card...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="121"/> <location filename="../src/carditem.cpp" line="130"/>
<source>Unattac&amp;h</source> <source>Ctrl+A</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="122"/>
<source>Set &amp;P/T...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="123"/>
<source>&amp;Set annotation...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="125"/>
<source>red</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="126"/>
<source>yellow</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="127"/>
<source>green</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="129"/>
<source>&amp;Add counter (%1)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="131"/> <location filename="../src/carditem.cpp" line="131"/>
<source>&amp;Remove counter (%1)</source> <source>Unattac&amp;h</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="132"/>
<source>Set &amp;P/T...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="133"/> <location filename="../src/carditem.cpp" line="133"/>
<source>&amp;Set counters (%1)...</source> <source>&amp;Set annotation...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="134"/>
<source>&amp;top of library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="135"/> <location filename="../src/carditem.cpp" line="135"/>
<source>&amp;bottom of library</source> <source>red</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="136"/> <location filename="../src/carditem.cpp" line="136"/>
<source>&amp;graveyard</source> <source>yellow</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="137"/> <location filename="../src/carditem.cpp" line="137"/>
<source>green</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="139"/>
<source>&amp;Add counter (%1)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="141"/>
<source>&amp;Remove counter (%1)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="143"/>
<source>&amp;Set counters (%1)...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="144"/>
<source>&amp;top of library</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="145"/>
<source>&amp;bottom of library</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="146"/>
<source>&amp;graveyard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/carditem.cpp" line="147"/>
<source>Ctrl+Del</source> <source>Ctrl+Del</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="138"/> <location filename="../src/carditem.cpp" line="148"/>
<source>&amp;exile</source> <source>&amp;exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/carditem.cpp" line="140"/> <location filename="../src/carditem.cpp" line="150"/>
<source>&amp;Move to</source> <source>&amp;Move to</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -228,112 +233,112 @@
<context> <context>
<name>CardZone</name> <name>CardZone</name>
<message> <message>
<location filename="../src/cardzone.cpp" line="41"/> <location filename="../src/cardzone.cpp" line="48"/>
<location filename="../src/cardzone.cpp" line="43"/> <location filename="../src/cardzone.cpp" line="50"/>
<source>his hand</source> <source>his hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="41"/> <location filename="../src/cardzone.cpp" line="48"/>
<location filename="../src/cardzone.cpp" line="43"/> <location filename="../src/cardzone.cpp" line="50"/>
<source>%1&apos;s hand</source> <source>%1&apos;s hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="42"/> <location filename="../src/cardzone.cpp" line="49"/>
<source>of his hand</source> <source>of his hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="42"/> <location filename="../src/cardzone.cpp" line="49"/>
<source>of %1&apos;s hand</source> <source>of %1&apos;s hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="47"/> <location filename="../src/cardzone.cpp" line="54"/>
<location filename="../src/cardzone.cpp" line="49"/> <location filename="../src/cardzone.cpp" line="56"/>
<source>his library</source> <source>his library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="47"/> <location filename="../src/cardzone.cpp" line="54"/>
<location filename="../src/cardzone.cpp" line="49"/> <location filename="../src/cardzone.cpp" line="56"/>
<source>%1&apos;s library</source> <source>%1&apos;s library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="48"/> <location filename="../src/cardzone.cpp" line="55"/>
<source>of his library</source> <source>of his library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="48"/> <location filename="../src/cardzone.cpp" line="55"/>
<source>of %1&apos;s library</source> <source>of %1&apos;s library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="53"/> <location filename="../src/cardzone.cpp" line="60"/>
<location filename="../src/cardzone.cpp" line="55"/> <location filename="../src/cardzone.cpp" line="62"/>
<source>his graveyard</source> <source>his graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="53"/> <location filename="../src/cardzone.cpp" line="60"/>
<location filename="../src/cardzone.cpp" line="55"/> <location filename="../src/cardzone.cpp" line="62"/>
<source>%1&apos;s graveyard</source> <source>%1&apos;s graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="54"/> <location filename="../src/cardzone.cpp" line="61"/>
<source>of his graveyard</source> <source>of his graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="54"/> <location filename="../src/cardzone.cpp" line="61"/>
<source>of %1&apos;s graveyard</source> <source>of %1&apos;s graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="59"/> <location filename="../src/cardzone.cpp" line="66"/>
<location filename="../src/cardzone.cpp" line="61"/> <location filename="../src/cardzone.cpp" line="68"/>
<source>his exile</source> <source>his exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="59"/> <location filename="../src/cardzone.cpp" line="66"/>
<location filename="../src/cardzone.cpp" line="61"/> <location filename="../src/cardzone.cpp" line="68"/>
<source>%1&apos;s exile</source> <source>%1&apos;s exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="60"/> <location filename="../src/cardzone.cpp" line="67"/>
<source>of his exile</source> <source>of his exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="60"/> <location filename="../src/cardzone.cpp" line="67"/>
<source>of %1&apos;s exile</source> <source>of %1&apos;s exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="65"/> <location filename="../src/cardzone.cpp" line="72"/>
<location filename="../src/cardzone.cpp" line="67"/> <location filename="../src/cardzone.cpp" line="74"/>
<source>his sideboard</source> <source>his sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="65"/> <location filename="../src/cardzone.cpp" line="72"/>
<location filename="../src/cardzone.cpp" line="67"/> <location filename="../src/cardzone.cpp" line="74"/>
<source>%1&apos;s sideboard</source> <source>%1&apos;s sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="66"/> <location filename="../src/cardzone.cpp" line="73"/>
<source>of his sideboard</source> <source>of his sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/cardzone.cpp" line="66"/> <location filename="../src/cardzone.cpp" line="73"/>
<source>of %1&apos;s sideboard</source> <source>of %1&apos;s sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1166,12 +1171,22 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="225"/> <location filename="../src/messagelogwidget.cpp" line="212"/>
<source>%1 attaches %2 to %3&apos;s %4.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/messagelogwidget.cpp" line="217"/>
<source>%1 unattaches %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/messagelogwidget.cpp" line="235"/>
<source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source> <source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<location filename="../src/messagelogwidget.cpp" line="240"/> <location filename="../src/messagelogwidget.cpp" line="250"/>
<source>%1 places %n counter(s) (%2) on %3 (now %4).</source> <source>%1 places %n counter(s) (%2) on %3 (now %4).</source>
<translation> <translation>
<numerusform>%1 places a counter (%2) on %3 (now %4).</numerusform> <numerusform>%1 places a counter (%2) on %3 (now %4).</numerusform>
@ -1179,7 +1194,7 @@
</translation> </translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<location filename="../src/messagelogwidget.cpp" line="242"/> <location filename="../src/messagelogwidget.cpp" line="252"/>
<source>%1 removes %n counter(s) (%2) from %3 (now %4).</source> <source>%1 removes %n counter(s) (%2) from %3 (now %4).</source>
<translation> <translation>
<numerusform>%1 removes a counter (%2) from %3 (now %4).</numerusform> <numerusform>%1 removes a counter (%2) from %3 (now %4).</numerusform>
@ -1187,37 +1202,37 @@
</translation> </translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="245"/> <location filename="../src/messagelogwidget.cpp" line="255"/>
<source>red</source> <source>red</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="246"/> <location filename="../src/messagelogwidget.cpp" line="256"/>
<source>yellow</source> <source>yellow</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="247"/> <location filename="../src/messagelogwidget.cpp" line="257"/>
<source>green</source> <source>green</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="266"/> <location filename="../src/messagelogwidget.cpp" line="276"/>
<source>%1 sets counter %2 to %3 (%4%5).</source> <source>%1 sets counter %2 to %3 (%4%5).</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="281"/> <location filename="../src/messagelogwidget.cpp" line="291"/>
<source>%1 sets PT of %2 to %3.</source> <source>%1 sets PT of %2 to %3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="286"/> <location filename="../src/messagelogwidget.cpp" line="296"/>
<source>%1 sets annotation of %2 to %3.</source> <source>%1 sets annotation of %2 to %3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="292"/> <location filename="../src/messagelogwidget.cpp" line="302"/>
<source>%1 is looking at the top %2 cards %3.</source> <source>%1 is looking at the top %2 cards %3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1287,37 +1302,37 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="212"/> <location filename="../src/messagelogwidget.cpp" line="222"/>
<source>%1 creates token: %2%3.</source> <source>%1 creates token: %2%3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="218"/> <location filename="../src/messagelogwidget.cpp" line="228"/>
<source>%1 points from %2&apos;s %3 to %4.</source> <source>%1 points from %2&apos;s %3 to %4.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="261"/> <location filename="../src/messagelogwidget.cpp" line="271"/>
<source>%1 %2 %3.</source> <source>%1 %2 %3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="294"/> <location filename="../src/messagelogwidget.cpp" line="304"/>
<source>%1 is looking at %2.</source> <source>%1 is looking at %2.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="300"/> <location filename="../src/messagelogwidget.cpp" line="310"/>
<source>%1 stops looking at %2.</source> <source>%1 stops looking at %2.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="324"/> <location filename="../src/messagelogwidget.cpp" line="334"/>
<source>ending phase</source> <source>ending phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="306"/> <location filename="../src/messagelogwidget.cpp" line="316"/>
<source>It is now %1&apos;s turn.</source> <source>It is now %1&apos;s turn.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1327,82 +1342,82 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="314"/> <location filename="../src/messagelogwidget.cpp" line="324"/>
<source>untap step</source> <source>untap step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="315"/> <location filename="../src/messagelogwidget.cpp" line="325"/>
<source>upkeep step</source> <source>upkeep step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="316"/> <location filename="../src/messagelogwidget.cpp" line="326"/>
<source>draw step</source> <source>draw step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="317"/> <location filename="../src/messagelogwidget.cpp" line="327"/>
<source>first main phase</source> <source>first main phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="318"/> <location filename="../src/messagelogwidget.cpp" line="328"/>
<source>beginning of combat step</source> <source>beginning of combat step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="319"/> <location filename="../src/messagelogwidget.cpp" line="329"/>
<source>declare attackers step</source> <source>declare attackers step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="320"/> <location filename="../src/messagelogwidget.cpp" line="330"/>
<source>declare blockers step</source> <source>declare blockers step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="321"/> <location filename="../src/messagelogwidget.cpp" line="331"/>
<source>combat damage step</source> <source>combat damage step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="322"/> <location filename="../src/messagelogwidget.cpp" line="332"/>
<source>end of combat step</source> <source>end of combat step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="323"/> <location filename="../src/messagelogwidget.cpp" line="333"/>
<source>second main phase</source> <source>second main phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="326"/> <location filename="../src/messagelogwidget.cpp" line="336"/>
<source>It is now the %1.</source> <source>It is now the %1.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="261"/> <location filename="../src/messagelogwidget.cpp" line="271"/>
<source>taps</source> <source>taps</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="261"/> <location filename="../src/messagelogwidget.cpp" line="271"/>
<source>untaps</source> <source>untaps</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="273"/> <location filename="../src/messagelogwidget.cpp" line="283"/>
<source>%1 sets %2 to not untap normally.</source> <source>%1 sets %2 to not untap normally.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="275"/> <location filename="../src/messagelogwidget.cpp" line="285"/>
<source>%1 sets %2 to untap normally.</source> <source>%1 sets %2 to untap normally.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="258"/> <location filename="../src/messagelogwidget.cpp" line="268"/>
<source>his permanents</source> <source>his permanents</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1491,255 +1506,255 @@
<context> <context>
<name>Player</name> <name>Player</name>
<message> <message>
<location filename="../src/player.cpp" line="288"/> <location filename="../src/player.cpp" line="289"/>
<location filename="../src/player.cpp" line="292"/> <location filename="../src/player.cpp" line="293"/>
<location filename="../src/player.cpp" line="296"/> <location filename="../src/player.cpp" line="297"/>
<source>Move to &amp;top of library</source> <source>Move to &amp;top of library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="289"/> <location filename="../src/player.cpp" line="290"/>
<location filename="../src/player.cpp" line="293"/> <location filename="../src/player.cpp" line="294"/>
<location filename="../src/player.cpp" line="297"/> <location filename="../src/player.cpp" line="298"/>
<source>Move to &amp;bottom of library</source> <source>Move to &amp;bottom of library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="300"/> <location filename="../src/player.cpp" line="301"/>
<source>&amp;View library</source> <source>&amp;View library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="301"/> <location filename="../src/player.cpp" line="302"/>
<source>F3</source> <source>F3</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="302"/> <location filename="../src/player.cpp" line="303"/>
<source>View &amp;top cards of library...</source> <source>View &amp;top cards of library...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="281"/> <location filename="../src/player.cpp" line="282"/>
<source>&amp;View graveyard</source> <source>&amp;View graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="304"/> <location filename="../src/player.cpp" line="305"/>
<source>F4</source> <source>F4</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="305"/> <location filename="../src/player.cpp" line="306"/>
<source>&amp;View sideboard</source> <source>&amp;View sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="283"/> <location filename="../src/player.cpp" line="284"/>
<source>Player &quot;%1&quot;</source> <source>Player &quot;%1&quot;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="315"/> <location filename="../src/player.cpp" line="316"/>
<source>&amp;Hand</source> <source>&amp;Hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="317"/> <location filename="../src/player.cpp" line="318"/>
<source>&amp;Library</source> <source>&amp;Library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="284"/> <location filename="../src/player.cpp" line="285"/>
<source>&amp;Graveyard</source> <source>&amp;Graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="316"/> <location filename="../src/player.cpp" line="317"/>
<source>&amp;Sideboard</source> <source>&amp;Sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="366"/> <location filename="../src/player.cpp" line="367"/>
<source>View top cards of library</source> <source>View top cards of library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="366"/> <location filename="../src/player.cpp" line="367"/>
<source>Number of cards:</source> <source>Number of cards:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="306"/> <location filename="../src/player.cpp" line="307"/>
<source>&amp;Draw card</source> <source>&amp;Draw card</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="282"/> <location filename="../src/player.cpp" line="283"/>
<source>&amp;View exile</source> <source>&amp;View exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="285"/> <location filename="../src/player.cpp" line="286"/>
<source>&amp;Exile</source> <source>&amp;Exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="294"/> <location filename="../src/player.cpp" line="295"/>
<location filename="../src/player.cpp" line="298"/> <location filename="../src/player.cpp" line="299"/>
<source>Move to &amp;hand</source> <source>Move to &amp;hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="290"/> <location filename="../src/player.cpp" line="291"/>
<location filename="../src/player.cpp" line="299"/> <location filename="../src/player.cpp" line="300"/>
<source>Move to g&amp;raveyard</source> <source>Move to g&amp;raveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="291"/> <location filename="../src/player.cpp" line="292"/>
<location filename="../src/player.cpp" line="295"/> <location filename="../src/player.cpp" line="296"/>
<source>Move to &amp;exile</source> <source>Move to &amp;exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="303"/> <location filename="../src/player.cpp" line="304"/>
<source>Ctrl+W</source> <source>Ctrl+W</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="307"/> <location filename="../src/player.cpp" line="308"/>
<source>Ctrl+D</source> <source>Ctrl+D</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="308"/> <location filename="../src/player.cpp" line="309"/>
<source>D&amp;raw cards...</source> <source>D&amp;raw cards...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="309"/> <location filename="../src/player.cpp" line="310"/>
<source>Ctrl+E</source> <source>Ctrl+E</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="310"/> <location filename="../src/player.cpp" line="311"/>
<source>Take &amp;mulligan</source> <source>Take &amp;mulligan</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="311"/> <location filename="../src/player.cpp" line="312"/>
<source>Ctrl+M</source> <source>Ctrl+M</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="312"/> <location filename="../src/player.cpp" line="313"/>
<source>&amp;Shuffle</source> <source>&amp;Shuffle</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="313"/> <location filename="../src/player.cpp" line="314"/>
<source>Ctrl+S</source> <source>Ctrl+S</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="318"/> <location filename="../src/player.cpp" line="319"/>
<source>&amp;Counters</source> <source>&amp;Counters</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="320"/> <location filename="../src/player.cpp" line="321"/>
<source>&amp;Untap all permanents</source> <source>&amp;Untap all permanents</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="321"/> <location filename="../src/player.cpp" line="322"/>
<source>Ctrl+U</source> <source>Ctrl+U</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="322"/> <location filename="../src/player.cpp" line="323"/>
<source>R&amp;oll die...</source> <source>R&amp;oll die...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="323"/> <location filename="../src/player.cpp" line="324"/>
<source>Ctrl+I</source> <source>Ctrl+I</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="324"/> <location filename="../src/player.cpp" line="325"/>
<source>&amp;Create token...</source> <source>&amp;Create token...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="325"/> <location filename="../src/player.cpp" line="326"/>
<source>Ctrl+T</source> <source>Ctrl+T</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="326"/> <location filename="../src/player.cpp" line="327"/>
<source>C&amp;reate another token</source> <source>C&amp;reate another token</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="327"/> <location filename="../src/player.cpp" line="328"/>
<source>Ctrl+G</source> <source>Ctrl+G</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="328"/> <location filename="../src/player.cpp" line="329"/>
<source>S&amp;ay</source> <source>S&amp;ay</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="334"/> <location filename="../src/player.cpp" line="335"/>
<source>C&amp;ard</source> <source>C&amp;ard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="405"/> <location filename="../src/player.cpp" line="406"/>
<source>Draw cards</source> <source>Draw cards</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="405"/> <location filename="../src/player.cpp" line="406"/>
<location filename="../src/player.cpp" line="1040"/> <location filename="../src/player.cpp" line="1113"/>
<source>Number:</source> <source>Number:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="418"/> <location filename="../src/player.cpp" line="419"/>
<source>Roll die</source> <source>Roll die</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="418"/> <location filename="../src/player.cpp" line="419"/>
<source>Number of sides:</source> <source>Number of sides:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="972"/> <location filename="../src/player.cpp" line="1039"/>
<source>Set power/toughness</source> <source>Set power/toughness</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="972"/> <location filename="../src/player.cpp" line="1039"/>
<source>Please enter the new PT:</source> <source>Please enter the new PT:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="994"/> <location filename="../src/player.cpp" line="1061"/>
<source>Set annotation</source> <source>Set annotation</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="994"/> <location filename="../src/player.cpp" line="1061"/>
<source>Please enter the new annotation:</source> <source>Please enter the new annotation:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/player.cpp" line="1040"/> <location filename="../src/player.cpp" line="1113"/>
<source>Set counters</source> <source>Set counters</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2027,12 +2042,12 @@ Please enter a name:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="493"/> <location filename="../src/tab_game.cpp" line="505"/>
<source>Load deck</source> <source>Load deck</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.h" line="127"/> <location filename="../src/tab_game.h" line="129"/>
<source>Game %1: %2</source> <source>Game %1: %2</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -39,7 +39,7 @@ ServerInfo_CardCounter::ServerInfo_CardCounter(int _id, int _value)
insertItem(new SerializableItem_Int("value", _value)); insertItem(new SerializableItem_Int("value", _value));
} }
ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y, bool _tapped, bool _attacking, const QString &_color, const QString &_pt, const QString &_annotation, bool _destroyOnZoneChange, const QList<ServerInfo_CardCounter *> &_counters) ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y, bool _tapped, bool _attacking, const QString &_color, const QString &_pt, const QString &_annotation, bool _destroyOnZoneChange, const QList<ServerInfo_CardCounter *> &_counters, int _attachPlayerId, const QString &_attachZone, int _attachCardId)
: SerializableItem_Map("card") : SerializableItem_Map("card")
{ {
insertItem(new SerializableItem_Int("id", _id)); insertItem(new SerializableItem_Int("id", _id));
@ -52,6 +52,9 @@ ServerInfo_Card::ServerInfo_Card(int _id, const QString &_name, int _x, int _y,
insertItem(new SerializableItem_String("pt", _pt)); insertItem(new SerializableItem_String("pt", _pt));
insertItem(new SerializableItem_String("annotation", _annotation)); insertItem(new SerializableItem_String("annotation", _annotation));
insertItem(new SerializableItem_Bool("destroy_on_zone_change", _destroyOnZoneChange)); insertItem(new SerializableItem_Bool("destroy_on_zone_change", _destroyOnZoneChange));
insertItem(new SerializableItem_Int("attach_player_id", _attachPlayerId));
insertItem(new SerializableItem_String("attach_zone", _attachZone));
insertItem(new SerializableItem_Int("attach_card_id", _attachCardId));
for (int i = 0; i < _counters.size(); ++i) for (int i = 0; i < _counters.size(); ++i)
itemList.append(_counters[i]); itemList.append(_counters[i]);

View file

@ -62,7 +62,7 @@ public:
class ServerInfo_Card : public SerializableItem_Map { class ServerInfo_Card : public SerializableItem_Map {
public: public:
ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, bool _tapped = false, bool _attacking = false, const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), bool _destroyOnZoneChange = false, const QList<ServerInfo_CardCounter *> &_counterList = QList<ServerInfo_CardCounter *>()); ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, bool _tapped = false, bool _attacking = false, const QString &_color = QString(), const QString &_pt = QString(), const QString &_annotation = QString(), bool _destroyOnZoneChange = false, const QList<ServerInfo_CardCounter *> &_counterList = QList<ServerInfo_CardCounter *>(), int attachPlayerId = -1, const QString &_attachZone = QString(), int attachCardId = -1);
static SerializableItem *newItem() { return new ServerInfo_Card; } static SerializableItem *newItem() { return new ServerInfo_Card; }
int getId() const { return static_cast<SerializableItem_Int *>(itemMap.value("id"))->getData(); } int getId() const { return static_cast<SerializableItem_Int *>(itemMap.value("id"))->getData(); }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); } QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
@ -75,6 +75,9 @@ public:
QString getAnnotation() const { return static_cast<SerializableItem_String *>(itemMap.value("annotation"))->getData(); } QString getAnnotation() const { return static_cast<SerializableItem_String *>(itemMap.value("annotation"))->getData(); }
bool getDestroyOnZoneChange() const { return static_cast<SerializableItem_Bool *>(itemMap.value("destroy_on_zone_change"))->getData(); } bool getDestroyOnZoneChange() const { return static_cast<SerializableItem_Bool *>(itemMap.value("destroy_on_zone_change"))->getData(); }
QList<ServerInfo_CardCounter *> getCounters() const { return typecastItemList<ServerInfo_CardCounter *>(); } QList<ServerInfo_CardCounter *> getCounters() const { return typecastItemList<ServerInfo_CardCounter *>(); }
int getAttachPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("attach_player_id"))->getData(); }
QString getAttachZone() const { return static_cast<SerializableItem_String *>(itemMap.value("attach_zone"))->getData(); }
int getAttachCardId() const { return static_cast<SerializableItem_Int *>(itemMap.value("attach_card_id"))->getData(); }
}; };
class ServerInfo_Zone : public SerializableItem_Map { class ServerInfo_Zone : public SerializableItem_Map {

View file

@ -27,6 +27,12 @@ Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y)
Server_Card::~Server_Card() Server_Card::~Server_Card()
{ {
// setParentCard(0) leads to the item being removed from our list, so we can't iterate properly
while (!attachedCards.isEmpty())
attachedCards.first()->setParentCard(0);
if (parentCard)
parentCard->removeAttachedCard(this);
} }
void Server_Card::resetState() void Server_Card::resetState()
@ -74,3 +80,12 @@ void Server_Card::setCounter(int id, int value)
else else
counters.remove(id); counters.remove(id);
} }
void Server_Card::setParentCard(Server_Card *_parentCard)
{
if (parentCard)
parentCard->removeAttachedCard(this);
parentCard = _parentCard;
if (parentCard)
parentCard->addAttachedCard(this);
}

View file

@ -44,6 +44,7 @@ private:
bool doesntUntap; bool doesntUntap;
Server_Card *parentCard; Server_Card *parentCard;
QList<Server_Card *> attachedCards;
public: public:
Server_Card(QString _name, int _id, int _coord_x, int _coord_y); Server_Card(QString _name, int _id, int _coord_x, int _coord_y);
~Server_Card(); ~Server_Card();
@ -66,6 +67,7 @@ public:
bool getDoesntUntap() const { return doesntUntap; } bool getDoesntUntap() const { return doesntUntap; }
bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } bool getDestroyOnZoneChange() const { return destroyOnZoneChange; }
Server_Card *getParentCard() const { return parentCard; } Server_Card *getParentCard() const { return parentCard; }
const QList<Server_Card *> &getAttachedCards() const { return attachedCards; }
void setId(int _id) { id = _id; } void setId(int _id) { id = _id; }
void setCoords(int x, int y) { coord_x = x; coord_y = y; } void setCoords(int x, int y) { coord_x = x; coord_y = y; }
@ -79,7 +81,9 @@ public:
void setAnnotation(const QString &_annotation) { annotation = _annotation; } void setAnnotation(const QString &_annotation) { annotation = _annotation; }
void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; }
void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; }
void setParentCard(Server_Card *_parentCard) { parentCard = _parentCard; } void setParentCard(Server_Card *_parentCard);
void addAttachedCard(Server_Card *card) { attachedCards.append(card); }
void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); }
void resetState(); void resetState();
bool setAttribute(const QString &aname, const QString &avalue, bool allCards); bool setAttribute(const QString &aname, const QString &avalue, bool allCards);

View file

@ -318,7 +318,15 @@ QList<ServerInfo_Player *> Server_Game::getGameState(Server_Player *playerWhosAs
cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value())); cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value()));
} }
cardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), cardCounterList)); int attachPlayerId = -1;
QString attachZone;
int attachCardId = -1;
if (card->getParentCard()) {
attachPlayerId = card->getParentCard()->getZone()->getPlayer()->getPlayerId();
attachZone = card->getParentCard()->getZone()->getName();
attachCardId = card->getParentCard()->getId();
}
cardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), cardCounterList, attachPlayerId, attachZone, attachCardId));
} }
} }
zoneList.append(new ServerInfo_Zone(zone->getName(), zone->getType(), zone->hasCoords(), zone->cards.size(), cardList)); zoneList.append(new ServerInfo_Zone(zone->getName(), zone->getType(), zone->hasCoords(), zone->cards.size(), cardList));

View file

@ -517,6 +517,12 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player *
if (!card) if (!card)
return RespNameNotFound; return RespNameNotFound;
if (startzone != targetzone) {
const QList<Server_Card *> &attachedCards = card->getAttachedCards();
for (int i = 0; i < attachedCards.size(); ++i)
unattachCard(game, attachedCards[i]->getZone()->getPlayer(), cont, attachedCards[i]);
}
if (card->getDestroyOnZoneChange() && (startzone != targetzone)) { if (card->getDestroyOnZoneChange() && (startzone != targetzone)) {
cont->enqueueGameEventPrivate(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); cont->enqueueGameEventPrivate(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId());
cont->enqueueGameEventPublic(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId()); cont->enqueueGameEventPublic(new Event_DestroyCard(player->getPlayerId(), startzone->getName(), card->getId()), game->getGameId());
@ -609,6 +615,17 @@ ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandC
return moveCard(game, player, cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped()); return moveCard(game, player, cont, cmd->getStartZone(), cmd->getCardId(), cmd->getTargetZone(), cmd->getX(), cmd->getY(), cmd->getFaceDown(), cmd->getTapped());
} }
void Server_ProtocolHandler::unattachCard(Server_Game *game, Server_Player *player, CommandContainer *cont, Server_Card *card)
{
Server_CardZone *zone = card->getZone();
card->setParentCard(0);
cont->enqueueGameEventPrivate(new Event_AttachCard(player->getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId());
cont->enqueueGameEventPublic(new Event_AttachCard(player->getPlayerId(), zone->getName(), card->getId(), -1, QString(), -1), game->getGameId());
moveCard(game, player, cont, zone->getName(), card->getId(), zone->getName(), -1, card->getY(), card->getFaceDown(), card->getTapped());
}
ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator()) if (player->getSpectator())
@ -625,21 +642,49 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm
if (!card) if (!card)
return RespNameNotFound; return RespNameNotFound;
Server_Player *targetPlayer = game->getPlayer(cmd->getTargetPlayerId()); int playerId = cmd->getTargetPlayerId();
if (!targetPlayer) Server_Player *targetPlayer = 0;
return RespNameNotFound; Server_CardZone *targetzone = 0;
Server_Card *targetCard = 0;
Server_CardZone *targetzone = targetPlayer->getZones().value(cmd->getTargetZone()); if (playerId != -1) {
if (!targetzone) targetPlayer = game->getPlayer(cmd->getTargetPlayerId());
return RespNameNotFound; if (!targetPlayer)
return RespNameNotFound;
} else if (!card->getParentCard())
return RespContextError;
if (targetPlayer)
targetzone = targetPlayer->getZones().value(cmd->getTargetZone());
if (targetzone)
targetCard = targetzone->getCard(cmd->getTargetCardId(), false);
// Get all arrows pointing to or originating from the card being attached and delete them.
QMapIterator<int, Server_Player *> playerIterator(game->getPlayers());
while (playerIterator.hasNext()) {
Server_Player *p = playerIterator.next().value();
QList<Server_Arrow *> arrows = p->getArrows().values();
QList<Server_Arrow *> toDelete;
for (int i = 0; i < arrows.size(); ++i) {
Server_Arrow *a = arrows[i];
Server_Card *tCard = qobject_cast<Server_Card *>(a->getTargetItem());
if ((tCard == card) || (a->getStartCard() == card))
toDelete.append(a);
}
for (int i = 0; i < toDelete.size(); ++i) {
cont->enqueueGameEventPrivate(new Event_DeleteArrow(p->getPlayerId(), toDelete[i]->getId()), game->getGameId());
cont->enqueueGameEventPublic(new Event_DeleteArrow(p->getPlayerId(), toDelete[i]->getId()), game->getGameId());
p->deleteArrow(toDelete[i]->getId());
}
}
Server_Card *targetCard = targetzone->getCard(cmd->getTargetCardId(), false); if (targetCard) {
if (!targetCard) card->setParentCard(targetCard);
return RespNameNotFound; card->setCoords(-1, card->getY());
cont->enqueueGameEventPrivate(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId());
cont->enqueueGameEventPublic(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId());
} else
unattachCard(game, player, cont, card);
card->setParentCard(targetCard);
cont->enqueueGameEventPrivate(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId());
cont->enqueueGameEventPublic(new Event_AttachCard(player->getPlayerId(), startzone->getName(), card->getId(), targetPlayer->getPlayerId(), targetzone->getName(), targetCard->getId()), game->getGameId());
return RespOk; return RespOk;
} }
@ -956,7 +1001,17 @@ ResponseCode Server_ProtocolHandler::cmdDumpZone(Command_DumpZone *cmd, CommandC
cardCounterIterator.next(); cardCounterIterator.next();
cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value())); cardCounterList.append(new ServerInfo_CardCounter(cardCounterIterator.key(), cardCounterIterator.value()));
} }
respCardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), cardCounterList));
int attachPlayerId = -1;
QString attachZone;
int attachCardId = -1;
if (card->getParentCard()) {
attachPlayerId = card->getParentCard()->getZone()->getPlayer()->getPlayerId();
attachZone = card->getParentCard()->getZone()->getName();
attachCardId = card->getParentCard()->getId();
}
respCardList.append(new ServerInfo_Card(card->getId(), displayedName, card->getX(), card->getY(), card->getTapped(), card->getAttacking(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), cardCounterList, attachPlayerId, attachZone, attachCardId));
} }
} }
if (zone->getType() == HiddenZone) { if (zone->getType() == HiddenZone) {

View file

@ -8,6 +8,7 @@
#include "protocol_items.h" #include "protocol_items.h"
class Server_Player; class Server_Player;
class Server_Card;
class QTimer; class QTimer;
class Server_ProtocolHandler : public QObject { class Server_ProtocolHandler : public QObject {
@ -61,6 +62,7 @@ private:
ResponseCode cmdDrawCards(Command_DrawCards *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdDrawCards(Command_DrawCards *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
ResponseCode moveCard(Server_Game *game, Server_Player *player, CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped); ResponseCode moveCard(Server_Game *game, Server_Player *player, CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int _x, int _y, bool _faceDown, bool _tapped);
ResponseCode cmdMoveCard(Command_MoveCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdMoveCard(Command_MoveCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
void unattachCard(Server_Game *game, Server_Player *player, CommandContainer *cont, Server_Card *card);
ResponseCode cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdAttachCard(Command_AttachCard *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
ResponseCode cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
ResponseCode cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player); ResponseCode cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);

View file

@ -130,6 +130,10 @@
<name>M10</name> <name>M10</name>
<longname>Magic 2010</longname> <longname>Magic 2010</longname>
</set> </set>
<set import="1">
<name>M11</name>
<longname>Magic 2011</longname>
</set>
<set import="1"> <set import="1">
<name>MM</name> <name>MM</name>
<longname>Mercadian Masques</longname> <longname>Mercadian Masques</longname>