diff --git a/cockatrice/src/game_graphics/zones/command_zone.cpp b/cockatrice/src/game_graphics/zones/command_zone.cpp index dc4c6d018..57106a756 100644 --- a/cockatrice/src/game_graphics/zones/command_zone.cpp +++ b/cockatrice/src/game_graphics/zones/command_zone.cpp @@ -105,12 +105,12 @@ void CommandZone::handleDropEvent(const QList &dragItems, return; } + const auto &cards = getLogic()->getCards(); int index = calcDropIndexFromY(dropPoint.y(), MIN_CARD_VISIBLE); - // Same-zone no-op: don't move a card onto itself - const auto &cards = getLogic()->getCards(); - if (!cards.isEmpty() && index < cards.size() && startZone == getLogic() && - cards.at(index)->getId() == dragItems.at(0)->getId()) { + // Same-zone no-op: don't move a card onto itself (index may equal size for append) + if (startZone == getLogic() && !cards.isEmpty() && + cards.at(qMin(index, static_cast(cards.size()) - 1))->getId() == dragItems.at(0)->getId()) { return; } diff --git a/cockatrice/src/game_graphics/zones/select_zone.cpp b/cockatrice/src/game_graphics/zones/select_zone.cpp index c58c41b92..8e9228f9f 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.cpp +++ b/cockatrice/src/game_graphics/zones/select_zone.cpp @@ -94,7 +94,7 @@ int SelectZone::calcDropIndexFromY(qreal dropY, qreal minOffset) const if (effectiveOffset <= 0.0) { return 0; } - return qBound(0, qRound((dropY - start) / effectiveOffset), params.cardCount - 1); + return qBound(0, qRound((dropY - start) / effectiveOffset), params.cardCount); } void SelectZone::restoreStaleEscapedCards() diff --git a/cockatrice/src/game_graphics/zones/select_zone.h b/cockatrice/src/game_graphics/zones/select_zone.h index 7408f29b6..7b52fd5cb 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.h +++ b/cockatrice/src/game_graphics/zones/select_zone.h @@ -103,7 +103,7 @@ protected: /** * @brief Computes the card index at a given y-coordinate within the zone's vertical layout. - * Returns 0 if the zone has no cards or the offset is zero. + * Returns 0..cardCount (inclusive), where cardCount means append after the last card. */ int calcDropIndexFromY(qreal dropY, qreal minOffset = 0.0) const; diff --git a/cockatrice/src/game_graphics/zones/stack_zone.cpp b/cockatrice/src/game_graphics/zones/stack_zone.cpp index ee2467baa..4ecac8707 100644 --- a/cockatrice/src/game_graphics/zones/stack_zone.cpp +++ b/cockatrice/src/game_graphics/zones/stack_zone.cpp @@ -48,17 +48,12 @@ void StackZone::handleDropEvent(const QList &dragItems, } const auto &cards = getLogic()->getCards(); - int index; - if (startZone == getLogic()) { - // Reordering within the zone: use drop position - index = calcDropIndexFromY(dropPoint.y(), MIN_CARD_VISIBLE); - // Same-zone no-op: don't move a card onto itself - if (!cards.isEmpty() && cards.at(index)->getId() == dragItems.at(0)->getId()) { - return; - } - } else { - // Coming from another zone: append at end (top of stack, rendered on top) - index = static_cast(cards.size()); + int index = calcDropIndexFromY(dropPoint.y(), MIN_CARD_VISIBLE); + + // Same-zone no-op: don't move a card onto itself (index may equal size for append) + if (startZone == getLogic() && !cards.isEmpty() && + cards.at(qMin(index, static_cast(cards.size()) - 1))->getId() == dragItems.at(0)->getId()) { + return; } Command_MoveCard cmd;