[Game] Inject settings providers into libcockatrice_game, drop Widgets

This commit is contained in:
Lukas Brübach 2026-10-11 15:11:54 +02:00 • committed by GitHub
parent db3caf4c5d
commit 31ce200ba0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 199 additions and 84 deletions

View file

@ -2,13 +2,18 @@
#define COCKATRICE_SETTINGS_CARD_PREFERENCE_PROVIDER_H
#include "../../client/settings/cache_settings.h"
#include <QObject>
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
#include <libcockatrice/settings/card_override_settings.h>
#include <libcockatrice/settings/cards_display_settings.h>
class SettingsCardPreferenceProvider : public ICardPreferenceProvider
class SettingsCardPreferenceProvider : public QObject, public ICardPreferenceProvider
{
public:
explicit SettingsCardPreferenceProvider(QObject *parent = nullptr) : QObject(parent)
{
}
[[nodiscard]] QString getCardPreferenceOverride(const QString &cardName) const override
{
return SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardName);

View file

@ -1,9 +1,9 @@
#include "arrow_registry.h"
#include "../../game/board/arrow_data.h"
#include "arrow_item.h"
#include <QSharedPointer>
#include <libcockatrice/game/board/arrow_data.h>
void ArrowRegistry::insert(QSharedPointer<ArrowData> data, ArrowItem *arrow)
{

View file

@ -2,9 +2,6 @@
#include "../../client/settings/cache_settings.h"
#include "../../client/settings/shortcuts_settings.h"
#include "../../game/abstract_game.h"
#include "../../game/game_event_handler.h"
#include "../../game/game_state.h"
#include "../../interface/card_picture_loader/card_picture_loader.h"
#include "../../interface/deck_loader/deck_file_format.h"
#include "../../interface/deck_loader/deck_loader.h"
@ -34,6 +31,9 @@
#include <QVBoxLayout>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/playmat_resolver.h>
#include <libcockatrice/game/abstract_game.h>
#include <libcockatrice/game/game_event_handler.h>
#include <libcockatrice/game/game_state.h>
#include <libcockatrice/protocol/pb/response_deck_download.pb.h>
#include <libcockatrice/protocol/pending_command.h>
#include <libcockatrice/settings/interface_settings.h>

View file

@ -1,7 +1,5 @@
#include "hand_counter.h"
#include "../game/board/card_list.h"
#include "../game/zones/card_zone_logic.h"
#include "../interface/pixel_map_generator.h"
#include <QGraphicsSceneMouseEvent>
@ -14,6 +12,8 @@
#include <QString>
#include <QStringLiteral>
#include <QTransform>
#include <libcockatrice/game/board/card_list.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <qnamespace.h>
class QGraphicsItem;

View file

@ -3,7 +3,6 @@
#include "../../client/settings/cache_settings.h"
#include "../../client/settings/card_counter_settings.h"
#include "../../client/sound_engine.h"
#include "../../client/translation.h"
#include "../../interface/card_localization.h"
#include "../../interface/widgets/server/chat_view/chat_view.h"
#include "../board/card_item.h"
@ -23,6 +22,7 @@
#include <libcockatrice/game/player/player_info.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/game/player/player_manager.h>
#include <libcockatrice/game/translation.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
#include <libcockatrice/protocol/pb/context_mulligan.pb.h>

View file

@ -2,10 +2,6 @@
#include "../../../client/settings/cache_settings.h"
#include "../../../client/settings/shortcuts_settings.h"
#include "../../../game/abstract_game.h"
#include "../../../game/player/player_info.h"
#include "../../../game/player/player_logic.h"
#include "../../../game/player/player_manager.h"
#include "../../../game_graphics/zones/hand_zone.h"
#include "../../../game_graphics/zones/pile_zone.h"
#include "../../../game_graphics/zones/table_zone.h"
@ -26,6 +22,10 @@
#include <QMenu>
#include <QString>
#include <libcockatrice/game/abstract_game.h>
#include <libcockatrice/game/player/player_info.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/game/player/player_manager.h>
PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_player)
{

View file

@ -2,8 +2,6 @@
#include "../../client/settings/cache_settings.h"
#include "../../client/settings/card_counter_settings.h"
#include "../../game/player/player_actions.h"
#include "../../game/player/player_logic.h"
#include "../../interface/widgets/utility/get_text_with_max.h"
#include "../board/abstract_counter.h"
#include "../board/card_item.h"
@ -18,6 +16,8 @@
#include <QInputDialog>
#include <QLineEdit>
#include <libcockatrice/card/relation/card_relation.h>
#include <libcockatrice/game/player/player_actions.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/utility/string_limits.h>
PlayerDialogs::PlayerDialogs(PlayerGraphicsItem *_player, PlayerActions *_playerActions)
@ -35,7 +35,7 @@ PlayerDialogs::PlayerDialogs(PlayerGraphicsItem *_player, PlayerActions *_player
&PlayerDialogs::onShuffleBottomDialogRequested);
connect(playerActions, &PlayerActions::requestMulliganDialog, this, &PlayerDialogs::onMulliganDialogRequested);
connect(playerActions, &PlayerActions::startingHandSizeChosen, this, &PlayerDialogs::onStartingHandSizeChosen);
connect(playerActions, &PlayerActions::requestDrawCardsDialog, this, &PlayerDialogs::onDrawCardsDialogRequested);
connect(playerActions, &PlayerActions::requestMoveTopCardsToDialog, this,
@ -127,6 +127,11 @@ void PlayerDialogs::onMulliganDialogRequested(int startSize, int handSize, int d
}
}
void PlayerDialogs::onStartingHandSizeChosen(int number)
{
SettingsCache::instance().userInterface().setStartingHandSize(number);
}
void PlayerDialogs::onDrawCardsDialogRequested(int defaultNumberTopCards, int deckSize)
{
bool ok;

View file

@ -17,6 +17,7 @@
class CardItem;
class CardRelation;
class CardState;
class PlayerActions;
class QWidget;
struct MoveTopCardsUntilOptions;
@ -58,6 +59,7 @@ public slots:
void onSetPTDialogRequested(const QString &oldPT);
void onSetAnnotationDialogRequested(const QString &oldAnnotation);
void onSetCardCounterDialogRequested(int counterId, const QString &oldValueForDlg);
void onStartingHandSizeChosen(int number);
private:
PlayerGraphicsItem *player;

View file

@ -1,13 +1,13 @@
#include "card_zone.h"
#include "../../game/board/card_list.h"
#include "../../game/zones/card_zone_logic.h"
#include "../board/abstract_graphics_item.h"
#include "../board/card_item.h"
#include <QAction>
#include <QGraphicsSceneMouseEvent>
#include <QMenu>
#include <libcockatrice/game/board/card_list.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <qnamespace.h>
class QGraphicsItem;

View file

@ -16,11 +16,13 @@
class CardDragItem;
class CardItem;
class CardState;
class CardZoneLogic;
class QAction;
class QGraphicsItem;
class QMenu;
class QPoint;
class ServerInfo_Card;
template <typename T> class QList;
class CardItem;

View file

@ -1,8 +1,6 @@
#include "select_zone.h"
#include "../../client/settings/cache_settings.h"
#include "../../game/board/card_list.h"
#include "../../game/zones/card_zone_logic.h"
#include "../board/card_item.h"
#include "../game_scene.h"
@ -17,6 +15,8 @@
#include <QTransform>
#include <QtGlobal>
#include <QtMath>
#include <libcockatrice/game/board/card_list.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <libcockatrice/settings/cards_display_settings.h>
#include <qnamespace.h>
#include <qnumeric.h>

View file

@ -18,6 +18,7 @@
#include <QPoint>
#include <QPointF>
#include <QtGlobal>
#include <libcockatrice/game/zones/table_zone_logic.h>
#include <qtmetamacros.h>
class CardDragItem;

View file

@ -1,7 +1,6 @@
#include "view_zone_widget.h"
#include "../../client/settings/cache_settings.h"
#include "../../client/translation.h"
#include "../../filters/syntax_help.h"
#include "../../interface/pixel_map_generator.h"
#include "../card_dimensions.h"
@ -42,6 +41,7 @@
#include <libcockatrice/game/board/card_list.h>
#include <libcockatrice/game/player/player_actions.h>
#include <libcockatrice/game/player/player_logic.h>
#include <libcockatrice/game/translation.h>
#include <libcockatrice/game/zones/card_zone_logic.h>
#include <libcockatrice/game/zones/view_zone_logic.h>
#include <libcockatrice/settings/cards_display_settings.h>
@ -176,9 +176,10 @@ ZoneViewWidget::ZoneViewWidget(PlayerLogic *_player,
vbox->addItem(zoneHBox);
zone = new ZoneViewZone(new ZoneViewZoneLogic(player, _origZone, numberCards, _revealZone, _writeableRevealZone,
_isReversed, zoneContainer),
zoneContainer);
zone =
new ZoneViewZone(new ZoneViewZoneLogic(player, _origZone, numberCards, _revealZone, _writeableRevealZone,
_isReversed, &SettingsCache::instance().userInterface(), zoneContainer),
zoneContainer);
connect(zone, &ZoneViewZone::wheelEventReceived, scrollBarProxy, &ScrollableGraphicsProxyWidget::recieveWheelEvent);
retranslateUi();

View file

@ -1,13 +1,13 @@
#include "replay_manager.h"
#include "../../../client/settings/cache_settings.h"
#include "../../../game/player/event_processing_options.h"
#include "libcockatrice/protocol/pb/game_event.pb.h"
#include "libcockatrice/protocol/pb/game_event_container.pb.h"
#include "libcockatrice/protocol/pb/game_replay.pb.h"
#include <QTimer>
#include <algorithm>
#include <libcockatrice/game/player/event_processing_options.h>
#include <libcockatrice/protocol/get_pb_extension.h>
#include <libcockatrice/settings/interface_settings.h>
#include <qnumeric.h>

View file

@ -8,9 +8,8 @@
#ifndef REPLAY_WIDGET_H
#define REPLAY_WIDGET_H
#include "../../../game/player/event_processing_options.h"
#include <QWidget>
#include <libcockatrice/game/player/event_processing_options.h>
#include <qtmetamacros.h>
class ReplayManager;

View file

@ -1,8 +1,5 @@
#include "user_context_menu.h"
#include "../../../../game/abstract_game.h"
#include "../../../../game/game_event_handler.h"
#include "../../../../game/game_meta_info.h"
#include "../../dialogs/dlg_report_user.h"
#include "../../interface/widgets/tabs/tab_supervisor.h"
#include "../chat_view/chat_view.h"
@ -37,6 +34,9 @@
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QWidget>
#include <libcockatrice/game/abstract_game.h>
#include <libcockatrice/game/game_event_handler.h>
#include <libcockatrice/game/game_meta_info.h>
#include <libcockatrice/network/client/abstract/abstract_client.h>
#include <libcockatrice/protocol/pb/command_kick_from_game.pb.h>
#include <libcockatrice/protocol/pb/commands.pb.h>

View file

@ -2,7 +2,10 @@
#include "../../../client/settings/cache_settings.h"
#include "../../../client/settings/shortcuts_settings.h"
#include "../../../database/interface/settings_card_preference_provider.h"
#include "../../../game_graphics/board/abstract_card_item.h"
#include "../game_graphics/board/arrow_item.h"
#include "../game_graphics/board/card_item.h"
#include "../game_graphics/deckview/deck_view_container.h"
#include "../game_graphics/deckview/tabbed_deck_view_container.h"
#include "../game_graphics/game_scene.h"
@ -96,7 +99,8 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
: Tab(_tabSupervisor), sayLabel(nullptr), sayEdit(nullptr)
{
// THIS CTOR IS USED ON REPLAY
game = new Replay(this, _replay, tabSupervisor->getIsLocalGame());
game = new Replay(this, _replay, tabSupervisor->getIsLocalGame(), &SettingsCache::instance().userInterface(),
new SettingsCardPreferenceProvider(this));
createCardInfoDock(true);
createPlayerListDock(true);
@ -140,7 +144,8 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
: Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager())
{
// THIS CTOR IS USED ON GAMES
game = new Game(this, tabSupervisor->getIsLocalGame(), _clients, event, _roomGameTypes);
game = new Game(this, tabSupervisor->getIsLocalGame(), _clients, event, _roomGameTypes,
&SettingsCache::instance().userInterface(), new SettingsCardPreferenceProvider(this));
createCardInfoDock();
createPlayerListDock();

View file

@ -2,10 +2,6 @@
#include "../../../client/settings/cache_settings.h"
#include "../../../client/settings/shortcuts_settings.h"
#include "../../../game/abstract_game.h"
#include "../../../game/game_event_handler.h"
#include "../../../game/game_meta_info.h"
#include "../../deck_loader/loaded_deck.h"
#include "../../intents/contexts/context_connect_to_server.h"
#include "../../intents/contexts/context_join_game.h"
#include "../../intents/contexts/context_join_room.h"
@ -65,6 +61,10 @@
#include <QStyleOption>
#include <QSystemTrayIcon>
#include <QTabBar>
#include <libcockatrice/deck_list/loaded_deck.h>
#include <libcockatrice/game/abstract_game.h>
#include <libcockatrice/game/game_event_handler.h>
#include <libcockatrice/game/game_meta_info.h>
#include <libcockatrice/network/client/abstract/abstract_client.h>
#include <libcockatrice/network/client/remote/remote_client.h>
#include <libcockatrice/protocol/pb/event_game_joined.pb.h>

View file

@ -63,19 +63,14 @@ add_library(
libcockatrice/game/zones/view_zone_logic.cpp
)
target_include_directories(
libcockatrice_game
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
# SettingsCache, the client-side settings facade the game logic still reads, lives in the
# application sources rather than in libcockatrice_settings.
PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src
)
target_include_directories(libcockatrice_game PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(
libcockatrice_game
PUBLIC libcockatrice_card
libcockatrice_deck_list
libcockatrice_filters
libcockatrice_interfaces
libcockatrice_network
libcockatrice_protocol
libcockatrice_settings
@ -83,5 +78,4 @@ target_link_libraries(
${QT_CORE_MODULE}
${COCKATRICE_QT_VERSION_NAME}::Concurrent
${COCKATRICE_QT_VERSION_NAME}::Gui
${COCKATRICE_QT_VERSION_NAME}::Widgets
)

View file

@ -3,6 +3,7 @@
#include <QSharedPointer>
#include <libcockatrice/card/card_info.h>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/database/card_database_querier.h>
void CardState::resetState(bool keepAnnotations)
{

View file

@ -16,13 +16,16 @@ Game::Game(QObject *_parent,
bool isLocalGame,
QList<AbstractClient *> &_clients,
const Event_GameJoined &event,
const QMap<int, QString> &_roomGameTypes)
const QMap<int, QString> &_roomGameTypes,
IInterfaceSettingsProvider *interfaceSettings,
ICardPreferenceProvider *cardPreferences)
: AbstractGame(_parent)
{
gameMetaInfo->setFromProto(event.game_info());
gameMetaInfo->setRoomGameTypes(_roomGameTypes);
gameState = new GameState(this, 0, event.host_id(), isLocalGame, _clients, false, event.resuming(), -1, false);
connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged);
playerManager = new PlayerManager(this, event.player_id(), event.judge(), event.spectator());
playerManager = new PlayerManager(this, event.player_id(), event.judge(), event.spectator(), interfaceSettings,
cardPreferences);
gameMetaInfo->setStarted(false);
}

View file

@ -18,6 +18,9 @@ class QString;
template <class Key, class T> class QMap;
template <typename T> class QList;
class ICardPreferenceProvider;
class IInterfaceSettingsProvider;
class Game : public AbstractGame
{
Q_OBJECT
@ -27,7 +30,9 @@ public:
bool isLocalGame,
QList<AbstractClient *> &_clients,
const Event_GameJoined &event,
const QMap<int, QString> &_roomGameTypes);
const QMap<int, QString> &_roomGameTypes,
IInterfaceSettingsProvider *interfaceSettings = nullptr,
ICardPreferenceProvider *cardPreferences = nullptr);
};
#endif // COCKATRICE_GAME_H

View file

@ -11,7 +11,6 @@
#include "../zones/pile_zone_logic.h"
#include "../zones/table_zone_logic.h"
#include "../zones/view_zone_logic.h"
#include "client/settings/cache_settings.h"
#include "libcockatrice/card/database/card_database_querier.h"
#include "libcockatrice/card/printing/exact_card.h"
#include "libcockatrice/card/printing/printing_info.h"
@ -46,6 +45,9 @@
#include <google/protobuf/stubs/port.h>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/relation/card_relation.h>
#include <libcockatrice/deck_list/loaded_deck.h>
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
#include <libcockatrice/interfaces/interface_interface_settings_provider.h>
#include <libcockatrice/protocol/pb/command_attach_card.pb.h>
#include <libcockatrice/protocol/pb/command_change_zone_properties.pb.h>
#include <libcockatrice/protocol/pb/command_create_arrow.pb.h>
@ -64,8 +66,7 @@
#include <libcockatrice/protocol/pb/command_set_counter.pb.h>
#include <libcockatrice/protocol/pb/command_shuffle.pb.h>
#include <libcockatrice/protocol/pb/command_undo_draw.pb.h>
#include <libcockatrice/settings/card_override_settings.h>
#include <libcockatrice/settings/interface_settings.h>
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
#include <libcockatrice/utility/clamped_arithmetic.h>
#include <libcockatrice/utility/color.h>
#include <libcockatrice/utility/counter_limits.h>
@ -79,8 +80,11 @@
// milliseconds in between triggers of the move top cards until action
static constexpr int MOVE_TOP_CARD_UNTIL_INTERVAL = 100;
PlayerActions::PlayerActions(PlayerLogic *_player)
: QObject(_player), player(_player), lastTokenTableRow(0), movingCardsUntil(false)
PlayerActions::PlayerActions(PlayerLogic *_player,
IInterfaceSettingsProvider *_interfaceSettings,
ICardPreferenceProvider *_cardPreferences)
: QObject(_player), player(_player), interfaceSettings(_interfaceSettings), cardPreferences(_cardPreferences),
lastTokenTableRow(0), movingCardsUntil(false)
{
connect(this, &PlayerActions::requestZoneViewToggle, player, &PlayerLogic::onRequestZoneViewToggle);
@ -90,6 +94,26 @@ PlayerActions::PlayerActions(PlayerLogic *_player)
connect(moveTopCardTimer, &QTimer::timeout, [this]() { actMoveTopCardToPlay(); });
}
bool PlayerActions::getPlayToStack() const
{
return interfaceSettings ? interfaceSettings->getPlayToStack() : true;
}
int PlayerActions::getStartingHandSize() const
{
return interfaceSettings ? interfaceSettings->getStartingHandSize() : 7;
}
bool PlayerActions::getAnnotateTokens() const
{
return interfaceSettings ? interfaceSettings->getAnnotateTokens() : false;
}
QString PlayerActions::getCardPreferenceOverride(const QString &cardName) const
{
return cardPreferences ? cardPreferences->getCardPreferenceOverride(cardName) : QString();
}
void PlayerActions::playCard(CardState *card, bool faceDown)
{
if (card == nullptr) {
@ -111,7 +135,7 @@ void PlayerActions::playCard(CardState *card, bool faceDown)
const CardInfo &info = exactCard.getInfo();
int tableRow = info.getUiAttributes().tableRow;
bool playToStack = SettingsCache::instance().userInterface().getPlayToStack();
bool playToStack = getPlayToStack();
QString currentZone = card->getZone()->getName();
if (!faceDown && currentZone == ZoneNames::STACK && tableRow == 3) {
cmd.set_target_zone(ZoneNames::GRAVE);
@ -213,7 +237,7 @@ void PlayerActions::createArrow(CardState *startCard, const ArrowData &arrow, in
// if the card is in hand then it has just been moved to the stack or table as part of drawing the arrow
if (arrow.startZone == ZoneNames::HAND) {
CardInfoPtr ci = startCard->getCard().getCardPtr();
bool playToStack = SettingsCache::instance().userInterface().getPlayToStack();
bool playToStack = getPlayToStack();
if (ci && ((!playToStack && ci->getUiAttributes().tableRow == 3) ||
(playToStack && ci->getUiAttributes().tableRow != 0 &&
startCard->getZone()->getName() != ZoneNames::STACK))) {
@ -408,7 +432,7 @@ void PlayerActions::actDrawCard()
void PlayerActions::actRequestMulliganDialog()
{
int startSize = SettingsCache::instance().userInterface().getStartingHandSize();
int startSize = getStartingHandSize();
int handSize = player->getHandZone()->getCards().size();
int deckSize = player->getDeckZone()->getCards().size() + handSize;
@ -424,7 +448,7 @@ void PlayerActions::actMulligan(int number)
}
doMulligan(number);
SettingsCache::instance().userInterface().setStartingHandSize(number);
emit startingHandSizeChosen(number);
}
void PlayerActions::actMulliganSameSize()
@ -973,13 +997,12 @@ void PlayerActions::setLastTokenInfo(CardInfoPtr cardInfo)
return;
}
lastTokenInfo = {
.name = cardInfo->getName(),
.color = cardInfo->getColors().isEmpty() ? QString() : cardInfo->getColors().left(1).toLower(),
.pt = cardInfo->getPowTough(),
.annotation = SettingsCache::instance().userInterface().getAnnotateTokens() ? cardInfo->getText() : "",
.destroy = true,
.providerId = SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardInfo->getName())};
lastTokenInfo = {.name = cardInfo->getName(),
.color = cardInfo->getColors().isEmpty() ? QString() : cardInfo->getColors().left(1).toLower(),
.pt = cardInfo->getPowTough(),
.annotation = getAnnotateTokens() ? cardInfo->getText() : "",
.destroy = true,
.providerId = getCardPreferenceOverride(cardInfo->getName())};
lastTokenTableRow = TableZoneLogic::tableRowToGridY(cardInfo->getUiAttributes().tableRow);
@ -1207,7 +1230,7 @@ void PlayerActions::createCard(const CardState *sourceCard,
}
cmd.set_pt(cardInfo->getPowTough().toStdString());
if (SettingsCache::instance().userInterface().getAnnotateTokens()) {
if (getAnnotateTokens()) {
cmd.set_annotation(cardInfo->getText().toStdString());
} else {
cmd.set_annotation("");

View file

@ -39,8 +39,12 @@ class Message;
class CardState;
class CardZoneLogic;
class Command_MoveCard;
class GameEventContext;
class ICardPreferenceProvider;
class IInterfaceSettingsProvider;
class PendingCommand;
class PlayerLogic;
class QAction;
struct ArrowData;
class PlayerActions : public QObject
{
@ -52,7 +56,9 @@ public:
RANDOM_CARD_FROM_ZONE = -2
};
explicit PlayerActions(PlayerLogic *player);
explicit PlayerActions(PlayerLogic *player,
IInterfaceSettingsProvider *interfaceSettings = nullptr,
ICardPreferenceProvider *cardPreferences = nullptr);
void sendGameCommand(PendingCommand *pend);
void sendGameCommand(const google::protobuf::Message &command);
@ -143,6 +149,12 @@ signals:
void requestSortHand(const QList<CardList::SortOption> &options);
void requestEnableAndSetCreateAnotherTokenAction(const QString &lastTokenName);
void requestSetLastToken(CardInfoPtr lastToken);
/**
* @brief The player chose a mulligan size to remember as the starting hand size.
*
* Game logic must not write client settings itself, so persistence is left to the application.
*/
void startingHandSizeChosen(int number);
public slots:
void setLastToken(CardInfoPtr cardInfo);
@ -275,6 +287,10 @@ public slots:
private:
PlayerLogic *player;
// Borrowed settings providers (owned by the application). Null outside the client, in which case the compiled-in
// defaults below apply.
IInterfaceSettingsProvider *interfaceSettings;
ICardPreferenceProvider *cardPreferences;
int defaultNumberTopCards = 1;
int defaultNumberTopCardsToPlaceBelow = 1;
@ -292,6 +308,11 @@ private:
bool lastRelatedCreationSucceeded = false;
[[nodiscard]] bool getPlayToStack() const;
[[nodiscard]] int getStartingHandSize() const;
[[nodiscard]] bool getAnnotateTokens() const;
[[nodiscard]] QString getCardPreferenceOverride(const QString &cardName) const;
void createCard(const CardState *sourceCard,
const QString &dbCardName,
CardRelationType attach = CardRelationType::DoesNotAttach,

View file

@ -28,6 +28,7 @@
#include <QtGlobal>
#include <algorithm>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/database/card_database_querier.h>
#include <libcockatrice/protocol/pb/command_set_card_attr.pb.h>
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
#include <libcockatrice/protocol/pb/context_undo_draw.pb.h>

View file

@ -39,10 +39,17 @@ static CardItem *toCardItem(CardState *card)
return card == nullptr ? nullptr : qobject_cast<CardItem *>(card->parent());
}
PlayerLogic::PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent)
PlayerLogic::PlayerLogic(const ServerInfo_User &info,
int _id,
bool _local,
bool _judge,
AbstractGame *_parent,
IInterfaceSettingsProvider *interfaceSettings,
ICardPreferenceProvider *cardPreferences)
: QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)),
playerEventHandler(new PlayerEventHandler(this)), playerActions(new PlayerActions(this)), active(false),
conceded(false), zoneId(0), dialogSemaphore(false)
playerEventHandler(new PlayerEventHandler(this)),
playerActions(new PlayerActions(this, interfaceSettings, cardPreferences)), active(false), conceded(false),
zoneId(0), dialogSemaphore(false)
{
initializeZones();
}

View file

@ -48,6 +48,8 @@ template <class T> class QSharedPointer;
inline Q_LOGGING_CATEGORY(PlayerLog, "player");
class AbstractCardItem;
class AbstractGame;
class ICardPreferenceProvider;
class IInterfaceSettingsProvider;
class PlayerInfo;
class PlayerEventHandler;
class PlayerActions;
@ -93,7 +95,13 @@ public slots:
void onRequestZoneViewToggle(const QString &zoneName, int numberCards, bool isReversed);
public:
PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent);
PlayerLogic(const ServerInfo_User &info,
int _id,
bool _local,
bool _judge,
AbstractGame *_parent,
IInterfaceSettingsProvider *interfaceSettings = nullptr,
ICardPreferenceProvider *cardPreferences = nullptr);
~PlayerLogic() override;
void initializeZones();

View file

@ -12,9 +12,12 @@
PlayerManager::PlayerManager(AbstractGame *_game,
int _localPlayerId,
bool _localPlayerIsJudge,
bool localPlayerIsSpectator)
bool localPlayerIsSpectator,
IInterfaceSettingsProvider *_interfaceSettings,
ICardPreferenceProvider *_cardPreferences)
: QObject(_game), game(_game), players(QMap<int, PlayerLogic *>()), localPlayerId(_localPlayerId),
localPlayerIsJudge(_localPlayerIsJudge), localPlayerIsSpectator(localPlayerIsSpectator)
localPlayerIsJudge(_localPlayerIsJudge), localPlayerIsSpectator(localPlayerIsSpectator),
interfaceSettings(_interfaceSettings), cardPreferences(_cardPreferences)
{
}
@ -52,7 +55,7 @@ bool PlayerManager::isLocalPlayer(int playerId)
PlayerLogic *PlayerManager::addPlayer(int playerId, const ServerInfo_User &info)
{
auto *newPlayer = new PlayerLogic(info, playerId, isLocalPlayer(playerId) || game->getGameState()->getIsLocalGame(),
isJudge(), getGame());
isJudge(), getGame(), interfaceSettings, cardPreferences);
connect(newPlayer, &PlayerLogic::concededChanged, this, &PlayerManager::onPlayerConceded);
players.insert(playerId, newPlayer);
emit playerAdded(newPlayer);

View file

@ -16,6 +16,8 @@
#include <qtmetamacros.h>
class AbstractGame;
class ICardPreferenceProvider;
class IInterfaceSettingsProvider;
class PlayerLogic;
class PlayerManager : public QObject
@ -23,7 +25,12 @@ class PlayerManager : public QObject
Q_OBJECT
public:
PlayerManager(AbstractGame *_game, int _localPlayerId, bool _localPlayerIsJudge, bool localPlayerIsSpectator);
PlayerManager(AbstractGame *_game,
int _localPlayerId,
bool _localPlayerIsJudge,
bool localPlayerIsSpectator,
IInterfaceSettingsProvider *interfaceSettings = nullptr,
ICardPreferenceProvider *cardPreferences = nullptr);
AbstractGame *game;
QMap<int, PlayerLogic *> players;
@ -31,6 +38,9 @@ public:
bool localPlayerIsJudge;
bool localPlayerIsSpectator;
QMap<int, ServerInfo_User> spectators;
// Borrowed settings providers forwarded to each PlayerLogic (owned by the application).
IInterfaceSettingsProvider *interfaceSettings;
ICardPreferenceProvider *cardPreferences;
[[nodiscard]] bool isSpectator() const
{

View file

@ -9,10 +9,15 @@
class GameReplay;
class QObject;
Replay::Replay(QObject *_parent, const GameReplay *_replay, bool isLocalGame) : AbstractGame(_parent)
Replay::Replay(QObject *_parent,
const GameReplay *_replay,
bool isLocalGame,
IInterfaceSettingsProvider *interfaceSettings,
ICardPreferenceProvider *cardPreferences)
: AbstractGame(_parent)
{
gameState = new GameState(this, 0, -1, isLocalGame, {}, false, false, -1, false);
connect(gameMetaInfo, &GameMetaInfo::startedChanged, gameState, &GameState::onStartedChanged);
playerManager = new PlayerManager(this, -1, false, true);
playerManager = new PlayerManager(this, -1, false, true, interfaceSettings, cardPreferences);
loadReplay(_replay);
}

View file

@ -14,13 +14,19 @@
class GameReplay;
class QObject;
class ICardPreferenceProvider;
class IInterfaceSettingsProvider;
class Replay : public AbstractGame
{
Q_OBJECT
public:
explicit Replay(QObject *_parent, const GameReplay *_replay, bool isLocalGame);
explicit Replay(QObject *_parent,
const GameReplay *_replay,
bool isLocalGame,
IInterfaceSettingsProvider *interfaceSettings = nullptr,
ICardPreferenceProvider *cardPreferences = nullptr);
};
#endif // COCKATRICE_REPLAY_H

View file

@ -1,12 +1,11 @@
#include "card_zone_logic.h"
#include "../../client/translation.h"
#include "../../game_graphics/zones/card_zone.h"
#include "../board/card_list.h"
#include "../board/card_state.h"
#include "../player/player_actions.h"
#include "../player/player_info.h"
#include "../player/player_logic.h"
#include "../translation.h"
#include "libcockatrice/card/database/card_database.h"
#include "view_zone_logic.h"

View file

@ -21,9 +21,6 @@ inline Q_LOGGING_CATEGORY(CardZoneLogicLog, "card_zone_logic");
class PlayerLogic;
class ZoneViewZoneLogic;
class QMenu;
class QAction;
class QPainter;
class CardDragItem;
class CardZoneLogic : public QObject

View file

@ -2,9 +2,9 @@
"
#include "../board/card_state.h"
#include "client/settings/cache_settings.h"
#include <QtGlobal>
#include <libcockatrice/interfaces/interface_interface_settings_provider.h>
#include <libcockatrice/settings/interface_settings.h>
class PlayerLogic;
@ -22,13 +22,19 @@ ZoneViewZoneLogic::ZoneViewZoneLogic(PlayerLogic *_player,
bool _revealZone,
bool _writeableRevealZone,
bool _isReversed,
IInterfaceSettingsProvider *_interfaceSettings,
QObject *parent)
: CardZoneLogic(_player, _origZone->getName(), false, false, true, parent), origZone(_origZone),
numberCards(_numberCards), revealZone(_revealZone), writeableRevealZone(_writeableRevealZone),
isReversed(_isReversed)
isReversed(_isReversed), interfaceSettings(_interfaceSettings)
{
}
bool ZoneViewZoneLogic::getCloseEmptyCardView() const
{
return interfaceSettings ? interfaceSettings->getCloseEmptyCardView() : true;
}
/**
* Checks if inserting a card at the given position requires an actual new card to be created and added to the view.
* Also does any cardId updates that would be required if a card is inserted in that position.
@ -64,7 +70,7 @@ bool ZoneViewZoneLogic::prepareAddCard(int x)
// autoclose check is done both here and in removeCard
if (cards.isEmpty() && !doInsert && SettingsCache::instance().userInterface().getCloseEmptyCardView()) {
if (cards.isEmpty() && !doInsert && getCloseEmptyCardView()) {
emit closeView();
}
@ -151,7 +157,7 @@ void ZoneViewZoneLogic::removeCard(int position, bool toNewZone)
// card gets dragged within the view.
// Another autoclose check is done in prepareAddCard so that the view autocloses if the last card was moved to an
// unrevealed portion of the same zone.
if (cards.isEmpty() && SettingsCache::instance().userInterface().getCloseEmptyCardView() && toNewZone) {
if (cards.isEmpty() && getCloseEmptyCardView() && toNewZone) {
emit closeView();
return;
}

View file

@ -13,6 +13,7 @@
class PlayerLogic;
class QObject;
class PendingCommand;
class IInterfaceSettingsProvider;
class ZoneViewZoneLogic : public CardZoneLogic
{
@ -27,6 +28,8 @@ private:
int numberCards;
bool revealZone, writeableRevealZone;
bool isReversed;
// Borrowed settings provider (owned by the application). Null outside the client, in which case views stay open.
IInterfaceSettingsProvider *interfaceSettings;
public:
enum CardAction
@ -42,6 +45,7 @@ public:
bool _revealZone,
bool _writeableRevealZone,
bool _isReversed,
IInterfaceSettingsProvider *interfaceSettings = nullptr,
QObject *parent = nullptr);
bool prepareAddCard(int x);
@ -58,6 +62,8 @@ public:
/** @brief Removes all cards from the view, without touching anything else. Used in replay rewind */
void clearCards();
[[nodiscard]] bool getCloseEmptyCardView() const;
int getNumberCards() const
{
return numberCards;