mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-26 00:23:55 -07:00
[Game] Add Command Zone support with commander tax tracking
- Add CommandZone and CommandZoneLogic for commander - Add CommanderTaxCounter - Add counter active state protocol (show/hide tax counters) - Add "Enable Command Zone" option in game creation dialogs - Add context menu actions for command zone operations Took 9 minutes Took 11 minutes
This commit is contained in:
parent
687e6644bc
commit
75d59e2d82
73 changed files with 1540 additions and 86 deletions
|
|
@ -79,6 +79,19 @@ void AbstractCounter::delCounter()
|
|||
}
|
||||
}
|
||||
|
||||
void AbstractCounter::setValue(int _value)
|
||||
{
|
||||
value = _value;
|
||||
update();
|
||||
}
|
||||
|
||||
void AbstractCounter::setActive(bool _active)
|
||||
{
|
||||
active = _active;
|
||||
setVisible(_active);
|
||||
update();
|
||||
}
|
||||
|
||||
void AbstractCounter::retranslateUi()
|
||||
{
|
||||
if (aSet) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* @file abstract_counter.h
|
||||
* @ingroup GameGraphicsPlayers
|
||||
* @brief Abstract base for player counters displayed on the game board.
|
||||
*/
|
||||
//! \todo Document this file.
|
||||
|
||||
|
|
@ -61,6 +62,13 @@ public:
|
|||
~AbstractCounter() override;
|
||||
|
||||
void retranslateUi() override;
|
||||
|
||||
/**
|
||||
* @brief Sets the counter value and triggers a visual update.
|
||||
* Virtual to allow subclass display customization (e.g., CommanderTaxCounter tooltip updates).
|
||||
* Overflow protection is handled server-side, not in client counter classes.
|
||||
*/
|
||||
virtual void setValue(int _value);
|
||||
void setShortcutsActive() override;
|
||||
void setShortcutsInactive() override;
|
||||
void delCounter();
|
||||
|
|
@ -93,6 +101,25 @@ public:
|
|||
{
|
||||
return shownInCounterArea;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns whether this counter is active (visible and interactable).
|
||||
* Inactive counters are hidden and their menu actions should be disabled.
|
||||
*/
|
||||
[[nodiscard]] bool isActive() const
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the active state of this counter.
|
||||
* When inactive, the counter is hidden via setVisible(false).
|
||||
* @param _active True to show and enable the counter, false to hide it
|
||||
*/
|
||||
virtual void setActive(bool _active);
|
||||
|
||||
private:
|
||||
bool active = true;
|
||||
};
|
||||
|
||||
class AbstractCounterDialog : public QInputDialog
|
||||
|
|
|
|||
|
|
@ -8,4 +8,6 @@ const QMap<QString, QString> TranslateCounterName::translated = {
|
|||
{"r", QT_TRANSLATE_NOOP("TranslateCounterName", "Red")},
|
||||
{"g", QT_TRANSLATE_NOOP("TranslateCounterName", "Green")},
|
||||
{"x", QT_TRANSLATE_NOOP("TranslateCounterName", "Colorless")},
|
||||
{"storm", QT_TRANSLATE_NOOP("TranslateCounterName", "Other")}};
|
||||
{"storm", QT_TRANSLATE_NOOP("TranslateCounterName", "Other")},
|
||||
{"commander_tax_counter", QT_TRANSLATE_NOOP("TranslateCounterName", "Commander Tax")},
|
||||
{"partner_tax_counter", QT_TRANSLATE_NOOP("TranslateCounterName", "Partner Tax")}};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <libcockatrice/protocol/pb/context_move_card.pb.h>
|
||||
#include <libcockatrice/protocol/pb/context_mulligan.pb.h>
|
||||
#include <libcockatrice/utility/counter_ids.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
#include <utility>
|
||||
|
||||
|
|
@ -80,6 +81,8 @@ MessageLogWidget::getFromStr(CardZoneLogic *zone, QString cardName, int position
|
|||
fromStr = tr(" from sideboard");
|
||||
} else if (zoneName == ZoneNames::STACK) {
|
||||
fromStr = tr(" from the stack");
|
||||
} else if (zoneName == ZoneNames::COMMAND) {
|
||||
fromStr = tr(" from the command zone");
|
||||
} else {
|
||||
fromStr = tr(" from custom zone '%1'").arg(zoneName);
|
||||
}
|
||||
|
|
@ -344,6 +347,8 @@ void MessageLogWidget::logMoveCard(PlayerLogic *player,
|
|||
} else {
|
||||
finalStr = tr("%1 plays %2%3.");
|
||||
}
|
||||
} else if (targetZoneName == ZoneNames::COMMAND) {
|
||||
finalStr = tr("%1 moves %2%3 to the command zone.");
|
||||
} else {
|
||||
fourthArg = targetZoneName;
|
||||
if (card->getFaceDown()) {
|
||||
|
|
@ -671,6 +676,20 @@ void MessageLogWidget::logSetCounter(PlayerLogic *player, QString counterName, i
|
|||
soundEngine->playSound("life_change");
|
||||
}
|
||||
|
||||
if (counterName == CounterNames::CommanderTax || counterName == CounterNames::PartnerTax) {
|
||||
QString playerName = sanitizeHtml(player->getPlayerInfo()->getName());
|
||||
QString valueStr = QString("<font class=\"blue\">%1</font>").arg(value);
|
||||
int delta = value - oldValue;
|
||||
QString counterDisplayName = TranslateCounterName::getDisplayName(counterName);
|
||||
QString taxLabel = QString("<font class=\"blue\">%1</font>").arg(sanitizeHtml(counterDisplayName));
|
||||
if (value > oldValue) {
|
||||
appendHtmlServerMessage(tr("%1 increases %2 to %3 (+%4).").arg(playerName, taxLabel, valueStr).arg(delta));
|
||||
} else {
|
||||
appendHtmlServerMessage(tr("%1 decreases %2 to %3 (%4).").arg(playerName, taxLabel, valueStr).arg(delta));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QString counterDisplayName = TranslateCounterName::getDisplayName(counterName);
|
||||
appendHtmlServerMessage(tr("%1 sets counter %2 to %3 (%4%5).")
|
||||
.arg(sanitizeHtml(player->getPlayerInfo()->getName()))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ enum CardMenuActionType
|
|||
cmMoveToHand,
|
||||
cmMoveToGraveyard,
|
||||
cmMoveToExile,
|
||||
cmMoveToTable
|
||||
cmMoveToTable,
|
||||
cmMoveToCommandZone
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_MENU_ACTION_TYPE_H
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../../../client/settings/card_counter_settings.h"
|
||||
#include "../../../interface/widgets/tabs/tab_game.h"
|
||||
#include "../../board/abstract_counter.h"
|
||||
#include "../../board/card_item.h"
|
||||
#include "../../game/player/player_actions.h"
|
||||
#include "../../game/player/player_logic.h"
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
#include <QPainter>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/card/relation/card_relation.h>
|
||||
#include <libcockatrice/utility/counter_ids.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
|
||||
/**
|
||||
|
|
@ -92,6 +94,12 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho
|
|||
aSelectRow = new QAction(this);
|
||||
aSelectColumn = new QAction(this);
|
||||
|
||||
aPlayAndIncreaseTax = new QAction(this);
|
||||
connect(aPlayAndIncreaseTax, &QAction::triggered, playerActions, &PlayerActions::actPlayAndIncreaseTax);
|
||||
aPlayAndIncreasePartnerTax = new QAction(this);
|
||||
connect(aPlayAndIncreasePartnerTax, &QAction::triggered, playerActions,
|
||||
&PlayerActions::actPlayAndIncreasePartnerTax);
|
||||
|
||||
connect(aAttach, &QAction::triggered, actions, &PlayerActions::actAttach);
|
||||
connect(aDrawArrow, &QAction::triggered, actions, &PlayerActions::actDrawArrow);
|
||||
connect(aSelectAll, &QAction::triggered, actions, &PlayerActions::actSelectAll);
|
||||
|
|
@ -157,6 +165,33 @@ CardMenu::CardMenu(PlayerGraphicsItem *_player, const CardItem *_card, bool _sho
|
|||
} else if (card->getZone()->getName() == ZoneNames::EXILE ||
|
||||
card->getZone()->getName() == ZoneNames::GRAVE) {
|
||||
createGraveyardOrExileMenu(writeableCard);
|
||||
} else if (card->getZone()->getName() == ZoneNames::COMMAND) {
|
||||
if (writeableCard) {
|
||||
addAction(aPlay);
|
||||
|
||||
AbstractCounter *cmdTax = player->getCounterWidget(CounterIds::CommanderTax);
|
||||
if (cmdTax && cmdTax->isActive()) {
|
||||
addAction(aPlayAndIncreaseTax);
|
||||
}
|
||||
|
||||
AbstractCounter *partnerTax = player->getCounterWidget(CounterIds::PartnerTax);
|
||||
if (partnerTax && partnerTax->isActive()) {
|
||||
addAction(aPlayAndIncreasePartnerTax);
|
||||
}
|
||||
|
||||
// No reveal submenu - command zone is public
|
||||
addSeparator();
|
||||
addAction(aClone);
|
||||
addMenu(new MoveMenu(player));
|
||||
} else {
|
||||
addAction(aDrawArrow);
|
||||
addSeparator();
|
||||
addAction(aClone);
|
||||
}
|
||||
addSeparator();
|
||||
addAction(aSelectAll);
|
||||
addRelatedCardView();
|
||||
addRelatedCardActions();
|
||||
} else {
|
||||
createHandOrCustomZoneMenu(writeableCard);
|
||||
}
|
||||
|
|
@ -487,6 +522,8 @@ void CardMenu::retranslateUi()
|
|||
aPlay->setText(tr("&Play"));
|
||||
aHide->setText(tr("&Hide"));
|
||||
aPlayFacedown->setText(tr("Play &Face Down"));
|
||||
aPlayAndIncreaseTax->setText(tr("Play and &Increase Commander Tax"));
|
||||
aPlayAndIncreasePartnerTax->setText(tr("Play and Increase &Partner Tax"));
|
||||
aRevealToAll->setText(tr("&All players"));
|
||||
//: Turn sideways or back again
|
||||
aTap->setText(tr("&Tap / Untap"));
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ public:
|
|||
QMenu *mCardCounters;
|
||||
|
||||
QAction *aPlay, *aPlayFacedown;
|
||||
QAction *
|
||||
aPlayAndIncreaseTax; ///< Plays card and increments the primary commander tax counter (CounterIds::CommanderTax)
|
||||
QAction *aPlayAndIncreasePartnerTax;
|
||||
QAction *aRevealToAll;
|
||||
QAction *aHide;
|
||||
QAction *aClone;
|
||||
|
|
|
|||
184
cockatrice/src/game_graphics/player/menu/command_zone_menu.cpp
Normal file
184
cockatrice/src/game_graphics/player/menu/command_zone_menu.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include "command_zone_menu.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../board/abstract_counter.h"
|
||||
#include "../../game_scene.h"
|
||||
#include "../../zones/command_zone.h"
|
||||
#include "../player_actions.h"
|
||||
#include "../player_graphics_item.h"
|
||||
#include "../player_logic.h"
|
||||
|
||||
#include <libcockatrice/utility/counter_ids.h>
|
||||
#include <libcockatrice/utility/zone_names.h>
|
||||
|
||||
CommandZoneMenu::CommandZoneMenu(PlayerLogic *_player, QMenu *playerMenu) : QMenu(playerMenu), player(_player)
|
||||
{
|
||||
viewZoneShortcutKey = QStringLiteral("Player/aViewCommandZone");
|
||||
incTaxShortcutKey = QStringLiteral("Player/aAddCommanderTax");
|
||||
decTaxShortcutKey = QStringLiteral("Player/aRemoveCommanderTax");
|
||||
incPartnerTaxShortcutKey = QStringLiteral("Player/aAddPartnerTax");
|
||||
decPartnerTaxShortcutKey = QStringLiteral("Player/aRemovePartnerTax");
|
||||
|
||||
aViewZone = new QAction(this);
|
||||
connect(aViewZone, &QAction::triggered, this,
|
||||
[this]() { player->getGameScene()->toggleZoneView(player, ZoneNames::COMMAND, -1); });
|
||||
|
||||
if (player->getPlayerInfo()->getLocalOrJudge()) {
|
||||
addAction(aViewZone);
|
||||
addSeparator();
|
||||
|
||||
PlayerActions *playerActions = player->getPlayerActions();
|
||||
|
||||
aIncreaseCommanderTax = new QAction(this);
|
||||
connect(aIncreaseCommanderTax, &QAction::triggered, this,
|
||||
[playerActions]() { playerActions->actModifyTaxCounter(CounterIds::CommanderTax, 1); });
|
||||
addAction(aIncreaseCommanderTax);
|
||||
|
||||
aDecreaseCommanderTax = new QAction(this);
|
||||
connect(aDecreaseCommanderTax, &QAction::triggered, this,
|
||||
[playerActions]() { playerActions->actModifyTaxCounter(CounterIds::CommanderTax, -1); });
|
||||
addAction(aDecreaseCommanderTax);
|
||||
|
||||
addSeparator();
|
||||
|
||||
aIncreasePartnerTax = new QAction(this);
|
||||
connect(aIncreasePartnerTax, &QAction::triggered, this,
|
||||
[playerActions]() { playerActions->actModifyTaxCounter(CounterIds::PartnerTax, 1); });
|
||||
addAction(aIncreasePartnerTax);
|
||||
|
||||
aDecreasePartnerTax = new QAction(this);
|
||||
connect(aDecreasePartnerTax, &QAction::triggered, this,
|
||||
[playerActions]() { playerActions->actModifyTaxCounter(CounterIds::PartnerTax, -1); });
|
||||
addAction(aDecreasePartnerTax);
|
||||
|
||||
addSeparator();
|
||||
|
||||
aToggleCommanderTaxCounter = new QAction(this);
|
||||
connect(aToggleCommanderTaxCounter, &QAction::triggered, this,
|
||||
[playerActions]() { playerActions->actToggleTaxCounter(CounterIds::CommanderTax); });
|
||||
addAction(aToggleCommanderTaxCounter);
|
||||
|
||||
aTogglePartnerTaxCounter = new QAction(this);
|
||||
connect(aTogglePartnerTaxCounter, &QAction::triggered, this,
|
||||
[playerActions]() { playerActions->actToggleTaxCounter(CounterIds::PartnerTax); });
|
||||
addAction(aTogglePartnerTaxCounter);
|
||||
|
||||
addSeparator();
|
||||
|
||||
aToggleMinimized = new QAction(this);
|
||||
connect(aToggleMinimized, &QAction::triggered, this, &CommandZoneMenu::actToggleMinimized);
|
||||
addAction(aToggleMinimized);
|
||||
|
||||
connect(this, &QMenu::aboutToShow, this, &CommandZoneMenu::updateTaxCounterActionStates);
|
||||
}
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void CommandZoneMenu::retranslateUi()
|
||||
{
|
||||
setTitle(tr("Co&mmander"));
|
||||
if (aViewZone) {
|
||||
aViewZone->setText(tr("&View command zone"));
|
||||
}
|
||||
if (aIncreaseCommanderTax) {
|
||||
aIncreaseCommanderTax->setText(tr("&Increase Commander Tax (+1)"));
|
||||
}
|
||||
if (aDecreaseCommanderTax) {
|
||||
aDecreaseCommanderTax->setText(tr("&Decrease Commander Tax (-1)"));
|
||||
}
|
||||
if (aToggleCommanderTaxCounter) {
|
||||
aToggleCommanderTaxCounter->setText(tr("&Remove Commander Tax"));
|
||||
}
|
||||
if (aIncreasePartnerTax) {
|
||||
aIncreasePartnerTax->setText(tr("Increase &Partner Tax (+1)"));
|
||||
}
|
||||
if (aDecreasePartnerTax) {
|
||||
aDecreasePartnerTax->setText(tr("Decrease P&artner Tax (-1)"));
|
||||
}
|
||||
if (aTogglePartnerTaxCounter) {
|
||||
aTogglePartnerTaxCounter->setText(tr("&Add Partner Tax"));
|
||||
}
|
||||
if (aToggleMinimized) {
|
||||
aToggleMinimized->setText(tr("&Minimize"));
|
||||
}
|
||||
}
|
||||
|
||||
void CommandZoneMenu::actToggleMinimized()
|
||||
{
|
||||
CommandZone *zone = player->getGraphicsItem()->getCommandZoneGraphicsItem();
|
||||
if (zone) {
|
||||
zone->toggleMinimized();
|
||||
}
|
||||
}
|
||||
|
||||
void CommandZoneMenu::updateTaxCounterActionStates()
|
||||
{
|
||||
AbstractCounter *cmdTax = player->getCounterWidget(CounterIds::CommanderTax);
|
||||
bool cmdActive = cmdTax && cmdTax->isActive();
|
||||
|
||||
AbstractCounter *partnerTax = player->getCounterWidget(CounterIds::PartnerTax);
|
||||
bool partnerActive = partnerTax && partnerTax->isActive();
|
||||
|
||||
if (aIncreaseCommanderTax) {
|
||||
aIncreaseCommanderTax->setVisible(cmdActive);
|
||||
}
|
||||
if (aDecreaseCommanderTax) {
|
||||
aDecreaseCommanderTax->setVisible(cmdActive);
|
||||
}
|
||||
if (aToggleCommanderTaxCounter) {
|
||||
aToggleCommanderTaxCounter->setText(cmdActive ? tr("&Remove Commander Tax") : tr("&Add Commander Tax"));
|
||||
aToggleCommanderTaxCounter->setVisible(!cmdActive || (cmdTax && cmdTax->getValue() == 0));
|
||||
}
|
||||
|
||||
if (aIncreasePartnerTax) {
|
||||
aIncreasePartnerTax->setVisible(partnerActive);
|
||||
}
|
||||
if (aDecreasePartnerTax) {
|
||||
aDecreasePartnerTax->setVisible(partnerActive);
|
||||
}
|
||||
if (aTogglePartnerTaxCounter) {
|
||||
aTogglePartnerTaxCounter->setText(partnerActive ? tr("R&emove Partner Tax") : tr("&Add Partner Tax"));
|
||||
aTogglePartnerTaxCounter->setVisible(!partnerActive || (partnerTax && partnerTax->getValue() == 0));
|
||||
}
|
||||
}
|
||||
|
||||
void CommandZoneMenu::setShortcutsActive()
|
||||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
|
||||
if (aViewZone) {
|
||||
aViewZone->setShortcuts(shortcuts.getShortcut(viewZoneShortcutKey));
|
||||
}
|
||||
if (aIncreaseCommanderTax) {
|
||||
aIncreaseCommanderTax->setShortcuts(shortcuts.getShortcut(incTaxShortcutKey));
|
||||
}
|
||||
if (aDecreaseCommanderTax) {
|
||||
aDecreaseCommanderTax->setShortcuts(shortcuts.getShortcut(decTaxShortcutKey));
|
||||
}
|
||||
if (aIncreasePartnerTax) {
|
||||
aIncreasePartnerTax->setShortcuts(shortcuts.getShortcut(incPartnerTaxShortcutKey));
|
||||
}
|
||||
if (aDecreasePartnerTax) {
|
||||
aDecreasePartnerTax->setShortcuts(shortcuts.getShortcut(decPartnerTaxShortcutKey));
|
||||
}
|
||||
}
|
||||
|
||||
void CommandZoneMenu::setShortcutsInactive()
|
||||
{
|
||||
if (aViewZone) {
|
||||
aViewZone->setShortcut(QKeySequence());
|
||||
}
|
||||
if (aIncreaseCommanderTax) {
|
||||
aIncreaseCommanderTax->setShortcut(QKeySequence());
|
||||
}
|
||||
if (aDecreaseCommanderTax) {
|
||||
aDecreaseCommanderTax->setShortcut(QKeySequence());
|
||||
}
|
||||
if (aIncreasePartnerTax) {
|
||||
aIncreasePartnerTax->setShortcut(QKeySequence());
|
||||
}
|
||||
if (aDecreasePartnerTax) {
|
||||
aDecreasePartnerTax->setShortcut(QKeySequence());
|
||||
}
|
||||
}
|
||||
62
cockatrice/src/game_graphics/player/menu/command_zone_menu.h
Normal file
62
cockatrice/src/game_graphics/player/menu/command_zone_menu.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* @file command_zone_menu.h
|
||||
* @ingroup GameMenusZones
|
||||
* @brief Context menu for command zone right-click actions.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_COMMAND_ZONE_MENU_H
|
||||
#define COCKATRICE_COMMAND_ZONE_MENU_H
|
||||
|
||||
#include "abstract_player_component.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
class PlayerLogic;
|
||||
|
||||
/**
|
||||
* @class CommandZoneMenu
|
||||
* @brief Context menu for the command zone.
|
||||
*
|
||||
* Appears when right-clicking on the command zone. Provides actions for
|
||||
* viewing zone contents, adjusting the commander tax counter, and
|
||||
* toggling minimized state.
|
||||
*
|
||||
* @see PlayerMenu
|
||||
* @see CommandZone
|
||||
*/
|
||||
class CommandZoneMenu : public QMenu, public AbstractPlayerComponent
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CommandZoneMenu(PlayerLogic *player, QMenu *playerMenu);
|
||||
void retranslateUi() override;
|
||||
void setShortcutsActive() override;
|
||||
void setShortcutsInactive() override;
|
||||
|
||||
QAction *aViewZone = nullptr; ///< Opens a zone viewer for the command zone
|
||||
|
||||
private:
|
||||
QAction *aIncreaseCommanderTax = nullptr; ///< Increments the primary commander tax counter
|
||||
QAction *aDecreaseCommanderTax = nullptr; ///< Decrements the primary commander tax counter
|
||||
QAction *aToggleCommanderTaxCounter = nullptr; ///< Toggles primary commander tax counter visibility
|
||||
QAction *aIncreasePartnerTax = nullptr; ///< Increments the partner commander tax counter
|
||||
QAction *aDecreasePartnerTax = nullptr; ///< Decrements the partner commander tax counter
|
||||
QAction *aTogglePartnerTaxCounter = nullptr; ///< Toggles partner commander tax counter visibility
|
||||
QAction *aToggleMinimized = nullptr; ///< Toggles command zone minimized state
|
||||
|
||||
private slots:
|
||||
void actToggleMinimized();
|
||||
|
||||
private:
|
||||
void updateTaxCounterActionStates();
|
||||
PlayerLogic *player;
|
||||
|
||||
QString viewZoneShortcutKey;
|
||||
QString incTaxShortcutKey;
|
||||
QString decTaxShortcutKey;
|
||||
QString incPartnerTaxShortcutKey;
|
||||
QString decPartnerTaxShortcutKey;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_COMMAND_ZONE_MENU_H
|
||||
|
|
@ -20,6 +20,8 @@ MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to"))
|
|||
aMoveToGraveyard->setData(cmMoveToGraveyard);
|
||||
aMoveToExile = new QAction(this);
|
||||
aMoveToExile->setData(cmMoveToExile);
|
||||
aMoveToCommandZone = new QAction(this);
|
||||
aMoveToCommandZone->setData(cmMoveToCommandZone);
|
||||
|
||||
auto *actions = player->getLogic()->getPlayerActions();
|
||||
|
||||
|
|
@ -49,6 +51,8 @@ MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to"))
|
|||
addAction(aMoveToGraveyard);
|
||||
addSeparator();
|
||||
addAction(aMoveToExile);
|
||||
addSeparator();
|
||||
addAction(aMoveToCommandZone);
|
||||
|
||||
setShortcutsActive();
|
||||
|
||||
|
|
@ -65,6 +69,7 @@ void MoveMenu::setShortcutsActive()
|
|||
aMoveToHand->setShortcuts(shortcuts.getShortcut("Player/aMoveToHand"));
|
||||
aMoveToGraveyard->setShortcuts(shortcuts.getShortcut("Player/aMoveToGraveyard"));
|
||||
aMoveToExile->setShortcuts(shortcuts.getShortcut("Player/aMoveToExile"));
|
||||
aMoveToCommandZone->setShortcuts(shortcuts.getShortcut("Player/aMoveToCommandZone"));
|
||||
}
|
||||
|
||||
void MoveMenu::retranslateUi()
|
||||
|
|
@ -76,4 +81,5 @@ void MoveMenu::retranslateUi()
|
|||
aMoveToHand->setText(tr("&Hand"));
|
||||
aMoveToGraveyard->setText(tr("&Graveyard"));
|
||||
aMoveToExile->setText(tr("&Exile"));
|
||||
aMoveToCommandZone->setText(tr("&Command Zone"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public:
|
|||
QAction *aMoveToTable = nullptr;
|
||||
QAction *aMoveToGraveyard = nullptr;
|
||||
QAction *aMoveToExile = nullptr;
|
||||
QAction *aMoveToCommandZone = nullptr;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_MOVE_MENU_H
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "../../../game_graphics/zones/table_zone.h"
|
||||
#include "../../../interface/widgets/tabs/tab_game.h"
|
||||
#include "../../board/card_item.h"
|
||||
#include "../../zones/command_zone.h"
|
||||
#include "../player_graphics_item.h"
|
||||
#include "card_menu.h"
|
||||
#include "hand_menu.h"
|
||||
|
|
@ -31,6 +32,16 @@ PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_
|
|||
|
||||
if (player->getLogic()->getPlayerInfo()->getLocalOrJudge()) {
|
||||
sideboardMenu = addManagedMenu<SideboardMenu>(player, playerMenu);
|
||||
|
||||
commandZoneMenu = addManagedMenu<CommandZoneMenu>(player, playerMenu);
|
||||
auto updateCommandZoneMenuVisibility = [this](bool has) {
|
||||
if (commandZoneMenu) {
|
||||
commandZoneMenu->menuAction()->setVisible(has);
|
||||
}
|
||||
};
|
||||
connect(player, &PlayerLogic::commandZoneSupportChanged, this, updateCommandZoneMenuVisibility);
|
||||
updateCommandZoneMenuVisibility(player->hasServerCommandZone());
|
||||
|
||||
customZonesMenu = addManagedMenu<CustomZoneMenu>(player);
|
||||
playerMenu->addSeparator();
|
||||
|
||||
|
|
@ -39,6 +50,7 @@ PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_
|
|||
utilityMenu = createManagedComponent<UtilityMenu>(player, playerMenu);
|
||||
} else {
|
||||
sideboardMenu = nullptr;
|
||||
commandZoneMenu = nullptr;
|
||||
customZonesMenu = nullptr;
|
||||
countersMenu = nullptr;
|
||||
utilityMenu = nullptr;
|
||||
|
|
@ -66,6 +78,10 @@ void PlayerMenu::setMenusForGraphicItems()
|
|||
player->getHandZoneGraphicsItem()->setMenu(handMenu);
|
||||
player->getDeckZoneGraphicsItem()->setMenu(libraryMenu, libraryMenu->aDrawCard);
|
||||
player->getSideboardZoneGraphicsItem()->setMenu(sideboardMenu);
|
||||
|
||||
if (auto *commandZone = player->getCommandZoneGraphicsItem()) {
|
||||
commandZone->setMenu(commandZoneMenu, commandZoneMenu->aViewZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#define COCKATRICE_PLAYER_MENU_H
|
||||
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
#include "../player_logic.h"
|
||||
#include "command_zone_menu.h"
|
||||
#include "custom_zone_menu.h"
|
||||
#include "grave_menu.h"
|
||||
#include "hand_menu.h"
|
||||
|
|
@ -88,6 +90,7 @@ private:
|
|||
RfgMenu *rfgMenu;
|
||||
UtilityMenu *utilityMenu;
|
||||
SayMenu *sayMenu;
|
||||
CommandZoneMenu *commandZoneMenu;
|
||||
CustomZoneMenu *customZonesMenu;
|
||||
|
||||
/** @brief Drives AbstractPlayerComponent lifecycle delegation. Counters are iterated separately via
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../game/player/player_actions.h"
|
||||
#include "../../interface/widgets/tabs/tab_game.h"
|
||||
#include "../board/abstract_card_item.h"
|
||||
#include "../board/commander_tax_counter.h"
|
||||
#include "../board/counter_general.h"
|
||||
#include "../hand_counter.h"
|
||||
#include "../zones/hand_zone.h"
|
||||
|
|
@ -13,6 +14,10 @@
|
|||
#include "player_dialogs.h"
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include "../z_values.h"
|
||||
#include "../zones/command_zone.h"
|
||||
|
||||
#include <libcockatrice/utility/counter_ids.h>
|
||||
|
||||
PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player)
|
||||
{
|
||||
|
|
@ -121,6 +126,12 @@ void PlayerGraphicsItem::initializeZones()
|
|||
new HandZone(player->getHandZone(), static_cast<int>(tableZoneGraphicsItem->boundingRect().height()), this);
|
||||
connect(player->getPlayerActions(), &PlayerActions::requestSortHand, handZoneGraphicsItem, &HandZone::sortHand);
|
||||
|
||||
// Command zone
|
||||
commandZoneGraphicsItem = new CommandZone(player->getCommandZone(), ZoneSizes::COMMAND_ZONE_HEIGHT, this);
|
||||
commandZoneGraphicsItem->setZValue(ZValues::COMMAND_ZONE);
|
||||
commandZoneGraphicsItem->setVisible(false);
|
||||
connect(commandZoneGraphicsItem, &CommandZone::minimizedChanged, this, &PlayerGraphicsItem::rearrangeZones);
|
||||
|
||||
connect(handZoneGraphicsItem->getLogic(), &HandZoneLogic::cardCountChanged, handCounter,
|
||||
&HandCounter::updateNumber);
|
||||
connect(handCounter, &HandCounter::showContextMenu, handZoneGraphicsItem, &HandZone::showContextMenu);
|
||||
|
|
@ -187,6 +198,13 @@ void PlayerGraphicsItem::onCounterAdded(CounterState *state)
|
|||
AbstractCounter *widget;
|
||||
if (state->getName() == "life") {
|
||||
widget = playerTarget->addCounter(state);
|
||||
} else if (CounterNames::isTaxCounter(state->getName())) {
|
||||
if (!commandZoneGraphicsItem) {
|
||||
qWarning() << "Cannot create tax counter" << state->getName() << "- command zone not available";
|
||||
return;
|
||||
}
|
||||
widget = new CommanderTaxCounter(state, player, commandZoneGraphicsItem);
|
||||
widget->setActive(state->isActive());
|
||||
} else {
|
||||
widget = new GeneralCounter(state, player, true, this);
|
||||
}
|
||||
|
|
@ -218,9 +236,16 @@ void PlayerGraphicsItem::onCounterRemoved(int counterId)
|
|||
|
||||
void PlayerGraphicsItem::rearrangeCounters()
|
||||
{
|
||||
if (commandZoneGraphicsItem) {
|
||||
commandZoneGraphicsItem->rearrangeTaxCounters();
|
||||
}
|
||||
|
||||
qreal ySize = boundingRect().y() + 80;
|
||||
constexpr qreal padding = 5;
|
||||
for (auto *ctr : counterWidgets.values()) {
|
||||
if (CounterNames::isTaxCounter(ctr->getName())) {
|
||||
continue;
|
||||
}
|
||||
if (!ctr->getShownInCounterArea()) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -230,9 +255,33 @@ void PlayerGraphicsItem::rearrangeCounters()
|
|||
}
|
||||
}
|
||||
|
||||
QList<AbstractCounter *> PlayerGraphicsItem::getTaxCounterWidgets() const
|
||||
{
|
||||
QList<AbstractCounter *> result;
|
||||
for (AbstractCounter *ctr : counterWidgets.values()) {
|
||||
if (CounterNames::isTaxCounter(ctr->getName())) {
|
||||
result.append(ctr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PlayerGraphicsItem::rearrangeZones()
|
||||
{
|
||||
auto base = QPointF(CardDimensions::HEIGHT_F + counterAreaWidth + 15, 0);
|
||||
|
||||
// Calculate stack height, accounting for command zone if visible
|
||||
bool commandZoneVisible = commandZoneGraphicsItem && commandZoneGraphicsItem->isVisible();
|
||||
qreal tableHeight = tableZoneGraphicsItem->boundingRect().height();
|
||||
qreal stackHeight = tableHeight;
|
||||
if (commandZoneVisible) {
|
||||
stackHeight = tableHeight - totalCommandZoneHeight();
|
||||
if (stackHeight < CommandZone::MINIMUM_STACKING_HEIGHT) {
|
||||
stackHeight = CommandZone::MINIMUM_STACKING_HEIGHT;
|
||||
}
|
||||
}
|
||||
stackZoneGraphicsItem->setHeight(stackHeight);
|
||||
|
||||
if (SettingsCache::instance().getHorizontalHand()) {
|
||||
if (mirrored) {
|
||||
if (player->getHandZone()->contentsKnown()) {
|
||||
|
|
@ -243,12 +292,12 @@ void PlayerGraphicsItem::rearrangeZones()
|
|||
handVisible = false;
|
||||
}
|
||||
|
||||
stackZoneGraphicsItem->setPos(base);
|
||||
positionCommandAndStackZones(base);
|
||||
base += QPointF(stackZoneGraphicsItem->boundingRect().width(), 0);
|
||||
|
||||
tableZoneGraphicsItem->setPos(base);
|
||||
} else {
|
||||
stackZoneGraphicsItem->setPos(base);
|
||||
positionCommandAndStackZones(base);
|
||||
|
||||
tableZoneGraphicsItem->setPos(base.x() + stackZoneGraphicsItem->boundingRect().width(), 0);
|
||||
base += QPointF(0, tableZoneGraphicsItem->boundingRect().height());
|
||||
|
|
@ -268,7 +317,7 @@ void PlayerGraphicsItem::rearrangeZones()
|
|||
handZoneGraphicsItem->setPos(base);
|
||||
base += QPointF(handZoneGraphicsItem->boundingRect().width(), 0);
|
||||
|
||||
stackZoneGraphicsItem->setPos(base);
|
||||
positionCommandAndStackZones(base);
|
||||
base += QPointF(stackZoneGraphicsItem->boundingRect().width(), 0);
|
||||
|
||||
tableZoneGraphicsItem->setPos(base);
|
||||
|
|
@ -297,3 +346,28 @@ void PlayerGraphicsItem::updateBoundingRect()
|
|||
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
qreal PlayerGraphicsItem::totalCommandZoneHeight() const
|
||||
{
|
||||
if (commandZoneGraphicsItem && commandZoneGraphicsItem->isVisible()) {
|
||||
return commandZoneGraphicsItem->currentHeight();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PlayerGraphicsItem::positionCommandAndStackZones(const QPointF &base)
|
||||
{
|
||||
bool commandZoneVisible = commandZoneGraphicsItem && commandZoneGraphicsItem->isVisible();
|
||||
if (commandZoneVisible) {
|
||||
commandZoneGraphicsItem->setPos(base);
|
||||
}
|
||||
stackZoneGraphicsItem->setPos(base.x(), base.y() + (commandZoneVisible ? totalCommandZoneHeight() : 0));
|
||||
}
|
||||
|
||||
void PlayerGraphicsItem::setCommandZoneVisible(bool visible)
|
||||
{
|
||||
if (commandZoneGraphicsItem) {
|
||||
commandZoneGraphicsItem->setVisible(visible);
|
||||
}
|
||||
rearrangeZones();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <QGraphicsObject>
|
||||
|
||||
class CommandZone;
|
||||
class HandZone;
|
||||
class PileZone;
|
||||
class PlayerDialogs;
|
||||
|
|
@ -112,6 +113,18 @@ public:
|
|||
{
|
||||
return handZoneGraphicsItem;
|
||||
}
|
||||
/** @brief Returns the command zone graphics item. */
|
||||
[[nodiscard]] CommandZone *getCommandZoneGraphicsItem() const
|
||||
{
|
||||
return commandZoneGraphicsItem;
|
||||
}
|
||||
/** @brief Returns the counter widget for the given counter ID, or nullptr if not found. */
|
||||
[[nodiscard]] AbstractCounter *getCounterWidget(int counterId) const
|
||||
{
|
||||
return counterWidgets.value(counterId, nullptr);
|
||||
}
|
||||
/** @brief Returns all tax counter widgets (commander tax and partner tax). */
|
||||
[[nodiscard]] QList<AbstractCounter *> getTaxCounterWidgets() const;
|
||||
|
||||
public slots:
|
||||
void onPlayerActiveChanged(bool _active);
|
||||
|
|
@ -120,6 +133,8 @@ public slots:
|
|||
void onCounterRemoved(int counterId);
|
||||
void rearrangeCounters();
|
||||
void retranslateUi();
|
||||
/** @brief Shows or hides the command zone and rearranges dependent zones. */
|
||||
void setCommandZoneVisible(bool visible);
|
||||
|
||||
signals:
|
||||
void sizeChanged();
|
||||
|
|
@ -142,10 +157,15 @@ private:
|
|||
TableZone *tableZoneGraphicsItem;
|
||||
StackZone *stackZoneGraphicsItem;
|
||||
HandZone *handZoneGraphicsItem;
|
||||
CommandZone *commandZoneGraphicsItem;
|
||||
QRectF bRect;
|
||||
bool mirrored;
|
||||
bool handVisible = false;
|
||||
|
||||
/** @brief Returns the command zone's display height, or 0 if hidden. */
|
||||
[[nodiscard]] qreal totalCommandZoneHeight() const;
|
||||
/** @brief Positions the command and stack zones vertically starting from base, updating base.y. */
|
||||
void positionCommandAndStackZones(const QPointF &base);
|
||||
private slots:
|
||||
void updateBoundingRect();
|
||||
void rearrangeZones();
|
||||
|
|
|
|||
|
|
@ -29,11 +29,16 @@
|
|||
namespace ZValues
|
||||
{
|
||||
|
||||
/** @brief Command zone sits at standard zone level */
|
||||
constexpr qreal COMMAND_ZONE = 1.0;
|
||||
|
||||
// Expose base for callers that need it
|
||||
constexpr qreal OVERLAY_BASE = ZValueLayerManager::OVERLAY_BASE;
|
||||
|
||||
// Overlay layer Z-values for items that should appear above normal cards
|
||||
constexpr qreal HOVERED_CARD = ZValueLayerManager::overlayZValue(1.0);
|
||||
/** @brief Commander tax counter overlay */
|
||||
constexpr qreal TAX_COUNTERS = ZValueLayerManager::overlayZValue(2.0);
|
||||
constexpr qreal ARROWS = ZValueLayerManager::overlayZValue(3.0);
|
||||
constexpr qreal ZONE_VIEW_WIDGET = ZValueLayerManager::overlayZValue(4.0);
|
||||
constexpr qreal DRAG_ITEM = ZValueLayerManager::overlayZValue(5.0);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ QRectF StackZone::boundingRect() const
|
|||
void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
QBrush brush = themeManager->getExtraBgBrush(ThemeManager::Stack, getLogic()->getPlayer()->getZoneId());
|
||||
|
||||
QPointF scenePos = mapToScene(QPointF(0, 0));
|
||||
painter->setBrushOrigin(-scenePos);
|
||||
|
||||
painter->fillRect(boundingRect(), brush);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue