diff --git a/cockatrice/src/game/game_scene.cpp b/cockatrice/src/game/game_scene.cpp index f8217305e..71937f1dc 100644 --- a/cockatrice/src/game/game_scene.cpp +++ b/cockatrice/src/game/game_scene.cpp @@ -142,7 +142,7 @@ void GameScene::rearrange() processViewSizeChange(viewSize); } -void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numberCards) +void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numberCards, bool isReversed) { for (auto &view : zoneViews) { ZoneViewZone *temp = view->getZone(); @@ -151,7 +151,8 @@ void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numb } } - ZoneViewWidget *item = new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards, false); + ZoneViewWidget *item = + new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards, false, false, {}, isReversed); zoneViews.append(item); connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeZoneView(ZoneViewWidget *))); addItem(item); diff --git a/cockatrice/src/game/game_scene.h b/cockatrice/src/game/game_scene.h index 7b80b8b6f..e7fc85f23 100644 --- a/cockatrice/src/game/game_scene.h +++ b/cockatrice/src/game/game_scene.h @@ -47,7 +47,7 @@ public: void registerAnimationItem(AbstractCardItem *item); void unregisterAnimationItem(AbstractCardItem *card); public slots: - void toggleZoneView(Player *player, const QString &zoneName, int numberCards); + void toggleZoneView(Player *player, const QString &zoneName, int numberCards, bool isReversed = false); void addRevealedZoneView(Player *player, CardZone *zone, const QList &cardList, diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index b4f6a95d0..a120e4b4b 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -217,6 +217,8 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T aViewTopCards = new QAction(this); connect(aViewTopCards, SIGNAL(triggered()), this, SLOT(actViewTopCards())); + aViewBottomCards = new QAction(this); + connect(aViewBottomCards, &QAction::triggered, this, &Player::actViewBottomCards); aAlwaysRevealTopCard = new QAction(this); aAlwaysRevealTopCard->setCheckable(true); connect(aAlwaysRevealTopCard, SIGNAL(triggered()), this, SLOT(actAlwaysRevealTopCard())); @@ -315,6 +317,7 @@ Player::Player(const ServerInfo_User &info, int _id, bool _local, bool _judge, T libraryMenu->addSeparator(); libraryMenu->addAction(aViewLibrary); libraryMenu->addAction(aViewTopCards); + libraryMenu->addAction(aViewBottomCards); libraryMenu->addSeparator(); playerLists.append(mRevealLibrary = libraryMenu->addMenu(QString())); singlePlayerLists.append(mLendLibrary = libraryMenu->addMenu(QString())); @@ -776,6 +779,7 @@ void Player::retranslateUi() aViewLibrary->setText(tr("&View library")); aViewHand->setText(tr("&View hand")); aViewTopCards->setText(tr("View &top cards of library...")); + aViewBottomCards->setText(tr("View bottom cards of library...")); mRevealLibrary->setTitle(tr("Reveal &library to...")); mLendLibrary->setTitle(tr("Lend library to...")); mRevealTopCard->setTitle(tr("Reveal &top cards to...")); @@ -969,6 +973,7 @@ void Player::setShortcutsActive() aViewLibrary->setShortcut(shortcuts.getSingleShortcut("Player/aViewLibrary")); aViewHand->setShortcut(shortcuts.getSingleShortcut("Player/aViewHand")); aViewTopCards->setShortcut(shortcuts.getSingleShortcut("Player/aViewTopCards")); + aViewBottomCards->setShortcut(shortcuts.getSingleShortcut("Player/aViewBottomCards")); aViewGraveyard->setShortcut(shortcuts.getSingleShortcut("Player/aViewGraveyard")); aDrawCard->setShortcut(shortcuts.getSingleShortcut("Player/aDrawCard")); aDrawCards->setShortcut(shortcuts.getSingleShortcut("Player/aDrawCards")); @@ -1018,6 +1023,7 @@ void Player::setShortcutsInactive() aViewLibrary->setShortcut(QKeySequence()); aViewHand->setShortcut(QKeySequence()); aViewTopCards->setShortcut(QKeySequence()); + aViewBottomCards->setShortcut(QKeySequence()); aViewGraveyard->setShortcut(QKeySequence()); aDrawCard->setShortcut(QKeySequence()); aDrawCards->setShortcut(QKeySequence()); @@ -1128,6 +1134,19 @@ void Player::actViewTopCards() } } +void Player::actViewBottomCards() +{ + int deckSize = zones.value("deck")->getCards().size(); + bool ok; + int number = + QInputDialog::getInt(game, tr("View bottom cards of library"), tr("Number of cards: (max. %1)").arg(deckSize), + defaultNumberTopCards, 1, deckSize, 1, &ok); + if (ok) { + defaultNumberTopCards = number; + static_cast(scene())->toggleZoneView(this, "deck", number, true); + } +} + void Player::actAlwaysRevealTopCard() { Command_ChangeZoneProperties cmd; @@ -2227,7 +2246,7 @@ void Player::eventDumpZone(const Event_DumpZone &event) if (!zone) { return; } - emit logDumpZone(this, zone, event.number_cards()); + emit logDumpZone(this, zone, event.number_cards(), event.is_reversed()); } void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext &context) diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index 8ef06ca30..2154b4306 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -138,7 +138,7 @@ signals: void logSetDoesntUntap(Player *player, CardItem *card, bool doesntUntap); void logSetPT(Player *player, CardItem *card, QString newPT); void logSetAnnotation(Player *player, CardItem *card, QString newAnnotation); - void logDumpZone(Player *player, CardZone *zone, int numberCards); + void logDumpZone(Player *player, CardZone *zone, int numberCards, bool isReversed = false); void logRevealCards(Player *player, CardZone *zone, int cardId, @@ -192,6 +192,7 @@ public slots: void actViewLibrary(); void actViewHand(); void actViewTopCards(); + void actViewBottomCards(); void actAlwaysRevealTopCard(); void actAlwaysLookAtTopCard(); void actViewGraveyard(); @@ -256,11 +257,11 @@ private: QAction *aMoveHandToTopLibrary, *aMoveHandToBottomLibrary, *aMoveHandToGrave, *aMoveHandToRfg, *aMoveGraveToTopLibrary, *aMoveGraveToBottomLibrary, *aMoveGraveToHand, *aMoveGraveToRfg, *aMoveRfgToTopLibrary, *aMoveRfgToBottomLibrary, *aMoveRfgToHand, *aMoveRfgToGrave, *aViewHand, *aViewLibrary, *aViewTopCards, - *aAlwaysRevealTopCard, *aAlwaysLookAtTopCard, *aOpenDeckInDeckEditor, *aMoveTopCardToGraveyard, - *aMoveTopCardToExile, *aMoveTopCardsToGraveyard, *aMoveTopCardsToExile, *aMoveTopCardsUntil, - *aMoveTopCardToBottom, *aViewGraveyard, *aViewRfg, *aViewSideboard, *aDrawCard, *aDrawCards, *aUndoDraw, - *aMulligan, *aShuffle, *aMoveTopToPlay, *aMoveTopToPlayFaceDown, *aUntapAll, *aRollDie, *aCreateToken, - *aCreateAnotherToken, *aMoveBottomToPlay, *aMoveBottomToPlayFaceDown, *aMoveBottomCardToTop, + *aViewBottomCards, *aAlwaysRevealTopCard, *aAlwaysLookAtTopCard, *aOpenDeckInDeckEditor, + *aMoveTopCardToGraveyard, *aMoveTopCardToExile, *aMoveTopCardsToGraveyard, *aMoveTopCardsToExile, + *aMoveTopCardsUntil, *aMoveTopCardToBottom, *aViewGraveyard, *aViewRfg, *aViewSideboard, *aDrawCard, + *aDrawCards, *aUndoDraw, *aMulligan, *aShuffle, *aMoveTopToPlay, *aMoveTopToPlayFaceDown, *aUntapAll, *aRollDie, + *aCreateToken, *aCreateAnotherToken, *aMoveBottomToPlay, *aMoveBottomToPlayFaceDown, *aMoveBottomCardToTop, *aMoveBottomCardToGraveyard, *aMoveBottomCardToExile, *aMoveBottomCardsToGraveyard, *aMoveBottomCardsToExile, *aDrawBottomCard, *aDrawBottomCards; diff --git a/cockatrice/src/game/zones/card_zone.cpp b/cockatrice/src/game/zones/card_zone.cpp index 6252bd297..4c3fd9db5 100644 --- a/cockatrice/src/game/zones/card_zone.cpp +++ b/cockatrice/src/game/zones/card_zone.cpp @@ -5,6 +5,7 @@ #include "../player/player.h" #include "pb/command_move_card.pb.h" #include "pb/serverinfo_user.pb.h" +#include "pile_zone.h" #include "view_zone.h" #include @@ -151,7 +152,7 @@ void CardZone::addCard(CardItem *card, const bool reorganize, const int x, const } for (auto *view : views) { - if ((x <= view->getCards().size()) || (view->getNumberCards() == -1)) { + if (view->getIsReversed() || (x <= view->getCards().size()) || (view->getNumberCards() == -1)) { view->addCard(new CardItem(player, nullptr, card->getName(), card->getProviderId(), card->getId()), reorganize, x, y); } @@ -199,12 +200,12 @@ CardItem *CardZone::takeCard(int position, int cardId, bool /*canResize*/) if (position >= cards.size()) return nullptr; - CardItem *c = cards.takeAt(position); - for (auto *view : views) { view->removeCard(position); } + CardItem *c = cards.takeAt(position); + c->setId(cardId); reorganizeCards(); diff --git a/cockatrice/src/game/zones/view_zone.cpp b/cockatrice/src/game/zones/view_zone.cpp index 0187e8ee5..215fb2bf9 100644 --- a/cockatrice/src/game/zones/view_zone.cpp +++ b/cockatrice/src/game/zones/view_zone.cpp @@ -28,10 +28,12 @@ ZoneViewZone::ZoneViewZone(Player *_p, int _numberCards, bool _revealZone, bool _writeableRevealZone, - QGraphicsItem *parent) + QGraphicsItem *parent, + bool _isReversed) : SelectZone(_p, _origZone->getName(), false, false, true, parent, true), bRect(QRectF()), minRows(0), numberCards(_numberCards), origZone(_origZone), revealZone(_revealZone), - writeableRevealZone(_writeableRevealZone), groupBy(CardList::NoSort), sortBy(CardList::NoSort) + writeableRevealZone(_writeableRevealZone), groupBy(CardList::NoSort), sortBy(CardList::NoSort), + isReversed(_isReversed) { if (!(revealZone && !writeableRevealZone)) { origZone->getViews().append(this); @@ -72,6 +74,7 @@ void ZoneViewZone::initializeCards(const QList &cardLis cmd.set_player_id(player->getId()); cmd.set_zone_name(name.toStdString()); cmd.set_number_cards(numberCards); + cmd.set_is_reversed(isReversed); PendingCommand *pend = player->prepareGameCommand(cmd); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, @@ -100,18 +103,49 @@ void ZoneViewZone::zoneDumpReceived(const Response &r) auto *card = new CardItem(player, this, cardName, cardProviderId, cardInfo.id(), revealZone, this); cards.insert(i, card); } + + updateCardIds(INITIALIZE); reorganizeCards(); emit cardCountChanged(); } +void ZoneViewZone::updateCardIds(CardAction action) +{ + if (origZone->contentsKnown()) { + return; + } + + if (cards.isEmpty()) { + return; + } + + int cardCount = cards.size(); + + auto startId = 0; + + if (isReversed) { + // the card has not been added to origZone's cardList at this point + startId = origZone->getCards().size() - cardCount; + switch (action) { + case INITIALIZE: + break; + case ADD_CARD: + startId += 1; + break; + case REMOVE_CARD: + startId -= 1; + break; + } + } + + for (int i = 0; i < cardCount; ++i) { + cards[i]->setId(i + startId); + } +} + // Because of boundingRect(), this function must not be called before the zone was added to a scene. void ZoneViewZone::reorganizeCards() { - int cardCount = cards.size(); - if (!origZone->contentsKnown()) - for (int i = 0; i < cardCount; ++i) - cards[i]->setId(i); - CardList cardsToDisplay(cards); // sort cards @@ -244,13 +278,30 @@ void ZoneViewZone::setPileView(int _pileView) void ZoneViewZone::addCardImpl(CardItem *card, int x, int /*y*/) { - // if x is negative set it to add at end - if (x < 0 || x >= cards.size()) { - x = cards.size(); + if (!isReversed) { + // if x is negative set it to add at end + if (x < 0) { + x = cards.size(); + } + cards.insert(x, card); + } else { + // map x (which is in origZone indexes) to this viewZone's cardList index + int firstId = cards.isEmpty() ? origZone->getCards().size() : cards.front()->getId(); + int insertionIndex = x - firstId; + if (insertionIndex >= 0) { + // card was put into a portion of the deck that's in the view + cards.insert(insertionIndex, card); + } else { + // card was put into a portion of the deck that's not in the view + updateCardIds(ADD_CARD); + return; + } } - cards.insert(x, card); + card->setParentItem(this); card->update(); + + updateCardIds(ADD_CARD); reorganizeCards(); } @@ -265,6 +316,7 @@ void ZoneViewZone::handleDropEvent(const QList &dragItems, cmd.set_target_zone(getName().toStdString()); cmd.set_x(0); cmd.set_y(0); + cmd.set_is_reversed(isReversed); for (int i = 0; i < dragItems.size(); ++i) cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId()); @@ -274,11 +326,21 @@ void ZoneViewZone::handleDropEvent(const QList &dragItems, void ZoneViewZone::removeCard(int position) { - if (position >= cards.size()) + if (isReversed) { + position -= cards.first()->getId(); + if (position < 0 || position >= cards.size()) { + updateCardIds(REMOVE_CARD); + return; + } + } + + if (position >= cards.size()) { return; + } CardItem *card = cards.takeAt(position); card->deleteLater(); + updateCardIds(REMOVE_CARD); reorganizeCards(); } diff --git a/cockatrice/src/game/zones/view_zone.h b/cockatrice/src/game/zones/view_zone.h index b1f5270b6..4780d73d1 100644 --- a/cockatrice/src/game/zones/view_zone.h +++ b/cockatrice/src/game/zones/view_zone.h @@ -34,6 +34,16 @@ private: bool revealZone, writeableRevealZone; CardList::SortOption groupBy, sortBy; bool pileView; + bool isReversed; + + enum CardAction + { + INITIALIZE, + ADD_CARD, + REMOVE_CARD + }; + + void updateCardIds(CardAction action); struct GridSize { @@ -49,7 +59,8 @@ public: int _numberCards = -1, bool _revealZone = false, bool _writeableRevealZone = false, - QGraphicsItem *parent = nullptr); + QGraphicsItem *parent = nullptr, + bool _isReversed = false); ~ZoneViewZone(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -74,6 +85,10 @@ public: return writeableRevealZone; } void setWriteableRevealZone(bool _writeableRevealZone); + bool getIsReversed() const + { + return isReversed; + } public slots: void setGroupBy(CardList::SortOption _groupBy); void setSortBy(CardList::SortOption _sortBy); diff --git a/cockatrice/src/game/zones/view_zone_widget.cpp b/cockatrice/src/game/zones/view_zone_widget.cpp index 1489ab723..f1e96c532 100644 --- a/cockatrice/src/game/zones/view_zone_widget.cpp +++ b/cockatrice/src/game/zones/view_zone_widget.cpp @@ -31,7 +31,8 @@ ZoneViewWidget::ZoneViewWidget(Player *_player, int numberCards, bool _revealZone, bool _writeableRevealZone, - const QList &cardList) + const QList &cardList, + bool _isReversed) : QGraphicsWidget(0, Qt::Window), canBeShuffled(_origZone->getIsShufflable()), player(_player) { setAcceptHoverEvents(true); @@ -107,7 +108,8 @@ ZoneViewWidget::ZoneViewWidget(Player *_player, vbox->addItem(zoneHBox); - zone = new ZoneViewZone(player, _origZone, numberCards, _revealZone, _writeableRevealZone, zoneContainer); + zone = + new ZoneViewZone(player, _origZone, numberCards, _revealZone, _writeableRevealZone, zoneContainer, _isReversed); connect(zone, SIGNAL(wheelEventReceived(QGraphicsSceneWheelEvent *)), scrollBarProxy, SLOT(recieveWheelEvent(QGraphicsSceneWheelEvent *))); diff --git a/cockatrice/src/game/zones/view_zone_widget.h b/cockatrice/src/game/zones/view_zone_widget.h index 9b0714dce..d656c4cb2 100644 --- a/cockatrice/src/game/zones/view_zone_widget.h +++ b/cockatrice/src/game/zones/view_zone_widget.h @@ -75,7 +75,8 @@ public: int numberCards = 0, bool _revealZone = false, bool _writeableRevealZone = false, - const QList &cardList = QList()); + const QList &cardList = QList(), + bool _isReversed = false); ZoneViewZone *getZone() const { return zone; diff --git a/cockatrice/src/server/message_log_widget.cpp b/cockatrice/src/server/message_log_widget.cpp index 0538517f5..12651eaa2 100644 --- a/cockatrice/src/server/message_log_widget.cpp +++ b/cockatrice/src/server/message_log_widget.cpp @@ -378,7 +378,7 @@ void MessageLogWidget::logDrawCards(Player *player, int number, bool deckIsEmpty } } -void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards) +void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards, bool isReversed) { if (numberCards == -1) { appendHtmlServerMessage(tr("%1 is looking at %2.") @@ -386,10 +386,11 @@ void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCar .arg(zone->getTranslatedName(zone->getPlayer() == player, CaseLookAtZone))); } else { appendHtmlServerMessage( - tr("%1 is looking at the top %3 card(s) %2.", "top card for singular, top %3 cards for plural", numberCards) + tr("%1 is looking at the %4 %3 card(s) %2.", "top card for singular, top %3 cards for plural", numberCards) .arg(sanitizeHtml(player->getName())) .arg(zone->getTranslatedName(zone->getPlayer() == player, CaseTopCardsOfZone)) - .arg("" + QString::number(numberCards) + "")); + .arg("" + QString::number(numberCards) + "") + .arg(isReversed ? tr("bottom") : tr("top"))); } } @@ -850,7 +851,7 @@ void MessageLogWidget::connectToPlayer(Player *player) 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, &Player::logDumpZone, this, &MessageLogWidget::logDumpZone); connect(player, SIGNAL(logDrawCards(Player *, int, bool)), this, SLOT(logDrawCards(Player *, int, bool))); connect(player, SIGNAL(logUndoDraw(Player *, QString)), this, SLOT(logUndoDraw(Player *, QString))); connect(player, SIGNAL(logRevealCards(Player *, CardZone *, int, QString, Player *, bool, int, bool)), this, diff --git a/cockatrice/src/server/message_log_widget.h b/cockatrice/src/server/message_log_widget.h index 8dc28b1b0..b95ed0f12 100644 --- a/cockatrice/src/server/message_log_widget.h +++ b/cockatrice/src/server/message_log_widget.h @@ -57,7 +57,7 @@ public slots: void logDeckSelect(Player *player, QString deckHash, int sideboardSize); void logDestroyCard(Player *player, QString cardName); void logDrawCards(Player *player, int number, bool deckIsEmpty); - void logDumpZone(Player *player, CardZone *zone, int numberCards); + void logDumpZone(Player *player, CardZone *zone, int numberCards, bool isReversed = false); void logFlipCard(Player *player, QString cardName, bool faceDown); void logGameClosed(); void logGameStart(); diff --git a/cockatrice/src/settings/shortcuts_settings.h b/cockatrice/src/settings/shortcuts_settings.h index 4b1a6e882..91a76d633 100644 --- a/cockatrice/src/settings/shortcuts_settings.h +++ b/cockatrice/src/settings/shortcuts_settings.h @@ -496,6 +496,9 @@ private: {"Player/aViewTopCards", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Top Cards of Library"), parseSequenceString("Ctrl+W"), ShortcutGroup::View)}, + {"Player/aViewBottomCards", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Bottom Cards of Library"), + parseSequenceString("Ctrl+Shift+W"), + ShortcutGroup::View)}, {"Player/aCloseMostRecentZoneView", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Close Recent View"), parseSequenceString("Esc"), ShortcutGroup::View)}, diff --git a/common/pb/command_dump_zone.proto b/common/pb/command_dump_zone.proto index 07bfe1950..21bac21c2 100644 --- a/common/pb/command_dump_zone.proto +++ b/common/pb/command_dump_zone.proto @@ -7,4 +7,5 @@ message Command_DumpZone { optional sint32 player_id = 1 [default = -1]; optional string zone_name = 2; optional sint32 number_cards = 3; + optional bool is_reversed = 4 [default = false]; } diff --git a/common/pb/command_move_card.proto b/common/pb/command_move_card.proto index 590a834b3..6003fb912 100644 --- a/common/pb/command_move_card.proto +++ b/common/pb/command_move_card.proto @@ -22,4 +22,5 @@ message Command_MoveCard { optional string target_zone = 5; optional sint32 x = 6 [default = -1]; optional sint32 y = 7 [default = -1]; + optional bool is_reversed = 8 [default = false]; } diff --git a/common/pb/event_dump_zone.proto b/common/pb/event_dump_zone.proto index f3dc08522..06c7a99d0 100644 --- a/common/pb/event_dump_zone.proto +++ b/common/pb/event_dump_zone.proto @@ -8,4 +8,5 @@ message Event_DumpZone { optional sint32 zone_owner_id = 1; optional string zone_name = 2; optional sint32 number_cards = 3; + optional bool is_reversed = 4 [default = false]; } diff --git a/common/server_player.cpp b/common/server_player.cpp index 5f0fd688c..74d4b751a 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -424,7 +424,8 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, int xCoord, int yCoord, bool fixFreeSpaces, - bool undoingDraw) + bool undoingDraw, + bool isReversed) { // Disallow controller change to other zones than the table. if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && @@ -542,7 +543,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, if (card) { ++xIndex; - int newX = xCoord + xIndex; + int newX = isReversed ? targetzone->getCards().size() - xCoord + xIndex : xCoord + xIndex; if (targetzone->hasCoords()) { newX = targetzone->getFreeGridColumn(newX, yCoord, card->getName(), faceDown); @@ -553,7 +554,7 @@ Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, targetzone->insertCard(card, newX, yCoord); int targetLookedCards = targetzone->getCardsBeingLookedAt(); - bool sourceKnownToPlayer = sourceBeingLookedAt && !card->getFaceDown(); + bool sourceKnownToPlayer = isReversed || (sourceBeingLookedAt && !card->getFaceDown()); if (targetzone->getType() == ServerInfo_Zone::HiddenZone && targetLookedCards >= newX) { if (sourceKnownToPlayer) { targetLookedCards += 1; @@ -1247,7 +1248,7 @@ Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc cardsToMove.append(&cmd.cards_to_move().card(i)); } - return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y()); + return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y(), true, false, cmd.is_reversed()); } Response::ResponseCode @@ -2008,13 +2009,14 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G zoneInfo->set_card_count(numberCards < cards.size() ? cards.size() : numberCards); for (int i = 0; (i < cards.size()) && (i < numberCards || numberCards == -1); ++i) { - Server_Card *card = cards[i]; + const auto &findId = cmd.is_reversed() ? cards.size() - numberCards + i : i; + Server_Card *card = cards[findId]; QString displayedName = card->getFaceDown() ? QString() : card->getName(); ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); cardInfo->set_provider_id(card->getProviderId().toStdString()); cardInfo->set_name(displayedName.toStdString()); if (zone->getType() == ServerInfo_Zone::HiddenZone) { - cardInfo->set_id(i); + cardInfo->set_id(findId); } else { cardInfo->set_id(card->getId()); cardInfo->set_x(card->getX()); @@ -2050,6 +2052,7 @@ Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, G event.set_zone_owner_id(otherPlayer->getPlayerId()); event.set_zone_name(zone->getName().toStdString()); event.set_number_cards(numberCards); + event.set_is_reversed(cmd.is_reversed()); ges.enqueueGameEvent(event, playerId); } rc.setResponseExtension(re); diff --git a/common/server_player.h b/common/server_player.h index 20cb2aea1..ffa12f8b0 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -179,7 +179,8 @@ public: int xCoord, int yCoord, bool fixFreeSpaces = true, - bool undoingDraw = false); + bool undoingDraw = false, + bool isReversed = false); void unattachCard(GameEventStorage &ges, Server_Card *card); Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, int targetPlayerId,