diff --git a/cockatrice/src/arrowitem.cpp b/cockatrice/src/arrowitem.cpp index 002bd2f1..8561678f 100644 --- a/cockatrice/src/arrowitem.cpp +++ b/cockatrice/src/arrowitem.cpp @@ -13,6 +13,7 @@ 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) { + qDebug() << "ArrowItem constructor: startItem=" << startItem; setZValue(2000000005); if (startItem) @@ -62,6 +63,9 @@ void ArrowItem::updatePath(const QPointF &endPoint) const double headLength = headWidth / sqrt(2); const double phi = 15; + if (!startItem) + return; + QPointF startPoint = startItem->mapToScene(QPointF(startItem->boundingRect().width() / 2, startItem->boundingRect().height() / 2)); QLineF line(startPoint, endPoint); qreal lineLength = line.length(); @@ -141,6 +145,11 @@ void ArrowDragItem::addChildArrow(ArrowDragItem *childArrow) void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + // This ensures that if a mouse move event happens after a call to delArrow(), + // the event will be discarded as it would create some stray pointers. + if (!startItem) + return; + QPointF endPos = event->scenePos(); QList colliding = scene()->items(endPos); @@ -177,6 +186,9 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + if (!startItem) + return; + if (targetItem && (targetItem != startItem)) { CardZone *startZone = static_cast(startItem)->getZone(); // For now, we can safely assume that the start item is always a card. @@ -222,6 +234,9 @@ ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem) void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + if (!startItem) + return; + QPointF endPos = event->scenePos(); QList colliding = scene()->items(endPos); @@ -249,6 +264,9 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/) { + if (!startItem) + return; + if (targetItem && (targetItem != startItem)) { CardItem *startCard = qgraphicsitem_cast(startItem); CardZone *startZone = startCard->getZone(); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index f5e2aac3..765727c2 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -721,7 +721,7 @@ void Player::eventMoveCard(Event_MoveCard *event) while (playerIterator.hasNext()) { Player *p = playerIterator.next().value(); - QList arrowsToDelete; + QList arrowsToDelete; QMapIterator arrowIterator(p->getArrows()); while (arrowIterator.hasNext()) { ArrowItem *arrow = arrowIterator.next().value(); @@ -729,11 +729,11 @@ void Player::eventMoveCard(Event_MoveCard *event) if (startZone == targetZone) arrow->updatePath(); else - arrowsToDelete.append(arrow->getId()); + arrowsToDelete.append(arrow); } } for (int i = 0; i < arrowsToDelete.size(); ++i) - p->delArrow(arrowsToDelete[i]); + arrowsToDelete[i]->delArrow(); } } @@ -774,14 +774,19 @@ void Player::eventAttachCard(Event_AttachCard *event) if (!startCard) return; + CardItem *oldParent = startCard->getAttachedTo(); + if (targetZone) startCard->setParentItem(targetZone); else startCard->setParentItem(startZone); startCard->setAttachedTo(targetCard); + startZone->reorganizeCards(); if ((startZone != targetZone) && targetZone) targetZone->reorganizeCards(); + if (oldParent) + oldParent->getZone()->reorganizeCards(); if (targetCard) emit logAttachCard(this, startCard->getName(), targetPlayer, targetCard->getName()); @@ -928,7 +933,7 @@ void Player::deleteCard(CardItem *c) if (dialogSemaphore) cardsToDelete.append(c); else - delete c; + c->deleteLater(); } void Player::addZone(CardZone *z) diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 1d70464b..d34a3add 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -670,11 +670,14 @@ ResponseCode Server_ProtocolHandler::cmdAttachCard(Command_AttachCard *cmd, Comm return RespContextError; if (targetPlayer) targetzone = targetPlayer->getZones().value(cmd->getTargetZone()); - if (targetzone) + if (targetzone) { + // This is currently enough to make sure cards don't get attached to a card that is not on the table. + // Possibly a flag will have to be introduced for this sometime. + if (!targetzone->hasCoords()) + return RespContextError; targetCard = targetzone->getCard(cmd->getTargetCardId(), false); - // This is currently enough to make sure cards don't get attached to a card that is not on the table. - // Possibly a flag will have to be introduced for this sometime. - if (!startzone->hasCoords() || !targetzone->hasCoords()) + } + if (!startzone->hasCoords()) return RespContextError; // Get all arrows pointing to or originating from the card being attached and delete them.