mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-10 08:14:47 -07:00
Major Directory Refactoring (#5118)
* refactored cardzone.cpp, added doc and changed if to switch case * started moving every files into different folders * remove undercase to match with other files naming convention * refactored dialog files * ran format.sh * refactored client/tabs folder * refactored client/tabs folder * refactored client/tabs folder * refactored client folder * refactored carddbparser * refactored dialogs * Create sonar-project.properties temporary file for lint * Create build.yml temporary file for lint * removed all files from root directory * removed all files from root directory * added current branch to workflow * fixed most broken import * fixed issues while renaming files * fixed oracle importer * fixed dbconverter * updated translations * made sub-folders for client * removed linter * removed linter folder * fixed oracle import * revert card_zone documentation * renamed db parser files name and deck_view imports * fixed dlg file issue * ran format file and fixed test file * fixed carddb test files * moved player folder in game * updated translations and format files * fixed peglib import * format cmake files * removing vcpkg to try to add it back later * tried fixing vcpkg file * renamed filter to filters and moved database parser to cards folder * reverted translation files * reverted oracle translated * Update cockatrice/src/dialogs/dlg_register.cpp Co-authored-by: tooomm <tooomm@users.noreply.github.com> * Update cockatrice/src/client/ui/window_main.cpp Co-authored-by: tooomm <tooomm@users.noreply.github.com> * removed empty line at file start * removed useless include from tab_supervisor.cpp * refactored cardzone.cpp, added doc and changed if to switch case * started moving every files into different folders * remove undercase to match with other files naming convention * refactored dialog files * ran format.sh * refactored client/tabs folder * refactored client folder * refactored carddbparser * refactored dialogs * removed all files from root directory * Create sonar-project.properties temporary file for lint * Create build.yml temporary file for lint * added current branch to workflow * fixed most broken import * fixed issues while renaming files * fixed oracle importer * fixed dbconverter * updated translations * made sub-folders for client * removed linter * removed linter folder * fixed oracle import * revert card_zone documentation * renamed db parser files name and deck_view imports * fixed dlg file issue * ran format file and fixed test file * fixed carddb test files * moved player folder in game * updated translations and format files * fixed peglib import * reverted translation files * format cmake files * removing vcpkg to try to add it back later * tried fixing vcpkg file * pre-updating of cockatrice changes * removed empty line at file start * reverted oracle translated * Update cockatrice/src/dialogs/dlg_register.cpp Co-authored-by: tooomm <tooomm@users.noreply.github.com> * Update cockatrice/src/client/ui/window_main.cpp Co-authored-by: tooomm <tooomm@users.noreply.github.com> * removed useless include from tab_supervisor.cpp --------- Co-authored-by: tooomm <tooomm@users.noreply.github.com>
This commit is contained in:
parent
d1e0f9dfc5
commit
fa999880ee
261 changed files with 735 additions and 729 deletions
404
cockatrice/src/game/zones/table_zone.cpp
Normal file
404
cockatrice/src/game/zones/table_zone.cpp
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
#include "table_zone.h"
|
||||
|
||||
#include "../../client/ui/theme_manager.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../board/arrow_item.h"
|
||||
#include "../cards/card_database.h"
|
||||
#include "../cards/card_drag_item.h"
|
||||
#include "../cards/card_item.h"
|
||||
#include "../player/player.h"
|
||||
#include "pb/command_move_card.pb.h"
|
||||
#include "pb/command_set_card_attr.pb.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QSet>
|
||||
|
||||
const QColor TableZone::BACKGROUND_COLOR = QColor(100, 100, 100);
|
||||
const QColor TableZone::FADE_MASK = QColor(0, 0, 0, 80);
|
||||
const QColor TableZone::GRADIENT_COLOR = QColor(255, 255, 255, 150);
|
||||
const QColor TableZone::GRADIENT_COLORLESS = QColor(255, 255, 255, 0);
|
||||
|
||||
TableZone::TableZone(Player *_p, QGraphicsItem *parent)
|
||||
: SelectZone(_p, "table", true, false, true, parent), active(false)
|
||||
{
|
||||
connect(themeManager, SIGNAL(themeChanged()), this, SLOT(updateBg()));
|
||||
connect(&SettingsCache::instance(), SIGNAL(invertVerticalCoordinateChanged()), this, SLOT(reorganizeCards()));
|
||||
|
||||
updateBg();
|
||||
|
||||
height = MARGIN_TOP + MARGIN_BOTTOM + TABLEROWS * CARD_HEIGHT + (TABLEROWS - 1) * PADDING_Y;
|
||||
width = MIN_WIDTH;
|
||||
currentMinimumWidth = width;
|
||||
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
void TableZone::updateBg()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
QRectF TableZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, width, height);
|
||||
}
|
||||
|
||||
bool TableZone::isInverted() const
|
||||
{
|
||||
return ((player->getMirrored() && !SettingsCache::instance().getInvertVerticalCoordinate()) ||
|
||||
(!player->getMirrored() && SettingsCache::instance().getInvertVerticalCoordinate()));
|
||||
}
|
||||
|
||||
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
|
||||
{
|
||||
QBrush brush = themeManager->getTableBgBrush();
|
||||
|
||||
if (player->getZoneId() > 0) {
|
||||
// If the extra image is not found, load the default one
|
||||
brush = themeManager->getExtraTableBgBrush(QString::number(player->getZoneId()), brush);
|
||||
}
|
||||
painter->fillRect(boundingRect(), brush);
|
||||
|
||||
if (active) {
|
||||
paintZoneOutline(painter);
|
||||
} else {
|
||||
// inactive player gets a darker table zone with a semi transparent black mask
|
||||
// this means if the user provides a custom background it will fade
|
||||
painter->fillRect(boundingRect(), FADE_MASK);
|
||||
}
|
||||
|
||||
paintLandDivider(painter);
|
||||
}
|
||||
|
||||
/**
|
||||
Render a soft outline around the edge of the TableZone.
|
||||
|
||||
@param painter QPainter object
|
||||
*/
|
||||
void TableZone::paintZoneOutline(QPainter *painter)
|
||||
{
|
||||
QLinearGradient grad1(0, 0, 0, 1);
|
||||
grad1.setCoordinateMode(QGradient::ObjectBoundingMode);
|
||||
grad1.setColorAt(0, GRADIENT_COLOR);
|
||||
grad1.setColorAt(1, GRADIENT_COLORLESS);
|
||||
painter->fillRect(QRectF(0, 0, width, BOX_LINE_WIDTH), QBrush(grad1));
|
||||
|
||||
grad1.setFinalStop(1, 0);
|
||||
painter->fillRect(QRectF(0, 0, BOX_LINE_WIDTH, height), QBrush(grad1));
|
||||
|
||||
grad1.setStart(0, 1);
|
||||
grad1.setFinalStop(0, 0);
|
||||
painter->fillRect(QRectF(0, height - BOX_LINE_WIDTH, width, BOX_LINE_WIDTH), QBrush(grad1));
|
||||
|
||||
grad1.setStart(1, 0);
|
||||
painter->fillRect(QRectF(width - BOX_LINE_WIDTH, 0, BOX_LINE_WIDTH, height), QBrush(grad1));
|
||||
}
|
||||
|
||||
/**
|
||||
Render a division line for land placement
|
||||
|
||||
@painter QPainter object
|
||||
*/
|
||||
void TableZone::paintLandDivider(QPainter *painter)
|
||||
{
|
||||
// Place the line 2 grid heights down then back it off just enough to allow
|
||||
// some space between a 3-card stack and the land area.
|
||||
qreal separatorY = MARGIN_TOP + 2 * (CARD_HEIGHT + PADDING_Y) - STACKED_CARD_OFFSET_Y / 2;
|
||||
if (isInverted())
|
||||
separatorY = height - separatorY;
|
||||
painter->setPen(QColor(255, 255, 255, 40));
|
||||
painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
|
||||
}
|
||||
|
||||
void TableZone::addCardImpl(CardItem *card, int _x, int _y)
|
||||
{
|
||||
cards.append(card);
|
||||
card->setGridPoint(QPoint(_x, _y));
|
||||
|
||||
card->setParentItem(this);
|
||||
card->setVisible(true);
|
||||
card->update();
|
||||
}
|
||||
|
||||
void TableZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
handleDropEventByGrid(dragItems, startZone, mapToGrid(dropPoint));
|
||||
}
|
||||
|
||||
void TableZone::handleDropEventByGrid(const QList<CardDragItem *> &dragItems,
|
||||
CardZone *startZone,
|
||||
const QPoint &gridPoint)
|
||||
{
|
||||
Command_MoveCard cmd;
|
||||
cmd.set_start_player_id(startZone->getPlayer()->getId());
|
||||
cmd.set_start_zone(startZone->getName().toStdString());
|
||||
cmd.set_target_player_id(player->getId());
|
||||
cmd.set_target_zone(getName().toStdString());
|
||||
cmd.set_x(gridPoint.x());
|
||||
cmd.set_y(gridPoint.y());
|
||||
|
||||
for (const auto &item : dragItems) {
|
||||
CardToMove *ctm = cmd.mutable_cards_to_move()->add_card();
|
||||
ctm->set_card_id(item->getId());
|
||||
ctm->set_face_down(item->getFaceDown());
|
||||
if (startZone->getName() != name && !item->getFaceDown()) {
|
||||
const auto &info = item->getItem()->getInfo();
|
||||
if (info) {
|
||||
ctm->set_pt(info->getPowTough().toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startZone->getPlayer()->sendGameCommand(cmd);
|
||||
}
|
||||
|
||||
void TableZone::reorganizeCards()
|
||||
{
|
||||
QSet<ArrowItem *> arrowsToUpdate;
|
||||
|
||||
// Calculate card stack widths so mapping functions work properly
|
||||
computeCardStackWidths();
|
||||
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
QPoint gridPoint = cards[i]->getGridPos();
|
||||
if (gridPoint.x() == -1)
|
||||
continue;
|
||||
|
||||
QPointF mapPoint = mapFromGrid(gridPoint);
|
||||
qreal x = mapPoint.x();
|
||||
qreal y = mapPoint.y();
|
||||
|
||||
int numberAttachedCards = cards[i]->getAttachedCards().size();
|
||||
qreal actualX = x + numberAttachedCards * STACKED_CARD_OFFSET_X;
|
||||
qreal actualY = y;
|
||||
if (numberAttachedCards)
|
||||
actualY += 15;
|
||||
|
||||
cards[i]->setPos(actualX, actualY);
|
||||
cards[i]->setRealZValue((actualY + CARD_HEIGHT) * 100000 + (actualX + 1) * 100);
|
||||
|
||||
QListIterator<CardItem *> attachedCardIterator(cards[i]->getAttachedCards());
|
||||
int j = 0;
|
||||
while (attachedCardIterator.hasNext()) {
|
||||
++j;
|
||||
CardItem *attachedCard = attachedCardIterator.next();
|
||||
qreal childX = actualX - j * STACKED_CARD_OFFSET_X;
|
||||
qreal childY = y + 5;
|
||||
attachedCard->setPos(childX, childY);
|
||||
attachedCard->setRealZValue((childY + CARD_HEIGHT) * 100000 + (childX + 1) * 100);
|
||||
for (ArrowItem *item : attachedCard->getArrowsFrom()) {
|
||||
arrowsToUpdate.insert(item);
|
||||
}
|
||||
for (ArrowItem *item : attachedCard->getArrowsTo()) {
|
||||
arrowsToUpdate.insert(item);
|
||||
}
|
||||
}
|
||||
|
||||
for (ArrowItem *item : cards[i]->getArrowsFrom()) {
|
||||
arrowsToUpdate.insert(item);
|
||||
}
|
||||
for (ArrowItem *item : cards[i]->getArrowsTo()) {
|
||||
arrowsToUpdate.insert(item);
|
||||
}
|
||||
}
|
||||
for (ArrowItem *item : arrowsToUpdate) {
|
||||
item->updatePath();
|
||||
}
|
||||
|
||||
resizeToContents();
|
||||
update();
|
||||
}
|
||||
|
||||
void TableZone::toggleTapped()
|
||||
{
|
||||
QList<QGraphicsItem *> selectedItems = scene()->selectedItems();
|
||||
bool tapAll = false;
|
||||
for (int i = 0; i < selectedItems.size(); i++)
|
||||
if (!qgraphicsitem_cast<CardItem *>(selectedItems[i])->getTapped()) {
|
||||
tapAll = true;
|
||||
break;
|
||||
}
|
||||
QList<const ::google::protobuf::Message *> cmdList;
|
||||
for (int i = 0; i < selectedItems.size(); i++) {
|
||||
CardItem *temp = qgraphicsitem_cast<CardItem *>(selectedItems[i]);
|
||||
if (temp->getTapped() != tapAll) {
|
||||
Command_SetCardAttr *cmd = new Command_SetCardAttr;
|
||||
cmd->set_zone(name.toStdString());
|
||||
cmd->set_card_id(temp->getId());
|
||||
cmd->set_attribute(AttrTapped);
|
||||
cmd->set_attr_value(tapAll ? "1" : "0");
|
||||
cmdList.append(cmd);
|
||||
}
|
||||
}
|
||||
player->sendGameCommand(player->prepareGameCommand(cmdList));
|
||||
}
|
||||
|
||||
CardItem *TableZone::takeCard(int position, int cardId, bool canResize)
|
||||
{
|
||||
CardItem *result = CardZone::takeCard(position, cardId);
|
||||
if (canResize)
|
||||
resizeToContents();
|
||||
return result;
|
||||
}
|
||||
|
||||
void TableZone::resizeToContents()
|
||||
{
|
||||
int xMax = 0;
|
||||
|
||||
// Find rightmost card position, which includes the left margin amount.
|
||||
for (int i = 0; i < cards.size(); ++i)
|
||||
if (cards[i]->pos().x() > xMax)
|
||||
xMax = (int)cards[i]->pos().x();
|
||||
|
||||
// Minimum width is the rightmost card position plus enough room for
|
||||
// another card with padding, then margin.
|
||||
currentMinimumWidth = xMax + (2 * CARD_WIDTH) + PADDING_X + MARGIN_RIGHT;
|
||||
|
||||
if (currentMinimumWidth < MIN_WIDTH)
|
||||
currentMinimumWidth = MIN_WIDTH;
|
||||
|
||||
if (currentMinimumWidth != width) {
|
||||
prepareGeometryChange();
|
||||
width = currentMinimumWidth;
|
||||
emit sizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const
|
||||
{
|
||||
for (int i = 0; i < cards.size(); i++)
|
||||
if (cards.at(i)->getGridPoint() == gridPoint)
|
||||
return cards.at(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CardItem *TableZone::getCardFromCoords(const QPointF &point) const
|
||||
{
|
||||
QPoint gridPoint = mapToGrid(point);
|
||||
return getCardFromGrid(gridPoint);
|
||||
}
|
||||
|
||||
void TableZone::computeCardStackWidths()
|
||||
{
|
||||
// Each card stack is three grid points worth of card locations.
|
||||
// First pass: compute the number of cards at each card stack.
|
||||
QMap<int, int> cardStackCount;
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
const QPoint &gridPoint = cards[i]->getGridPos();
|
||||
if (gridPoint.x() == -1)
|
||||
continue;
|
||||
|
||||
const int key = getCardStackMapKey(gridPoint.x() / 3, gridPoint.y());
|
||||
cardStackCount.insert(key, cardStackCount.value(key, 0) + 1);
|
||||
}
|
||||
|
||||
// Second pass: compute the width at each card stack.
|
||||
cardStackWidth.clear();
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
const QPoint &gridPoint = cards[i]->getGridPos();
|
||||
if (gridPoint.x() == -1)
|
||||
continue;
|
||||
|
||||
const int key = getCardStackMapKey(gridPoint.x() / 3, gridPoint.y());
|
||||
const int stackCount = cardStackCount.value(key, 0);
|
||||
if (stackCount == 1)
|
||||
cardStackWidth.insert(key, CARD_WIDTH + cards[i]->getAttachedCards().size() * STACKED_CARD_OFFSET_X);
|
||||
else
|
||||
cardStackWidth.insert(key, CARD_WIDTH + (stackCount - 1) * STACKED_CARD_OFFSET_X);
|
||||
}
|
||||
}
|
||||
|
||||
QPointF TableZone::mapFromGrid(QPoint gridPoint) const
|
||||
{
|
||||
qreal x, y;
|
||||
|
||||
// Start with margin plus stacked card offset
|
||||
x = MARGIN_LEFT + (gridPoint.x() % 3) * STACKED_CARD_OFFSET_X;
|
||||
|
||||
// Add in width of card stack plus padding for each column
|
||||
for (int i = 0; i < gridPoint.x() / 3; ++i) {
|
||||
const int key = getCardStackMapKey(i, gridPoint.y());
|
||||
x += cardStackWidth.value(key, CARD_WIDTH) + PADDING_X;
|
||||
}
|
||||
|
||||
if (isInverted())
|
||||
gridPoint.setY(TABLEROWS - 1 - gridPoint.y());
|
||||
|
||||
// Start with margin plus stacked card offset
|
||||
y = MARGIN_TOP + (gridPoint.x() % 3) * STACKED_CARD_OFFSET_Y;
|
||||
|
||||
// Add in card size and padding for each row
|
||||
for (int i = 0; i < gridPoint.y(); ++i)
|
||||
y += CARD_HEIGHT + PADDING_Y;
|
||||
|
||||
return QPointF(x, y);
|
||||
}
|
||||
|
||||
QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
|
||||
{
|
||||
// Begin by calculating the y-coordinate of the grid space, which will be
|
||||
// used for the x-coordinate.
|
||||
|
||||
// Offset point by the margin amount to reference point within grid area.
|
||||
int y = mapPoint.y() - MARGIN_TOP;
|
||||
|
||||
// Below calculation effectively rounds to the nearest grid point.
|
||||
const int gridPointHeight = CARD_HEIGHT + PADDING_Y;
|
||||
int gridPointY = (y + PADDING_Y / 2) / gridPointHeight;
|
||||
|
||||
gridPointY = clampValidTableRow(gridPointY);
|
||||
|
||||
if (isInverted())
|
||||
gridPointY = TABLEROWS - 1 - gridPointY;
|
||||
|
||||
// Calculating the x-coordinate of the grid space requires adding up the
|
||||
// widths of each card stack along the row.
|
||||
|
||||
// Offset point by the margin amount to reference point within grid area.
|
||||
int x = mapPoint.x() - MARGIN_LEFT + PADDING_X / 2;
|
||||
|
||||
// Maximum value is a card width from the right margin, referenced to the
|
||||
// grid area.
|
||||
const int xMax = width - MARGIN_LEFT - MARGIN_RIGHT - CARD_WIDTH;
|
||||
|
||||
int xStack = 0;
|
||||
int xNextStack = 0;
|
||||
int nextStackCol = 0;
|
||||
while ((xNextStack <= x) && (xNextStack <= xMax)) {
|
||||
xStack = xNextStack;
|
||||
const int key = getCardStackMapKey(nextStackCol, gridPointY);
|
||||
xNextStack += cardStackWidth.value(key, CARD_WIDTH) + PADDING_X;
|
||||
nextStackCol++;
|
||||
}
|
||||
int stackCol = qMax(nextStackCol - 1, 0);
|
||||
|
||||
// Have the stack column, need to refine to the grid column. Take the
|
||||
// difference between the point and the stack point and divide by stacked
|
||||
// card offsets.
|
||||
int xDiff = x - xStack;
|
||||
int gridPointX = stackCol * 3 + qMin(xDiff / STACKED_CARD_OFFSET_X, 2);
|
||||
|
||||
return QPoint(gridPointX, gridPointY);
|
||||
}
|
||||
|
||||
QPointF TableZone::closestGridPoint(const QPointF &point)
|
||||
{
|
||||
QPoint gridPoint = mapToGrid(point);
|
||||
gridPoint.setX((gridPoint.x() / 3) * 3);
|
||||
if (getCardFromGrid(gridPoint))
|
||||
gridPoint.setX(gridPoint.x() + 1);
|
||||
if (getCardFromGrid(gridPoint))
|
||||
gridPoint.setX(gridPoint.x() + 1);
|
||||
return mapFromGrid(gridPoint);
|
||||
}
|
||||
|
||||
int TableZone::clampValidTableRow(const int row)
|
||||
{
|
||||
if (row < 0)
|
||||
return 0;
|
||||
if (row >= TABLEROWS)
|
||||
return TABLEROWS - 1;
|
||||
return row;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue