diff --git a/common/server_game.cpp b/common/server_game.cpp index 734db1cb..71ad8fb7 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -266,7 +266,7 @@ void Server_Game::removePlayer(Server_Player *player) QMutexLocker locker(&gameMutex); players.remove(player->getPlayerId()); - removeArrowsToPlayer(player); + removeArrowsRelatedToPlayer(player); sendGameEvent(new Event_Leave(player->getPlayerId())); bool playerActive = activePlayer == player->getPlayerId(); @@ -299,11 +299,13 @@ void Server_Game::removePlayer(Server_Player *player) room->broadcastGameListUpdate(this); } -void Server_Game::removeArrowsToPlayer(Server_Player *player) +void Server_Game::removeArrowsRelatedToPlayer(Server_Player *player) { QMutexLocker locker(&gameMutex); // Remove all arrows of other players pointing to the player being removed or to one of his cards. + // Also remove all arrows starting at one of his cards. This is necessary since players can create + // arrows that start at another person's cards. QMapIterator playerIterator(players); while (playerIterator.hasNext()) { Server_Player *p = playerIterator.next().value(); @@ -315,7 +317,11 @@ void Server_Game::removeArrowsToPlayer(Server_Player *player) if (targetCard) { if (targetCard->getZone()->getPlayer() == player) toDelete.append(a); - } else if ((static_cast(a->getTargetItem()) == player) || (a->getStartCard()->getZone()->getPlayer() == player)) + } else if (static_cast(a->getTargetItem()) == player) + toDelete.append(a); + + // Don't use else here! It has to happen regardless of whether targetCard == 0. + if (a->getStartCard()->getZone()->getPlayer() == player) toDelete.append(a); } for (int i = 0; i < toDelete.size(); ++i) { diff --git a/common/server_game.h b/common/server_game.h index 0b1ecc8e..20704245 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -82,7 +82,7 @@ public: bool containsUser(const QString &userName) const; Server_Player *addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate = true); void removePlayer(Server_Player *player); - void removeArrowsToPlayer(Server_Player *player); + void removeArrowsRelatedToPlayer(Server_Player *player); bool kickPlayer(int playerId); void startGameIfReady(); void stopGameIfFinished(); diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 8a7336f8..3a1b11b7 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -632,7 +632,7 @@ ResponseCode Server_ProtocolHandler::cmdConcede(Command_Concede * /*cmd*/, Comma return RespContextError; player->setConceded(true); - game->removeArrowsToPlayer(player); + game->removeArrowsRelatedToPlayer(player); player->clearZones(); game->sendGameEvent(new Event_PlayerPropertiesChanged(player->getPlayerId(), player->getProperties()), new Context_Concede); game->stopGameIfFinished();