Player refactor (#6112)

* Player refactor.

Took 1 hour 43 minutes

Took 1 minute


Took 23 seconds

* Tiny lint.

Took 3 minutes

* Hook up tap logic again.

Took 13 minutes

* Fix an include.

Took 3 minutes

* Stuff.

Took 6 minutes

* Fix typo.

Took 7 minutes

* Include.

Took 1 minute

* Reorganize method/variable definitions, remove unused ones.

Took 1 hour 8 minutes


Took 24 seconds

* Clean up some unused imports.

Took 6 minutes

* Player holds the deck, emits deckChanged(), other elements player->getDeck() to respond to changes.

Took 37 minutes

* Connect player->openDeckEditor signal directly in the player constructor

Took 6 minutes

* Emit openDeckEditor signal in player_actions again.

Took 3 minutes

* Do to-do's

Took 3 hours 32 minutes

* Lint.

Took 3 minutes

* Lint again.

Took 2 minutes

* Fix include.

Took 32 minutes

* The stack should ensure card visibility.

Took 21 minutes

* Fine, the game can remember the tab.

Took 10 minutes

Took 21 seconds

Took 9 seconds

* zoneId is a dynamic gameplay property and thus belongs in player.cpp

Took 11 minutes

Took 19 seconds

* Signal view removal, addition.

Took 5 minutes

* Ensure all players are considered local in local game.

Took 10 minutes

* ENSURE they are.

Took 8 minutes

* Bounds check data sent by QAction()

Took 54 minutes

* Move comment.

Took 20 seconds

* Reimplement logging category for game_event_handler.cpp, remove linebreaks.

Took 36 seconds

* PlayerGraphicsItem is responsible for retranslateUi, not Player.


Took 14 seconds

* Set menu for sideboard again, translate some menu titles, reimplement actIncPT action

Took 54 seconds

* Comment spacing.

Took 43 seconds

* Change message_log_widget.cpp slots to take CardZoneLogic parameters as emitted by PlayerEventHandler.

Took 7 minutes

Took 14 seconds

* Remove unused player_logger.cpp

Took 2 minutes

* Query local game state correctly from tab_supervisor again

Took 3 minutes

* Revert Deck legality checker.

Took 3 minutes

* Instantiate menu before graphics item.

Took 1 hour 5 minutes

Took 55 minutes

* Differentiate games and replays.


Took 9 seconds

* Lint.

Took 10 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2025-09-11 00:49:33 +02:00 committed by GitHub
parent b8e545bfa4
commit 9601a1fa4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
92 changed files with 7104 additions and 5827 deletions

View file

@ -4,6 +4,7 @@
#include "../cards/exact_card.h"
#include "arrow_target.h"
#include "card_ref.h"
#include "graphics_item_type.h"
class Player;

View file

@ -1,5 +1,6 @@
#include "abstract_counter.h"
#include "../../client/tabs/tab_game.h"
#include "../../client/translate_counter_name.h"
#include "../../settings/cache_settings.h"
#include "../player/player.h"
@ -22,17 +23,16 @@ AbstractCounter::AbstractCounter(Player *_player,
bool _shownInCounterArea,
int _value,
bool _useNameForShortcut,
QGraphicsItem *parent,
QWidget *_game)
QGraphicsItem *parent)
: QGraphicsItem(parent), player(_player), id(_id), name(_name), value(_value),
useNameForShortcut(_useNameForShortcut), hovered(false), aDec(nullptr), aInc(nullptr), dialogSemaphore(false),
deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea), game(_game)
deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea)
{
setAcceptHoverEvents(true);
shortcutActive = false;
if (player->getLocalOrJudge()) {
if (player->getPlayerInfo()->getLocalOrJudge()) {
QString displayName = TranslateCounterName::getDisplayName(_name);
menu = new TearOffMenu(displayName);
aSet = new QAction(this);
@ -85,7 +85,7 @@ void AbstractCounter::retranslateUi()
void AbstractCounter::setShortcutsActive()
{
if (!player->getLocal()) {
if (!player->getPlayerInfo()->getLocal()) {
return;
}
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
@ -127,7 +127,7 @@ void AbstractCounter::setValue(int _value)
void AbstractCounter::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (isUnderMouse() && player->getLocalOrJudge()) {
if (isUnderMouse() && player->getPlayerInfo()->getLocalOrJudge()) {
if (event->button() == Qt::MiddleButton || (QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
if (menu)
menu->exec(event->screenPos());
@ -136,13 +136,13 @@ void AbstractCounter::mousePressEvent(QGraphicsSceneMouseEvent *event)
Command_IncCounter cmd;
cmd.set_counter_id(id);
cmd.set_delta(1);
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
event->accept();
} else if (event->button() == Qt::RightButton) {
Command_IncCounter cmd;
cmd.set_counter_id(id);
cmd.set_delta(-1);
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
event->accept();
}
} else
@ -167,13 +167,13 @@ void AbstractCounter::incrementCounter()
Command_IncCounter cmd;
cmd.set_counter_id(id);
cmd.set_delta(delta);
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
}
void AbstractCounter::setCounter()
{
dialogSemaphore = true;
AbstractCounterDialog dialog(name, QString::number(value), game);
AbstractCounterDialog dialog(name, QString::number(value), player->getGame()->getTab());
const int ok = dialog.exec();
if (deleteAfterDialog) {
@ -191,7 +191,7 @@ void AbstractCounter::setCounter()
Command_SetCounter cmd;
cmd.set_counter_id(id);
cmd.set_value(newValue);
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
}
AbstractCounterDialog::AbstractCounterDialog(const QString &name, const QString &value, QWidget *parent)

View file

@ -34,7 +34,6 @@ private:
bool dialogSemaphore, deleteAfterDialog;
bool shownInCounterArea;
bool shortcutActive;
QWidget *game;
private slots:
void refreshShortcuts();
@ -48,8 +47,7 @@ public:
bool _shownInCounterArea,
int _value,
bool _useNameForShortcut = false,
QGraphicsItem *parent = nullptr,
QWidget *game = nullptr);
QGraphicsItem *parent = nullptr);
~AbstractCounter() override;
void retranslateUi();

View file

@ -3,28 +3,18 @@
#include <QGraphicsItem>
enum GraphicsItemType
{
typeCard = QGraphicsItem::UserType + 1,
typeCardDrag = QGraphicsItem::UserType + 2,
typeZone = QGraphicsItem::UserType + 3,
typePlayerTarget = QGraphicsItem::UserType + 4,
typeDeckViewCardContainer = QGraphicsItem::UserType + 5,
typeOther = QGraphicsItem::UserType + 6
};
/**
* Parent class of all objects that appear in a game.
*/
class AbstractGraphicsItem : public QObject, public QGraphicsItem
class AbstractGraphicsItem : public QGraphicsObject
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
protected:
void paintNumberEllipse(int number, int radius, const QColor &color, int position, int count, QPainter *painter);
public:
explicit AbstractGraphicsItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent)
explicit AbstractGraphicsItem(QGraphicsItem *parent = nullptr) : QGraphicsObject(parent)
{
}
};

View file

@ -130,7 +130,7 @@ void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti
void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (!player->getLocal()) {
if (!player->getPlayerInfo()->getLocal()) {
event->ignore();
return;
}
@ -147,7 +147,7 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (event->button() == Qt::RightButton) {
Command_DeleteArrow cmd;
cmd.set_arrow_id(id);
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
}
}
@ -214,7 +214,7 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
return;
if (targetItem && (targetItem != startItem)) {
CardZone *startZone = static_cast<CardItem *>(startItem)->getZone();
CardZoneLogic *startZone = static_cast<CardItem *>(startItem)->getZone();
// For now, we can safely assume that the start item is always a card.
// The target item can be a player as well.
CardItem *startCard = qgraphicsitem_cast<CardItem *>(startItem);
@ -222,18 +222,18 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
Command_CreateArrow cmd;
cmd.mutable_arrow_color()->CopyFrom(convertQColorToColor(color));
cmd.set_start_player_id(startZone->getPlayer()->getId());
cmd.set_start_player_id(startZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_start_zone(startZone->getName().toStdString());
cmd.set_start_card_id(startCard->getId());
if (targetCard) {
CardZone *targetZone = targetCard->getZone();
cmd.set_target_player_id(targetZone->getPlayer()->getId());
CardZoneLogic *targetZone = targetCard->getZone();
cmd.set_target_player_id(targetZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_target_zone(targetZone->getName().toStdString());
cmd.set_target_card_id(targetCard->getId());
} else {
PlayerTarget *targetPlayer = qgraphicsitem_cast<PlayerTarget *>(targetItem);
cmd.set_target_player_id(targetPlayer->getOwner()->getId());
cmd.set_target_player_id(targetPlayer->getOwner()->getPlayerInfo()->getId());
}
if (startZone->getName().compare("hand") == 0) {
startCard->playCard(false);
@ -245,7 +245,7 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
else
cmd.set_start_zone(SettingsCache::instance().getPlayToStack() ? "stack" : "table");
}
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
}
delArrow();
@ -312,22 +312,22 @@ void ArrowAttachItem::attachCards(CardItem *startCard, const CardItem *targetCar
return;
}
CardZone *startZone = startCard->getZone();
CardZone *targetZone = targetCard->getZone();
CardZoneLogic *startZone = startCard->getZone();
CardZoneLogic *targetZone = targetCard->getZone();
// move card onto table first if attaching from some other zone
if (startZone->getName() != "table") {
player->playCardToTable(startCard, false);
player->getPlayerActions()->playCardToTable(startCard, false);
}
Command_AttachCard cmd;
cmd.set_start_zone("table");
cmd.set_card_id(startCard->getId());
cmd.set_target_player_id(targetZone->getPlayer()->getId());
cmd.set_target_player_id(targetZone->getPlayer()->getPlayerInfo()->getId());
cmd.set_target_zone(targetZone->getName().toStdString());
cmd.set_target_card_id(targetCard->getId());
player->sendGameCommand(cmd);
player->getPlayerActions()->sendGameCommand(cmd);
}
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)

View file

@ -109,15 +109,16 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
sc->removeItem(this);
QList<CardDragItem *> dragItemList;
CardZone *startZone = static_cast<CardItem *>(item)->getZone();
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone))) {
CardZoneLogic *startZone = static_cast<CardItem *>(item)->getZone();
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone->getLogic()))) {
if (!occupied) {
dragItemList.append(this);
}
for (int i = 0; i < childDrags.size(); i++) {
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
if (!occupied && !(static_cast<CardItem *>(c->item)->getAttachedTo() && (startZone == currentZone)) &&
if (!occupied &&
!(static_cast<CardItem *>(c->item)->getAttachedTo() && (startZone == currentZone->getLogic())) &&
!c->occupied) {
dragItemList.append(c);
}

View file

@ -7,6 +7,7 @@
#include "../game_scene.h"
#include "../player/player.h"
#include "../zones/card_zone.h"
#include "../zones/logic/view_zone_logic.h"
#include "../zones/table_zone.h"
#include "../zones/view_zone.h"
#include "arrow_item.h"
@ -18,7 +19,7 @@
#include <QMenu>
#include <QPainter>
CardItem::CardItem(Player *_owner, QGraphicsItem *parent, const CardRef &cardRef, int _cardid, CardZone *_zone)
CardItem::CardItem(Player *_owner, QGraphicsItem *parent, const CardRef &cardRef, int _cardid, CardZoneLogic *_zone)
: AbstractCardItem(parent, cardRef, _owner, _cardid), zone(_zone), attacking(false), destroyOnZoneChange(false),
doesntUntap(false), dragItem(nullptr), attachedTo(nullptr)
{
@ -34,7 +35,7 @@ void CardItem::prepareDelete()
{
if (owner != nullptr) {
if (owner->getGame()->getActiveCard() == this) {
owner->updateCardMenu(nullptr);
owner->getPlayerMenu()->updateCardMenu(nullptr);
owner->getGame()->setActiveCard(nullptr);
}
owner = nullptr;
@ -59,7 +60,7 @@ void CardItem::deleteLater()
AbstractCardItem::deleteLater();
}
void CardItem::setZone(CardZone *_zone)
void CardItem::setZone(CardZoneLogic *_zone)
{
zone = _zone;
}
@ -184,13 +185,13 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
gridPoint.setX(-1);
attachedTo = _attachedTo;
if (attachedTo != nullptr) {
setParentItem(attachedTo->getZone());
emit attachedTo->zone->cardAdded(this);
attachedTo->addAttachedCard(this);
if (zone != attachedTo->getZone()) {
attachedTo->getZone()->reorganizeCards();
}
} else {
setParentItem(zone);
emit zone->cardAdded(this);
}
if (zone != nullptr) {
@ -259,10 +260,14 @@ void CardItem::deleteDragItem()
void CardItem::drawArrow(const QColor &arrowColor)
{
if (static_cast<TabGame *>(owner->parent())->getGameState()->isSpectator())
if (static_cast<TabGame *>(owner->parent())->getGame()->getPlayerManager()->isSpectator())
return;
Player *arrowOwner = static_cast<TabGame *>(owner->parent())->getGameState()->getActiveLocalPlayer();
Player *arrowOwner = static_cast<TabGame *>(owner->parent())
->getGame()
->getPlayerManager()
->getActiveLocalPlayer(
static_cast<TabGame *>(owner->parent())->getGame()->getGameState()->getActivePlayer());
ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor);
scene()->addItem(arrow);
arrow->grabMouse();
@ -282,7 +287,7 @@ void CardItem::drawArrow(const QColor &arrowColor)
void CardItem::drawAttachArrow()
{
if (static_cast<TabGame *>(owner->parent())->getGameState()->isSpectator())
if (static_cast<TabGame *>(owner->parent())->getGame()->getPlayerManager()->isSpectator())
return;
auto *arrow = new ArrowAttachItem(this);
@ -322,10 +327,10 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() <
2 * QApplication::startDragDistance())
return;
if (const ZoneViewZone *view = qobject_cast<const ZoneViewZone *>(zone)) {
if (const ZoneViewZoneLogic *view = qobject_cast<const ZoneViewZoneLogic *>(zone)) {
if (view->getRevealZone() && !view->getWriteableRevealZone())
return;
} else if (!owner->getLocalOrJudge())
} else if (!owner->getPlayerInfo()->getLocalOrJudge())
return;
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
@ -358,17 +363,18 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
void CardItem::playCard(bool faceDown)
{
// Do nothing if the card belongs to another player
if (!owner->getLocalOrJudge())
if (!owner->getPlayerInfo()->getLocalOrJudge())
return;
TableZone *tz = qobject_cast<TableZone *>(zone);
TableZoneLogic *tz = qobject_cast<TableZoneLogic *>(zone);
if (tz)
tz->toggleTapped();
emit tz->toggleTapped();
else {
if (SettingsCache::instance().getClickPlaysAllSelected()) {
faceDown ? zone->getPlayer()->actPlayFacedown() : zone->getPlayer()->actPlay();
faceDown ? zone->getPlayer()->getPlayerActions()->actPlayFacedown()
: zone->getPlayer()->getPlayerActions()->actPlay();
} else {
zone->getPlayer()->playCard(this, faceDown);
zone->getPlayer()->getPlayerActions()->playCard(this, faceDown);
}
}
}
@ -377,9 +383,9 @@ void CardItem::playCard(bool faceDown)
* @brief returns true if the zone is a unwritable reveal zone view (eg a card reveal window). Will return false if zone
* is nullptr.
*/
static bool isUnwritableRevealZone(CardZone *zone)
static bool isUnwritableRevealZone(CardZoneLogic *zone)
{
if (auto *view = qobject_cast<ZoneViewZone *>(zone)) {
if (auto *view = qobject_cast<ZoneViewZoneLogic *>(zone)) {
return view->getRevealZone() && !view->getWriteableRevealZone();
}
return false;
@ -395,7 +401,7 @@ void CardItem::handleClickedToPlay(bool shiftHeld)
{
if (isUnwritableRevealZone(zone)) {
if (SettingsCache::instance().getClickPlaysAllSelected()) {
zone->getPlayer()->actHide();
zone->getPlayer()->getPlayerActions()->actHide();
} else {
zone->removeCard(this);
}
@ -410,7 +416,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
if (owner != nullptr) {
owner->getGame()->setActiveCard(this);
if (QMenu *cardMenu = owner->updateCardMenu(this)) {
if (QMenu *cardMenu = owner->getPlayerMenu()->updateCardMenu(this)) {
cardMenu->popup(event->screenPos());
return;
}
@ -467,10 +473,11 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value)
if ((change == ItemSelectedHasChanged) && owner != nullptr) {
if (value == true) {
owner->getGame()->setActiveCard(this);
owner->updateCardMenu(this);
} else if (owner->scene()->selectedItems().isEmpty()) {
owner->getPlayerMenu()->updateCardMenu(this);
} else if (owner->getGameScene()->selectedItems().isEmpty()) {
owner->getGame()->setActiveCard(nullptr);
owner->updateCardMenu(nullptr);
owner->getPlayerMenu()->updateCardMenu(nullptr);
}
}
return AbstractCardItem::itemChange(change, value);

View file

@ -1,6 +1,7 @@
#ifndef CARDITEM_H
#define CARDITEM_H
#include "../zones/logic/card_zone_logic.h"
#include "abstract_card_item.h"
#include "server_card.h"
@ -21,7 +22,7 @@ class CardItem : public AbstractCardItem
{
Q_OBJECT
private:
CardZone *zone;
CardZoneLogic *zone;
bool attacking;
QMap<int, int> counters;
QString annotation;
@ -51,14 +52,14 @@ public:
QGraphicsItem *parent = nullptr,
const CardRef &cardRef = {},
int _cardid = -1,
CardZone *_zone = nullptr);
CardZoneLogic *_zone = nullptr);
void retranslateUi();
CardZone *getZone() const
CardZoneLogic *getZone() const
{
return zone;
}
void setZone(CardZone *_zone);
void setZone(CardZoneLogic *_zone);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QPoint getGridPoint() const
{

View file

@ -12,10 +12,8 @@ GeneralCounter::GeneralCounter(Player *_player,
int _radius,
int _value,
bool useNameForShortcut,
QGraphicsItem *parent,
QWidget *game)
: AbstractCounter(_player, _id, _name, true, _value, useNameForShortcut, parent, game), color(_color),
radius(_radius)
QGraphicsItem *parent)
: AbstractCounter(_player, _id, _name, true, _value, useNameForShortcut, parent), color(_color), radius(_radius)
{
setCacheMode(DeviceCoordinateCache);
}

View file

@ -18,8 +18,7 @@ public:
int _radius,
int _value,
bool useNameForShortcut = false,
QGraphicsItem *parent = nullptr,
QWidget *game = nullptr);
QGraphicsItem *parent = nullptr);
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
};

View file

@ -0,0 +1,16 @@
#ifndef COCKATRICE_GRAPHICS_ITEM_TYPE_H
#define COCKATRICE_GRAPHICS_ITEM_TYPE_H
#include <QGraphicsItem>
enum GraphicsItemType
{
typeCard = QGraphicsItem::UserType + 1,
typeCardDrag = QGraphicsItem::UserType + 2,
typeZone = QGraphicsItem::UserType + 3,
typePlayerTarget = QGraphicsItem::UserType + 4,
typeDeckViewCardContainer = QGraphicsItem::UserType + 5,
typeOther = QGraphicsItem::UserType + 6
};
#endif // COCKATRICE_GRAPHICS_ITEM_TYPE_H