diff --git a/cockatrice/src/game/game_event_handler.cpp b/cockatrice/src/game/game_event_handler.cpp index c91d08385..95460011f 100644 --- a/cockatrice/src/game/game_event_handler.cpp +++ b/cockatrice/src/game/game_event_handler.cpp @@ -229,7 +229,11 @@ void GameEventHandler::handleArrowDeletion(int creatorId, int arrowId) void GameEventHandler::handleArrowDeletionFinished(const Response &response, int creatorId, int arrowId) { - if (response.response_code() == Response::RespNameNotFound) { + // The server confirms the arrow no longer exists whether it deleted it itself + // (RespOk, followed by an Event_DeleteArrow broadcast) or never had it + // (RespNameNotFound). In both cases the local copy has to go. deleteArrow is + // a no-op if the arrow was already removed by the event broadcast. + if (response.response_code() == Response::RespOk || response.response_code() == Response::RespNameNotFound) { emit arrowDeleted(creatorId, arrowId); } } diff --git a/cockatrice/src/game_graphics/board/arrow_item.cpp b/cockatrice/src/game_graphics/board/arrow_item.cpp index af63d047d..664d44ecc 100644 --- a/cockatrice/src/game_graphics/board/arrow_item.cpp +++ b/cockatrice/src/game_graphics/board/arrow_item.cpp @@ -75,6 +75,14 @@ ArrowItem::~ArrowItem() void ArrowItem::onTargetDestroyed() { + if (data->id == -1) { + // Drag and attach arrows are never inserted into the arrow registry and + // have no server-side counterpart, so no deletion event can clean them + // up. Delete them locally when either endpoint is destroyed. + delArrow(); + return; + } + emit requestDeletion(data->creatorId, data->id); } @@ -384,6 +392,12 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (!startItem) { + // The source card was destroyed while the arrow was being drawn. + // Clean up the arrow and its children instead of leaking them. + delArrow(); + for (auto *child : childArrows) { + child->mouseReleaseEvent(event); + } return; } @@ -507,6 +521,12 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (!startItem) { + // The source card was destroyed while the arrow was being drawn. + // Clean up the arrow and its children instead of leaking them. + delArrow(); + for (auto *child : childArrows) { + child->mouseReleaseEvent(event); + } return; }