[Game] Playmats (#7101)

* [Game] Playmats

Took 19 seconds

Took 1 minute

* [Playmats] Add fixed override and configurable fallbacks to settings.

Took 29 minutes

Took 43 seconds

* Add main to test.

Took 1 minute

Took 29 seconds

* Move settings to own group

Took 11 minutes

* Some attempts to refresh macOS compositor

Took 2 minutes

* Try something else

Took 17 minutes

* Don't manipulate live list

Took 11 minutes

* Change things about resolution, address comments.

Took 45 minutes

Took 12 minutes

* Comments.

Took 14 minutes

Took 8 seconds

* Re-order settings menu location

Took 2 minutes

* Rename PlaymatResolution to Info and add enums

Took 8 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-08-21 10:40:49 +02:00 committed by GitHub
parent 74a454552a
commit 9eafd90a91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 1931 additions and 28 deletions

View file

@ -14,12 +14,15 @@
#include <QMessageBox>
#include <libcockatrice/card/database/card_database.h>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/deck_list/playmat_resolver.h>
#include <libcockatrice/protocol/pb/command_deck_select.pb.h>
#include <libcockatrice/protocol/pb/command_ready_start.pb.h>
#include <libcockatrice/protocol/pb/command_set_playmat.pb.h>
#include <libcockatrice/protocol/pb/command_set_sideboard_lock.pb.h>
#include <libcockatrice/protocol/pb/command_set_sideboard_plan.pb.h>
#include <libcockatrice/protocol/pb/response_deck_download.pb.h>
#include <libcockatrice/protocol/pending_command.h>
#include <libcockatrice/settings/interface_settings.h>
#include <libcockatrice/settings/visual_deck_storage_settings.h>
#include <libcockatrice/utility/string_limits.h>
@ -100,6 +103,9 @@ DeckViewContainer::DeckViewContainer(int _playerId, TabGame *parent)
connect(&SettingsCache::instance().visualDeckStorage(), &VisualDeckStorageSettings::visualDeckStorageInGameChanged,
this, &DeckViewContainer::setVisualDeckStorageExists);
connect(&SettingsCache::instance().userInterface(), &InterfaceSettings::playmatSettingsChanged, this,
&DeckViewContainer::onPlaymatSettingsChanged);
switchToDeckSelectView();
}
@ -277,6 +283,8 @@ void DeckViewContainer::loadDeckFromFile(const QString &filePath)
void DeckViewContainer::loadDeckFromDeckList(const DeckList &deck)
{
currentDeck = deck;
QString deckString = deck.writeToString_Native();
if (deckString.length() > MAX_FILE_LENGTH) {
@ -289,6 +297,52 @@ void DeckViewContainer::loadDeckFromDeckList(const DeckList &deck)
PendingCommand *pend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(cmd);
connect(pend, &PendingCommand::finished, this, &DeckViewContainer::deckSelectFinished);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(pend, playerId);
resolveAndSendPlaymat();
}
void DeckViewContainer::resolveAndSendPlaymat()
{
if (currentDeck.getCardRefList().isEmpty() && currentDeck.getPlaymat().card.isEmpty()) {
return;
}
const auto &settings = SettingsCache::instance().userInterface();
const auto fallbackBehavior = static_cast<PlaymatFallbackMode>(settings.getPlaymatFallbackBehavior());
QList<PlaymatInfo> fallbackList = settings.getPlaymatFallbackList();
// In random mode with 2+ entries, remove the last-resolved mat to avoid repeats.
if (fallbackBehavior == PlaymatFallbackModeRandom && fallbackList.size() > 1) {
fallbackList.removeAll(lastResolvedPlaymat);
}
const PlaymatInfo resolved =
resolvePlaymatForDeck(currentDeck, fallbackList, static_cast<PlaymatMode>(settings.getPlaymatMode()),
fallbackBehavior, playmatRotationIndex);
lastResolvedPlaymat = resolved;
Command_SetPlaymat playmatCmd;
auto *pp = playmatCmd.mutable_playmat_params();
pp->set_card_name(resolved.card.name.toStdString());
pp->set_card_provider_id(resolved.card.providerId.toStdString());
pp->set_margin_pct_l(resolved.params.marginPctL);
pp->set_margin_pct_r(resolved.params.marginPctR);
pp->set_vertical_offset(resolved.params.verticalOffset);
pp->set_zoom(resolved.params.zoom);
PendingCommand *playmatPend = parentGame->getGame()->getGameEventHandler()->prepareGameCommand(playmatCmd);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(playmatPend, playerId);
}
void DeckViewContainer::onPlaymatSettingsChanged()
{
resolveAndSendPlaymat();
}
void DeckViewContainer::advancePlaymatRotation()
{
playmatRotationIndex++;
}
void DeckViewContainer::loadRemoteDeck()
@ -379,6 +433,10 @@ void DeckViewContainer::sideboardPlanChanged()
*/
void DeckViewContainer::sendReadyStartCommand(bool ready)
{
if (ready) {
resolveAndSendPlaymat();
}
Command_ReadyStart cmd;
cmd.set_ready(ready);
parentGame->getGame()->getGameEventHandler()->sendGameCommand(cmd, playerId);
@ -416,6 +474,7 @@ void DeckViewContainer::setSideboardLocked(bool locked)
void DeckViewContainer::setDeck(const DeckList &deck)
{
currentDeck = deck;
deckView->setDeck(deck);
switchToDeckLoadedView();
}