Rename PlaymatResolution to Info and add enums

Took 8 minutes
This commit is contained in:
Lukas Brübach 2026-08-21 10:02:47 +02:00
parent c4a6c2ed81
commit a62c5b74f4
20 changed files with 181 additions and 153 deletions

View file

@ -310,29 +310,16 @@ void DeckViewContainer::resolveAndSendPlaymat()
const auto &settings = SettingsCache::instance().userInterface();
const auto fallbackBehavior = static_cast<PlaymatFallbackMode>(settings.getPlaymatFallbackBehavior());
PlaymatResolution resolved;
QList<PlaymatResolution> fallbackList = settings.getPlaymatFallbackList();
QList<PlaymatInfo> fallbackList = settings.getPlaymatFallbackList();
// In random mode with 2+ entries, remove the last-resolved mat to avoid repeats.
if (fallbackBehavior == PlaymatFallbackMode::Random && fallbackList.size() > 1) {
if (fallbackBehavior == PlaymatFallbackModeRandom && fallbackList.size() > 1) {
fallbackList.removeAll(lastResolvedPlaymat);
}
switch (settings.getPlaymatMode()) {
case 0: { // Override deck playmat — always use collection
DeckList emptyDeck;
resolved = resolveEffectivePlaymat(emptyDeck, {}, fallbackList, fallbackBehavior, playmatRotationIndex);
break;
}
case 1: // Fallback if deck has none — deck > collection > none
resolved = resolveEffectivePlaymat(currentDeck, {}, fallbackList, fallbackBehavior, playmatRotationIndex);
break;
case 2: // Deck only, ignore collection
resolved = currentDeck.getPlaymat();
break;
default:
break;
}
const PlaymatInfo resolved =
resolvePlaymatForDeck(currentDeck, fallbackList, static_cast<PlaymatMode>(settings.getPlaymatMode()),
fallbackBehavior, playmatRotationIndex);
lastResolvedPlaymat = resolved;

View file

@ -57,9 +57,9 @@ private:
VisualDeckStorageWidget *visualDeckStorageWidget;
TabGame *parentGame;
int playerId;
int playmatRotationIndex = 0; ///< Per-match cursor for round-robin playmat mode.
DeckList currentDeck; ///< Cached deck for live settings re-resolution.
PlaymatResolution lastResolvedPlaymat; ///< Tracks last sent playmat to avoid repeats in random mode.
int playmatRotationIndex = 0; ///< Per-match cursor for round-robin playmat mode.
DeckList currentDeck; ///< Cached deck for live settings re-resolution.
PlaymatInfo lastResolvedPlaymat; ///< Tracks last sent playmat to avoid repeats in random mode.
void tryCreateVisualDeckStorageWidget();
void sendReadyStartCommand(bool ready);

View file

@ -372,13 +372,13 @@ void PlayerGraphicsItem::updatePlaymat()
int visibility = SettingsCache::instance().userInterface().getPlaymatVisibility();
// "Don't use playmats" — never show
if (visibility == 0) {
if (visibility == PlaymatVisibilityNone) {
clearPlaymat();
return;
}
// "Show own playmat only" — hide playmats for remote players
if (visibility == 1 && !player->getPlayerInfo()->getLocal()) {
if (visibility == PlaymatVisibilityOwnOnly && !player->getPlayerInfo()->getLocal()) {
clearPlaymat();
return;
}
@ -394,38 +394,15 @@ void PlayerGraphicsItem::updatePlaymat()
// Local player without a server broadcast yet: apply the full
// settings-based resolution chain (mode, fallback list, behavior).
const auto &settings = SettingsCache::instance().userInterface();
const DeckList &deck = player->getDeck();
const auto fallbackBehavior = static_cast<PlaymatFallbackMode>(settings.getPlaymatFallbackBehavior());
switch (settings.getPlaymatMode()) {
case 0: { // Override deck playmat — always use collection
DeckList emptyDeck;
const PlaymatResolution resolved =
resolveEffectivePlaymat(emptyDeck, {}, settings.getPlaymatFallbackList(), fallbackBehavior, 0);
playmatCard = resolved.card;
params = resolved.params;
break;
}
case 1: { // Fallback if deck has none — deck > collection > none
const PlaymatResolution resolved =
resolveEffectivePlaymat(deck, {}, settings.getPlaymatFallbackList(), fallbackBehavior, 0);
playmatCard = resolved.card;
params = resolved.params;
break;
}
case 2: { // Deck only, ignore collection
const PlaymatResolution &deckPlaymat = deck.getPlaymat();
if (!deckPlaymat.card.isEmpty()) {
playmatCard = deckPlaymat.card;
params = deckPlaymat.params;
}
break;
}
}
const PlaymatInfo resolved = resolvePlaymatForDeck(
player->getDeck(), settings.getPlaymatFallbackList(), static_cast<PlaymatMode>(settings.getPlaymatMode()),
static_cast<PlaymatFallbackMode>(settings.getPlaymatFallbackBehavior()), 0);
playmatCard = resolved.card;
params = resolved.params;
} else {
// Opponent without a server broadcast: use the deck-embedded playmat.
const DeckList &deck = player->getDeck();
const PlaymatResolution &deckPlaymat = deck.getPlaymat();
const PlaymatInfo &deckPlaymat = deck.getPlaymat();
if (!deckPlaymat.card.isEmpty()) {
playmatCard = deckPlaymat.card;
params = deckPlaymat.params;

View file

@ -453,7 +453,7 @@ void DeckEditorDeckDockWidget::writeBannerCard(int index)
void DeckEditorDeckDockWidget::openPlaymatSettings()
{
PlaymatResolution current = deckStateManager->getMetadata().playmat;
PlaymatInfo current = deckStateManager->getMetadata().playmat;
PlaymatSettingsDialog dialog(current.card, current.params, this);
if (dialog.exec() == QDialog::Accepted) {
@ -461,7 +461,7 @@ void DeckEditorDeckDockWidget::openPlaymatSettings()
PlaymatParams newParams = dialog.params();
if (newCard.isEmpty()) {
deckStateManager->setPlaymat(PlaymatResolution{});
deckStateManager->setPlaymat(PlaymatInfo{});
} else {
deckStateManager->setPlaymat({newCard, newParams});
}

View file

@ -142,9 +142,9 @@ void DeckStateManager::setBannerCard(const CardRef &bannerCard)
doMetadataModified();
}
void DeckStateManager::setPlaymat(const PlaymatResolution &playmat)
void DeckStateManager::setPlaymat(const PlaymatInfo &playmat)
{
PlaymatResolution previous = deckList->getPlaymat();
PlaymatInfo previous = deckList->getPlaymat();
if (previous == playmat) {
return;
}

View file

@ -171,7 +171,7 @@ public:
void setName(const QString &name);
void setComments(const QString &comments);
void setBannerCard(const CardRef &bannerCard);
void setPlaymat(const PlaymatResolution &playmat);
void setPlaymat(const PlaymatInfo &playmat);
void setTags(const QStringList &tags);
void setFormat(const QString &format);
///@}

View file

@ -38,7 +38,7 @@ void PlaymatCollectionDialog::setupUi()
playmats = interfaceSettings.getPlaymatFallbackList();
playmatList = new QListWidget;
for (const PlaymatResolution &entry : playmats) {
for (const PlaymatInfo &entry : playmats) {
playmatList->addItem(entry.card.name);
}
connect(playmatList, &QListWidget::itemSelectionChanged, this, &PlaymatCollectionDialog::selectionChanged);
@ -69,9 +69,9 @@ void PlaymatCollectionDialog::setupUi()
listRow->addLayout(listButtons);
modeCombo = new QComboBox;
modeCombo->addItem(QString(), 0);
modeCombo->addItem(QString(), 1);
modeCombo->addItem(QString(), 2);
modeCombo->addItem(QString(), PlaymatFallbackModeFixed);
modeCombo->addItem(QString(), PlaymatFallbackModeRoundRobin);
modeCombo->addItem(QString(), PlaymatFallbackModeRandom);
const int modeIndex = modeCombo->findData(interfaceSettings.getPlaymatFallbackBehavior());
if (modeIndex >= 0) {
modeCombo->setCurrentIndex(modeIndex);
@ -111,7 +111,7 @@ void PlaymatCollectionDialog::addPlaymat()
if (dialog.exec() == QDialog::Accepted) {
const CardRef card = dialog.card();
if (!card.isEmpty()) {
PlaymatResolution res = {card, dialog.params()};
PlaymatInfo res = {card, dialog.params()};
playmats.append(res);
playmatList->addItem(res.card.name);
playmatList->setCurrentRow(playmatList->count() - 1);
@ -126,7 +126,7 @@ void PlaymatCollectionDialog::editPlaymat()
return;
}
const PlaymatResolution &current = playmats.at(row);
const PlaymatInfo &current = playmats.at(row);
PlaymatSettingsDialog dialog(current.card, current.params, this);
if (dialog.exec() == QDialog::Accepted) {
const CardRef card = dialog.card();

View file

@ -40,7 +40,7 @@ private:
void retranslateUi();
int currentRow() const;
QList<PlaymatResolution> playmats; ///< Working copy edited by the dialog.
QList<PlaymatInfo> playmats; ///< Working copy edited by the dialog.
QListWidget *playmatList;
QComboBox *modeCombo;
QLabel *modeLabel;

View file

@ -329,9 +329,9 @@ AppearanceSettingsPage::AppearanceSettingsPage()
tableGroupBox->setLayout(tableGrid);
// Playmat settings
playmatVisibilityCombo.addItem(tr("Show all playmats"), 2);
playmatVisibilityCombo.addItem(tr("Show own playmat only"), 1);
playmatVisibilityCombo.addItem(tr("Don't use playmats"), 0);
playmatVisibilityCombo.addItem(tr("Show all playmats"), PlaymatVisibilityAll);
playmatVisibilityCombo.addItem(tr("Show own playmat only"), PlaymatVisibilityOwnOnly);
playmatVisibilityCombo.addItem(tr("Don't use playmats"), PlaymatVisibilityNone);
int visIdx = playmatVisibilityCombo.findData(settings.userInterface().getPlaymatVisibility());
if (visIdx >= 0) {
playmatVisibilityCombo.setCurrentIndex(visIdx);
@ -342,9 +342,9 @@ AppearanceSettingsPage::AppearanceSettingsPage()
playmatVisibilityLabel.setBuddy(&playmatVisibilityCombo);
// Playmat mode: Override / Fallback / Deck-only
playmatModeCombo.addItem(tr("Override deck playmat"), 0);
playmatModeCombo.addItem(tr("Fallback if deck has none"), 1);
playmatModeCombo.addItem(tr("Deck only, ignore collection"), 2);
playmatModeCombo.addItem(tr("Override deck playmat"), PlaymatModeOverrideDeck);
playmatModeCombo.addItem(tr("Fallback if deck has none"), PlaymatModeFallback);
playmatModeCombo.addItem(tr("Deck only, ignore collection"), PlaymatModeDeckOnly);
int modeIdx = playmatModeCombo.findData(settings.userInterface().getPlaymatMode());
if (modeIdx >= 0) {
playmatModeCombo.setCurrentIndex(modeIdx);

View file

@ -35,4 +35,7 @@ add_dependencies(libcockatrice_deck_list libcockatrice_protocol)
target_include_directories(libcockatrice_deck_list PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(libcockatrice_deck_list PUBLIC libcockatrice_protocol libcockatrice_utility ${QT_CORE_MODULE})
target_link_libraries(
libcockatrice_deck_list PUBLIC libcockatrice_interfaces libcockatrice_protocol libcockatrice_utility
${QT_CORE_MODULE}
)

View file

@ -82,7 +82,7 @@ bool DeckList::readElement(QXmlStreamReader *xml)
QString vOffStr = xml->attributes().value("verticalOffset").toString();
QString zoomStr = xml->attributes().value("zoom").toString();
QString cardName = xml->readElementText();
PlaymatResolution playmat;
PlaymatInfo playmat;
playmat.card = {cardName, providerId};
// Clamp to the same ranges as the settings dialog and the remote
// player-properties path so malformed deck files cannot produce

View file

@ -70,7 +70,7 @@ public:
CardRef bannerCard; ///< Optional representative card for the deck.
QStringList tags; ///< User-defined tags for deck classification.
QString lastLoadedTimestamp; ///< Timestamp string of last load.
PlaymatResolution playmat; ///< Optional playmat background for table+stack zones.
PlaymatInfo playmat; ///< Optional playmat background for table+stack zones.
/**
* @brief Checks if all values (except for lastLoadedTimestamp) in the metadata is empty.
@ -116,7 +116,7 @@ public:
{
metadata.bannerCard = _bannerCard;
}
void setPlaymat(const PlaymatResolution &_playmat = {})
void setPlaymat(const PlaymatInfo &_playmat = {})
{
metadata.playmat = _playmat;
}
@ -175,7 +175,7 @@ public:
{
return metadata.bannerCard;
}
PlaymatResolution getPlaymat() const
PlaymatInfo getPlaymat() const
{
return metadata.playmat;
}

View file

@ -2,17 +2,17 @@
#include <QRandomGenerator>
PlaymatResolution resolveEffectivePlaymat(const DeckList &deck,
const PlaymatResolution &force,
const QList<PlaymatResolution> &fallbackList,
PlaymatFallbackMode fallbackMode,
int rotationIndex)
PlaymatInfo resolveEffectivePlaymat(const DeckList &deck,
const PlaymatInfo &force,
const QList<PlaymatInfo> &fallbackList,
PlaymatFallbackMode fallbackMode,
int rotationIndex)
{
if (!force.card.isEmpty()) {
return force;
}
const PlaymatResolution &deckPlaymat = deck.getPlaymat();
const PlaymatInfo &deckPlaymat = deck.getPlaymat();
if (!deckPlaymat.card.isEmpty()) {
return deckPlaymat;
}
@ -22,13 +22,33 @@ PlaymatResolution resolveEffectivePlaymat(const DeckList &deck,
}
switch (fallbackMode) {
case PlaymatFallbackMode::Fixed:
case PlaymatFallbackModeFixed:
return fallbackList.first();
case PlaymatFallbackMode::RoundRobin:
case PlaymatFallbackModeRoundRobin:
return fallbackList.at(rotationIndex % fallbackList.size());
case PlaymatFallbackMode::Random:
case PlaymatFallbackModeRandom:
return fallbackList.at(QRandomGenerator::global()->bounded(fallbackList.size()));
}
return {};
}
PlaymatInfo resolvePlaymatForDeck(const DeckList &deck,
const QList<PlaymatInfo> &fallbackList,
PlaymatMode mode,
PlaymatFallbackMode fallbackBehavior,
int rotationIndex)
{
switch (mode) {
case PlaymatModeOverrideDeck: {
const DeckList emptyDeck;
return resolveEffectivePlaymat(emptyDeck, {}, fallbackList, fallbackBehavior, rotationIndex);
}
case PlaymatModeFallback:
return resolveEffectivePlaymat(deck, {}, fallbackList, fallbackBehavior, rotationIndex);
case PlaymatModeDeckOnly:
return deck.getPlaymat();
}
return {};
}

View file

@ -3,16 +3,7 @@
#include "deck_list.h"
/**
* @brief How the user-level fallback playmat list is consulted when a deck has
* no playmat configured.
*/
enum class PlaymatFallbackMode
{
Fixed = 0, ///< Always use the first entry of the fallback list.
RoundRobin = 1, ///< Cycle through the list, advancing one entry per resolution.
Random = 2 ///< Pick a random entry per resolution.
};
#include <libcockatrice/interfaces/interface_interface_settings_provider.h>
/**
* @brief Resolves the effective playmat for a deck per the resolution chain:
@ -20,19 +11,37 @@ enum class PlaymatFallbackMode
*
* @param deck The deck to resolve a playmat for.
* @param force An optional user-level override; wins over everything. Pass an
* empty @ref PlaymatResolution::card to skip it.
* empty @ref PlaymatInfo::card to skip it.
* @param fallbackList User-level fallback playmats, consulted only when the
* deck has no configured playmat.
* @param fallbackMode How @p fallbackList is consulted (ignored when empty).
* @param rotationIndex In/out cursor for @c PlaymatFallbackMode::RoundRobin;
* @param rotationIndex In/out cursor for @c PlaymatFallbackModeRoundRobin;
* advanced once per call. Unused for the other modes.
* @return The effective playmat; an empty @ref PlaymatResolution::card when
* @return The effective playmat; an empty @ref PlaymatInfo::card when
* nothing in the chain resolves.
*/
PlaymatResolution resolveEffectivePlaymat(const DeckList &deck,
const PlaymatResolution &force,
const QList<PlaymatResolution> &fallbackList,
PlaymatFallbackMode fallbackMode,
int rotationIndex);
PlaymatInfo resolveEffectivePlaymat(const DeckList &deck,
const PlaymatInfo &force,
const QList<PlaymatInfo> &fallbackList,
PlaymatFallbackMode fallbackMode,
int rotationIndex);
/**
* @brief Resolves the playmat to display for a deck according to the user's
* collection mode (@ref PlaymatMode), combining the deck with the
* given fallback list.
*
* @param deck The deck to resolve a playmat for.
* @param fallbackList User-level fallback playmats.
* @param mode How the collection interacts with the deck-configured playmat.
* @param fallbackBehavior How @p fallbackList is picked from.
* @param rotationIndex Cursor for @c PlaymatFallbackModeRoundRobin.
* @return The effective playmat; an empty @ref PlaymatInfo::card when nothing resolves.
*/
PlaymatInfo resolvePlaymatForDeck(const DeckList &deck,
const QList<PlaymatInfo> &fallbackList,
PlaymatMode mode,
PlaymatFallbackMode fallbackBehavior,
int rotationIndex);
#endif // COCKATRICE_PLAYMAT_RESOLVER_H

View file

@ -6,6 +6,36 @@
#include <QStringList>
#include <libcockatrice/utility/playmat_params.h>
/**
* @brief Whether playmats are rendered in-game, and for whom.
*/
enum PlaymatVisibility
{
PlaymatVisibilityNone = 0, ///< Don't use playmats.
PlaymatVisibilityOwnOnly = 1, ///< Show the local player's playmat only.
PlaymatVisibilityAll = 2 ///< Show playmats for all players.
};
/**
* @brief How the user-level playmat collection interacts with the deck-configured playmat.
*/
enum PlaymatMode
{
PlaymatModeOverrideDeck = 0, ///< Always use the collection, ignoring any deck-configured playmat.
PlaymatModeFallback = 1, ///< Prefer the deck-configured playmat; fall back to the collection when absent.
PlaymatModeDeckOnly = 2 ///< Use only the deck-configured playmat, ignoring the collection.
};
/**
* @brief How the user-level fallback playmat list is consulted when a deck has no playmat configured.
*/
enum PlaymatFallbackMode
{
PlaymatFallbackModeFixed = 0, ///< Always use the first entry of the fallback list.
PlaymatFallbackModeRoundRobin = 1, ///< Cycle through the list, advancing one entry per resolution.
PlaymatFallbackModeRandom = 2 ///< Pick a random entry per resolution.
};
class IInterfaceSettingsProvider
{
public:
@ -45,17 +75,20 @@ public:
[[nodiscard]] virtual bool getLifeCounterAnimationsEnabled() const = 0;
[[nodiscard]] virtual bool getBattlefieldFlashEnabled() const = 0;
[[nodiscard]] virtual QStringList getUserListExpandedSections() const = 0;
/** @brief Who gets playmats rendered: @ref PlaymatVisibility. */
[[nodiscard]] virtual int getPlaymatVisibility() const = 0;
/** @brief User-level playmat collection. Used either as a forced playmat
* (mode == Always) or as a fallback when a deck has none (mode == Fallback). */
[[nodiscard]] virtual QList<PlaymatResolution> getPlaymatFallbackList() const = 0;
* (mode == @ref PlaymatModeOverrideDeck) or as a fallback when a deck has none
* (mode == @ref PlaymatModeFallback). */
[[nodiscard]] virtual QList<PlaymatInfo> getPlaymatFallbackList() const = 0;
/** @brief How the fallback list is applied: Always (0), Fallback (1), Never (2). */
/** @brief How the fallback list is applied: @ref PlaymatMode. */
[[nodiscard]] virtual int getPlaymatMode() const = 0;
/** @brief How the fallback list is picked from when mode is Fallback
* (0 Fixed, 1 Round-robin, 2 Random). */
/** @brief How the fallback list is picked from when mode is @ref PlaymatModeFallback:
* @ref PlaymatFallbackMode. */
[[nodiscard]] virtual int getPlaymatFallbackBehavior() const = 0;
};

View file

@ -618,7 +618,7 @@ Server_Player::cmdSetPlaymat(const Command_SetPlaymat &cmd, ResponseContainer &r
if (rawName.length() > MAX_NAME_LENGTH || rawProviderId.length() > MAX_NAME_LENGTH) {
return Response::RespInvalidData;
}
PlaymatResolution playmat;
PlaymatInfo playmat;
playmat.card.name = rawName;
playmat.card.providerId = rawProviderId;
playmat.params.marginPctL = qBound(0.0, pp.margin_pct_l(), 0.95);

View file

@ -2,9 +2,9 @@
namespace
{
const QChar PLAYMAT_FIELD_SEP = QChar(0x1F); ///< Separator between PlaymatResolution fields.
const QChar PLAYMAT_FIELD_SEP = QChar(0x1F); ///< Separator between PlaymatInfo fields.
QString encodePlaymatResolution(const PlaymatResolution &res)
QString encodePlaymatInfo(const PlaymatInfo &res)
{
return res.card.name + PLAYMAT_FIELD_SEP + res.card.providerId + PLAYMAT_FIELD_SEP +
QString::number(res.params.marginPctL, 'f', 4) + PLAYMAT_FIELD_SEP +
@ -13,13 +13,13 @@ QString encodePlaymatResolution(const PlaymatResolution &res)
QString::number(res.params.zoom, 'f', 4);
}
PlaymatResolution decodePlaymatResolution(const QString &encoded)
PlaymatInfo decodePlaymatInfo(const QString &encoded)
{
const QStringList fields = encoded.split(PLAYMAT_FIELD_SEP);
if (fields.size() != 6) {
return {};
}
PlaymatResolution res;
PlaymatInfo res;
res.card.name = fields.at(0);
res.card.providerId = fields.at(1);
res.params.marginPctL = fields.at(2).toDouble();
@ -192,16 +192,16 @@ bool InterfaceSettings::getShowGameSelectorFilterToolbar() const
int InterfaceSettings::getPlaymatVisibility() const
{
return getValue("playmatvisibility", QString(), QString(), 2).toInt();
return qBound(0, getValue("playmatvisibility", QString(), QString(), 2).toInt(), 2);
}
QList<PlaymatResolution> InterfaceSettings::getPlaymatFallbackList() const
QList<PlaymatInfo> InterfaceSettings::getPlaymatFallbackList() const
{
const QStringList entries = getValue("playmatFallbackList", QString(), QString(), QStringList()).toStringList();
QList<PlaymatResolution> result;
QList<PlaymatInfo> result;
result.reserve(entries.size());
for (const QString &entry : entries) {
const PlaymatResolution res = decodePlaymatResolution(entry);
const PlaymatInfo res = decodePlaymatInfo(entry);
if (!res.card.isEmpty()) {
result.append(res);
}
@ -411,12 +411,12 @@ void InterfaceSettings::setPlaymatVisibility(int _visibility)
emit playmatVisibilityChanged(_visibility);
}
void InterfaceSettings::setPlaymatFallbackList(const QList<PlaymatResolution> &_fallbackList)
void InterfaceSettings::setPlaymatFallbackList(const QList<PlaymatInfo> &_fallbackList)
{
QStringList entries;
entries.reserve(_fallbackList.size());
for (const PlaymatResolution &res : _fallbackList) {
entries.append(encodePlaymatResolution(res));
for (const PlaymatInfo &res : _fallbackList) {
entries.append(encodePlaymatInfo(res));
}
setValue(entries, "playmatFallbackList");
emit playmatSettingsChanged();

View file

@ -43,7 +43,7 @@ public:
[[nodiscard]] bool getShowShortcuts() const override;
[[nodiscard]] bool getShowGameSelectorFilterToolbar() const override;
[[nodiscard]] int getPlaymatVisibility() const override;
[[nodiscard]] QList<PlaymatResolution> getPlaymatFallbackList() const override;
[[nodiscard]] QList<PlaymatInfo> getPlaymatFallbackList() const override;
[[nodiscard]] int getPlaymatMode() const override;
[[nodiscard]] int getPlaymatFallbackBehavior() const override;
[[nodiscard]] bool getLifeCounterAnimationsEnabled() const override;
@ -82,7 +82,7 @@ public:
void setShowShortcuts(bool _showShortcuts);
void setShowGameSelectorFilterToolbar(bool _showGameSelectorFilterToolbar);
void setPlaymatVisibility(int _visibility);
void setPlaymatFallbackList(const QList<PlaymatResolution> &_fallbackList);
void setPlaymatFallbackList(const QList<PlaymatInfo> &_fallbackList);
void setPlaymatMode(int _mode);
void setPlaymatFallbackBehavior(int _behavior);
void setLifeCounterAnimationsEnabled(bool _lifeCounterAnimationsEnabled);

View file

@ -34,16 +34,16 @@ struct PlaymatParams
};
/**
* @struct PlaymatResolution
* @struct PlaymatInfo
* @ingroup Decks
* @brief A resolved playmat (card + positioning parameters).
*/
struct PlaymatResolution
struct PlaymatInfo
{
CardRef card; ///< The card whose art is used as playmat.
PlaymatParams params; ///< Positioning parameters for the playmat card image.
bool operator==(const PlaymatResolution &other) const
bool operator==(const PlaymatInfo &other) const
{
return card == other.card && params == other.params;
}

View file

@ -5,11 +5,11 @@
namespace
{
PlaymatResolution makeResolution(const QString &name, const QString &providerId = QString())
PlaymatInfo makePlaymatInfo(const QString &name, const QString &providerId = QString())
{
PlaymatResolution resolution;
resolution.card = {name, providerId};
return resolution;
PlaymatInfo info;
info.card = {name, providerId};
return info;
}
} // namespace
@ -17,7 +17,7 @@ PlaymatResolution makeResolution(const QString &name, const QString &providerId
TEST(PlaymatResolverTest, EmptyChainReturnsEmpty)
{
DeckList deck;
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, {}, {}, PlaymatFallbackMode::Fixed, 0);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, {}, PlaymatFallbackModeFixed, 0);
EXPECT_TRUE(resolved.card.isEmpty());
}
@ -26,10 +26,10 @@ TEST(PlaymatResolverTest, OverrideWinsOverDeckAndFallback)
DeckList deck;
deck.setPlaymat({{QStringLiteral("Deck Mat"), QStringLiteral("deck-provider")}, {}});
const PlaymatResolution force = makeResolution(QStringLiteral("Force Mat"), QStringLiteral("force-provider"));
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("Fallback Mat"))};
const PlaymatInfo force = makePlaymatInfo(QStringLiteral("Force Mat"), QStringLiteral("force-provider"));
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("Fallback Mat"))};
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, force, fallback, PlaymatFallbackMode::Fixed, 0);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, force, fallback, PlaymatFallbackModeFixed, 0);
EXPECT_EQ(resolved.card.name, QStringLiteral("Force Mat"));
EXPECT_EQ(resolved.card.providerId, QStringLiteral("force-provider"));
}
@ -39,9 +39,9 @@ TEST(PlaymatResolverTest, DeckWinsOverFallback)
DeckList deck;
deck.setPlaymat({{QStringLiteral("Deck Mat"), QStringLiteral("deck-provider")}, {0.1, 0.2, 0.3, 1.5}});
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("Fallback Mat"))};
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("Fallback Mat"))};
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackMode::Fixed, 0);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackModeFixed, 0);
EXPECT_EQ(resolved.card.name, QStringLiteral("Deck Mat"));
EXPECT_EQ(resolved.card.providerId, QStringLiteral("deck-provider"));
EXPECT_DOUBLE_EQ(resolved.params.marginPctL, 0.1);
@ -51,20 +51,20 @@ TEST(PlaymatResolverTest, DeckWinsOverFallback)
TEST(PlaymatResolverTest, FallbackUsedWhenDeckHasNone)
{
DeckList deck;
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("Fallback Mat"))};
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("Fallback Mat"))};
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackMode::Fixed, 0);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackModeFixed, 0);
EXPECT_EQ(resolved.card.name, QStringLiteral("Fallback Mat"));
}
TEST(PlaymatResolverTest, FixedAlwaysUsesFirst)
{
DeckList deck;
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("First")),
makeResolution(QStringLiteral("Second"))};
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("First")),
makePlaymatInfo(QStringLiteral("Second"))};
for (int i = 0; i < 5; ++i) {
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackMode::Fixed, i);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackModeFixed, i);
EXPECT_EQ(resolved.card.name, QStringLiteral("First"));
}
}
@ -72,15 +72,14 @@ TEST(PlaymatResolverTest, FixedAlwaysUsesFirst)
TEST(PlaymatResolverTest, RoundRobinCyclesAndWraps)
{
DeckList deck;
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("First")),
makeResolution(QStringLiteral("Second")),
makeResolution(QStringLiteral("Third"))};
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("First")),
makePlaymatInfo(QStringLiteral("Second")),
makePlaymatInfo(QStringLiteral("Third"))};
const QStringList expected = {QStringLiteral("First"), QStringLiteral("Second"), QStringLiteral("Third"),
QStringLiteral("First"), QStringLiteral("Second"), QStringLiteral("Third")};
for (int i = 0; i < expected.size(); ++i) {
const PlaymatResolution resolved =
resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackMode::RoundRobin, i);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackModeRoundRobin, i);
EXPECT_EQ(resolved.card.name, expected.at(i));
}
}
@ -88,22 +87,22 @@ TEST(PlaymatResolverTest, RoundRobinCyclesAndWraps)
TEST(PlaymatResolverTest, RoundRobinRespectsCursor)
{
DeckList deck;
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("First")),
makeResolution(QStringLiteral("Second"))};
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("First")),
makePlaymatInfo(QStringLiteral("Second"))};
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackMode::RoundRobin, 5);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackModeRoundRobin, 5);
EXPECT_EQ(resolved.card.name, QStringLiteral("Second")); // 5 % 2 == 1
}
TEST(PlaymatResolverTest, RandomStaysWithinList)
{
DeckList deck;
const QList<PlaymatResolution> fallback = {makeResolution(QStringLiteral("First")),
makeResolution(QStringLiteral("Second")),
makeResolution(QStringLiteral("Third"))};
const QList<PlaymatInfo> fallback = {makePlaymatInfo(QStringLiteral("First")),
makePlaymatInfo(QStringLiteral("Second")),
makePlaymatInfo(QStringLiteral("Third"))};
for (int i = 0; i < 50; ++i) {
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackMode::Random, i);
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, {}, fallback, PlaymatFallbackModeRandom, i);
ASSERT_FALSE(resolved.card.name.isEmpty());
EXPECT_TRUE(fallback.contains(resolved));
}
@ -115,8 +114,8 @@ TEST(PlaymatResolverTest, ForceWithEmptyCardIgnoresFallbackParamsButNotFallback)
deck.setPlaymat({{QStringLiteral("Deck Mat")}, {}});
// An empty force entry must not mask the deck-configured playmat.
const PlaymatResolution emptyForce;
const PlaymatResolution resolved = resolveEffectivePlaymat(deck, emptyForce, {}, PlaymatFallbackMode::Fixed, 0);
const PlaymatInfo emptyForce;
const PlaymatInfo resolved = resolveEffectivePlaymat(deck, emptyForce, {}, PlaymatFallbackModeFixed, 0);
EXPECT_EQ(resolved.card.name, QStringLiteral("Deck Mat"));
}