mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-12 09:04:53 -07:00
Support starting games with fewer than max players (#5338)
This commit is contained in:
parent
956c12eb32
commit
6dfd354973
6 changed files with 50 additions and 16 deletions
|
|
@ -106,11 +106,14 @@ DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
|
||||||
loadRemoteButton = new QPushButton;
|
loadRemoteButton = new QPushButton;
|
||||||
readyStartButton = new ToggleButton;
|
readyStartButton = new ToggleButton;
|
||||||
readyStartButton->setEnabled(false);
|
readyStartButton->setEnabled(false);
|
||||||
|
forceStartGameButton = new QPushButton;
|
||||||
|
forceStartGameButton->setEnabled(parent->isHost());
|
||||||
sideboardLockButton = new ToggleButton;
|
sideboardLockButton = new ToggleButton;
|
||||||
sideboardLockButton->setEnabled(false);
|
sideboardLockButton->setEnabled(false);
|
||||||
|
|
||||||
connect(loadLocalButton, SIGNAL(clicked()), this, SLOT(loadLocalDeck()));
|
connect(loadLocalButton, SIGNAL(clicked()), this, SLOT(loadLocalDeck()));
|
||||||
connect(readyStartButton, SIGNAL(clicked()), this, SLOT(readyStart()));
|
connect(readyStartButton, SIGNAL(clicked()), this, SLOT(readyStart()));
|
||||||
|
connect(forceStartGameButton, &QPushButton::clicked, this, &DeckViewContainer::forceStart);
|
||||||
connect(sideboardLockButton, SIGNAL(clicked()), this, SLOT(sideboardLockButtonClicked()));
|
connect(sideboardLockButton, SIGNAL(clicked()), this, SLOT(sideboardLockButtonClicked()));
|
||||||
connect(sideboardLockButton, SIGNAL(stateChanged()), this, SLOT(updateSideboardLockButtonText()));
|
connect(sideboardLockButton, SIGNAL(stateChanged()), this, SLOT(updateSideboardLockButtonText()));
|
||||||
|
|
||||||
|
|
@ -125,6 +128,9 @@ DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
|
||||||
buttonHBox->addWidget(loadRemoteButton);
|
buttonHBox->addWidget(loadRemoteButton);
|
||||||
buttonHBox->addWidget(readyStartButton);
|
buttonHBox->addWidget(readyStartButton);
|
||||||
buttonHBox->addWidget(sideboardLockButton);
|
buttonHBox->addWidget(sideboardLockButton);
|
||||||
|
if (forceStartGameButton->isEnabled()) {
|
||||||
|
buttonHBox->addWidget(forceStartGameButton);
|
||||||
|
}
|
||||||
buttonHBox->setContentsMargins(0, 0, 0, 0);
|
buttonHBox->setContentsMargins(0, 0, 0, 0);
|
||||||
buttonHBox->addStretch();
|
buttonHBox->addStretch();
|
||||||
deckView = new DeckView;
|
deckView = new DeckView;
|
||||||
|
|
@ -147,6 +153,7 @@ void DeckViewContainer::retranslateUi()
|
||||||
loadLocalButton->setText(tr("Load deck..."));
|
loadLocalButton->setText(tr("Load deck..."));
|
||||||
loadRemoteButton->setText(tr("Load remote deck..."));
|
loadRemoteButton->setText(tr("Load remote deck..."));
|
||||||
readyStartButton->setText(tr("Ready to start"));
|
readyStartButton->setText(tr("Ready to start"));
|
||||||
|
forceStartGameButton->setText(tr("Force start"));
|
||||||
updateSideboardLockButtonText();
|
updateSideboardLockButtonText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,6 +162,7 @@ void DeckViewContainer::setButtonsVisible(bool _visible)
|
||||||
loadLocalButton->setVisible(_visible);
|
loadLocalButton->setVisible(_visible);
|
||||||
loadRemoteButton->setVisible(_visible);
|
loadRemoteButton->setVisible(_visible);
|
||||||
readyStartButton->setVisible(_visible);
|
readyStartButton->setVisible(_visible);
|
||||||
|
forceStartGameButton->setVisible(_visible);
|
||||||
sideboardLockButton->setVisible(_visible);
|
sideboardLockButton->setVisible(_visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,6 +346,14 @@ void DeckViewContainer::readyStart()
|
||||||
parentGame->sendGameCommand(cmd, playerId);
|
parentGame->sendGameCommand(cmd, playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeckViewContainer::forceStart()
|
||||||
|
{
|
||||||
|
Command_ReadyStart cmd;
|
||||||
|
cmd.set_force_start(true);
|
||||||
|
cmd.set_ready(true);
|
||||||
|
parentGame->sendGameCommand(cmd, playerId);
|
||||||
|
}
|
||||||
|
|
||||||
void DeckViewContainer::sideboardLockButtonClicked()
|
void DeckViewContainer::sideboardLockButtonClicked()
|
||||||
{
|
{
|
||||||
Command_SetSideboardLock cmd;
|
Command_SetSideboardLock cmd;
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class DeckViewContainer : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
QPushButton *loadLocalButton, *loadRemoteButton;
|
QPushButton *loadLocalButton, *loadRemoteButton, *forceStartGameButton;
|
||||||
ToggleButton *readyStartButton, *sideboardLockButton;
|
ToggleButton *readyStartButton, *sideboardLockButton;
|
||||||
DeckView *deckView;
|
DeckView *deckView;
|
||||||
TabGame *parentGame;
|
TabGame *parentGame;
|
||||||
|
|
@ -95,6 +95,7 @@ private slots:
|
||||||
void loadLocalDeck();
|
void loadLocalDeck();
|
||||||
void loadRemoteDeck();
|
void loadRemoteDeck();
|
||||||
void readyStart();
|
void readyStart();
|
||||||
|
void forceStart();
|
||||||
void deckSelectFinished(const Response &r);
|
void deckSelectFinished(const Response &r);
|
||||||
void sideboardPlanChanged();
|
void sideboardPlanChanged();
|
||||||
void sideboardLockButtonClicked();
|
void sideboardLockButtonClicked();
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ message Command_ReadyStart {
|
||||||
optional Command_ReadyStart ext = 1016;
|
optional Command_ReadyStart ext = 1016;
|
||||||
}
|
}
|
||||||
optional bool ready = 1;
|
optional bool ready = 1;
|
||||||
|
optional bool force_start = 2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ Server_Game::Server_Game(const ServerInfo_User &_creatorInfo,
|
||||||
currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId());
|
currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId());
|
||||||
description = _description.simplified();
|
description = _description.simplified();
|
||||||
|
|
||||||
connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection);
|
connect(this, &Server_Game::sigStartGameIfReady, this, &Server_Game::doStartGameIfReady, Qt::QueuedConnection);
|
||||||
|
|
||||||
getInfo(*currentReplay->mutable_game_info());
|
getInfo(*currentReplay->mutable_game_info());
|
||||||
|
|
||||||
|
|
@ -311,20 +311,31 @@ void Server_Game::sendGameStateToPlayers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Game::doStartGameIfReady()
|
void Server_Game::doStartGameIfReady(bool forceStartGame)
|
||||||
{
|
{
|
||||||
Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface();
|
Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface();
|
||||||
QMutexLocker locker(&gameMutex);
|
QMutexLocker locker(&gameMutex);
|
||||||
|
|
||||||
if (getPlayerCount() < maxPlayers)
|
if (getPlayerCount() < maxPlayers && !forceStartGame) {
|
||||||
return;
|
return;
|
||||||
for (Server_Player *player : players.values()) {
|
|
||||||
if (!player->getReadyStart() && !player->getSpectator())
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Server_Player *player : players.values()) {
|
for (Server_Player *player : players.values()) {
|
||||||
if (!player->getSpectator())
|
if (!player->getReadyStart() && !player->getSpectator()) {
|
||||||
|
if (forceStartGame) {
|
||||||
|
// Player is not ready to start, so kick them
|
||||||
|
// TODO: Move them to Spectators instead
|
||||||
|
kickPlayer(player->getPlayerId());
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Server_Player *player : players.values()) {
|
||||||
|
if (!player->getSpectator()) {
|
||||||
player->setupZones();
|
player->setupZones();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStarted = true;
|
gameStarted = true;
|
||||||
|
|
@ -369,9 +380,9 @@ void Server_Game::doStartGameIfReady()
|
||||||
emit gameInfoChanged(gameInfo);
|
emit gameInfoChanged(gameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Game::startGameIfReady()
|
void Server_Game::startGameIfReady(bool forceStartGame)
|
||||||
{
|
{
|
||||||
emit sigStartGameIfReady();
|
emit sigStartGameIfReady(forceStartGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server_Game::stopGameIfFinished()
|
void Server_Game::stopGameIfFinished()
|
||||||
|
|
|
||||||
|
|
@ -82,11 +82,11 @@ private:
|
||||||
bool withUserInfo);
|
bool withUserInfo);
|
||||||
void storeGameInformation();
|
void storeGameInformation();
|
||||||
signals:
|
signals:
|
||||||
void sigStartGameIfReady();
|
void sigStartGameIfReady(bool override);
|
||||||
void gameInfoChanged(ServerInfo_Game gameInfo);
|
void gameInfoChanged(ServerInfo_Game gameInfo);
|
||||||
private slots:
|
private slots:
|
||||||
void pingClockTimeout();
|
void pingClockTimeout();
|
||||||
void doStartGameIfReady();
|
void doStartGameIfReady(bool forceStartGame = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
|
|
@ -180,7 +180,7 @@ public:
|
||||||
void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player);
|
void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player);
|
||||||
void unattachCards(GameEventStorage &ges, Server_Player *player);
|
void unattachCards(GameEventStorage &ges, Server_Player *player);
|
||||||
bool kickPlayer(int playerId);
|
bool kickPlayer(int playerId);
|
||||||
void startGameIfReady();
|
void startGameIfReady(bool forceStartGame);
|
||||||
void stopGameIfFinished();
|
void stopGameIfFinished();
|
||||||
int getActivePlayer() const
|
int getActivePlayer() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -944,7 +944,7 @@ Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readyStart == cmd.ready()) {
|
if (readyStart == cmd.ready() && !cmd.force_start()) {
|
||||||
return Response::RespContextError;
|
return Response::RespContextError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -955,8 +955,13 @@ Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &
|
||||||
ges.enqueueGameEvent(event, playerId);
|
ges.enqueueGameEvent(event, playerId);
|
||||||
ges.setGameEventContext(Context_ReadyStart());
|
ges.setGameEventContext(Context_ReadyStart());
|
||||||
|
|
||||||
if (cmd.ready()) {
|
if (cmd.force_start()) {
|
||||||
game->startGameIfReady();
|
if (game->getHostId() != playerId) {
|
||||||
|
return Response::RespFunctionNotAllowed;
|
||||||
|
}
|
||||||
|
game->startGameIfReady(true);
|
||||||
|
} else if (cmd.ready()) {
|
||||||
|
game->startGameIfReady(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue