mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-09 01:23:57 -07:00
Merge branch 'master' into disabledisabledartcrops
This commit is contained in:
commit
ceeedd32b4
20 changed files with 156 additions and 79 deletions
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -1,9 +1,12 @@
|
||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 💬 Discord Community (Get help with server issues, e.g. Login)
|
- name: 💬 Discord Community (Get help with server issues, e.g. Login)
|
||||||
url: https://discord.gg/3Z9yzmA
|
url: https://discord.com/invite/3Z9yzmA
|
||||||
about: Need help with using the client? Want to find some games? Try the Discord server!
|
about: Need help with using the client? Want to find some games? Try the Discord server!
|
||||||
- name: 🌐 Translations (Help improve the localization of the app)
|
- name: 🌐 Translations (Help improve the localization of the app)
|
||||||
url: https://explore.transifex.com/cockatrice/cockatrice/
|
url: https://explore.transifex.com/cockatrice/cockatrice/
|
||||||
# it is not possible to add a link to the wiki to this description
|
# it is not possible to add a link to the wiki to this description
|
||||||
about: For more information and guidance check our Translation FAQ on our wiki!
|
about: For more information and guidance check our Translation FAQ on our wiki!
|
||||||
|
- name: 📖 Code Documentation
|
||||||
|
url: https://cockatrice.github.io/docs/
|
||||||
|
about:
|
||||||
|
|
|
||||||
10
.github/workflows/desktop-build.yml
vendored
10
.github/workflows/desktop-build.yml
vendored
|
|
@ -212,7 +212,7 @@ jobs:
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
id: upload_artifact
|
id: upload_artifact
|
||||||
if: matrix.package != 'skip'
|
if: matrix.package != 'skip'
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: ${{matrix.distro}}${{matrix.version}}-package
|
name: ${{matrix.distro}}${{matrix.version}}-package
|
||||||
path: ${{steps.build.outputs.path}}
|
path: ${{steps.build.outputs.path}}
|
||||||
|
|
@ -232,7 +232,7 @@ jobs:
|
||||||
- name: Attest binary provenance
|
- name: Attest binary provenance
|
||||||
id: attestation
|
id: attestation
|
||||||
if: steps.upload_release.outcome == 'success'
|
if: steps.upload_release.outcome == 'success'
|
||||||
uses: actions/attest-build-provenance@v3
|
uses: actions/attest-build-provenance@v4
|
||||||
with:
|
with:
|
||||||
subject-name: ${{steps.build.outputs.name}}
|
subject-name: ${{steps.build.outputs.name}}
|
||||||
subject-path: ${{steps.build.outputs.path}}
|
subject-path: ${{steps.build.outputs.path}}
|
||||||
|
|
@ -499,7 +499,7 @@ jobs:
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
id: upload_artifact
|
id: upload_artifact
|
||||||
if: matrix.make_package
|
if: matrix.make_package
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: ${{matrix.artifact_name}}
|
name: ${{matrix.artifact_name}}
|
||||||
path: ${{steps.build.outputs.path}}
|
path: ${{steps.build.outputs.path}}
|
||||||
|
|
@ -507,7 +507,7 @@ jobs:
|
||||||
|
|
||||||
- name: Upload PDBs (Program Databases)
|
- name: Upload PDBs (Program Databases)
|
||||||
if: matrix.os == 'Windows'
|
if: matrix.os == 'Windows'
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Windows${{matrix.target}}-PDBs
|
name: Windows${{matrix.target}}-PDBs
|
||||||
path: |
|
path: |
|
||||||
|
|
@ -530,7 +530,7 @@ jobs:
|
||||||
- name: Attest binary provenance
|
- name: Attest binary provenance
|
||||||
id: attestation
|
id: attestation
|
||||||
if: steps.upload_release.outcome == 'success'
|
if: steps.upload_release.outcome == 'success'
|
||||||
uses: actions/attest-build-provenance@v3
|
uses: actions/attest-build-provenance@v4
|
||||||
with:
|
with:
|
||||||
subject-name: ${{steps.build.outputs.name}}
|
subject-name: ${{steps.build.outputs.name}}
|
||||||
subject-path: ${{steps.build.outputs.path}}
|
subject-path: ${{steps.build.outputs.path}}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,10 @@
|
||||||
CardDragItem::CardDragItem(CardItem *_item,
|
CardDragItem::CardDragItem(CardItem *_item,
|
||||||
int _id,
|
int _id,
|
||||||
const QPointF &_hotSpot,
|
const QPointF &_hotSpot,
|
||||||
bool _faceDown,
|
bool _forceFaceDown,
|
||||||
AbstractCardDragItem *parentDrag)
|
AbstractCardDragItem *parentDrag)
|
||||||
: AbstractCardDragItem(_item, _hotSpot, parentDrag), id(_id), faceDown(_faceDown), occupied(false), currentZone(0)
|
: AbstractCardDragItem(_item, _hotSpot, parentDrag), id(_id), forceFaceDown(_forceFaceDown), occupied(false),
|
||||||
|
currentZone(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class CardDragItem : public AbstractCardDragItem
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
int id;
|
int id;
|
||||||
bool faceDown;
|
bool forceFaceDown;
|
||||||
bool occupied;
|
bool occupied;
|
||||||
CardZone *currentZone;
|
CardZone *currentZone;
|
||||||
|
|
||||||
|
|
@ -24,15 +24,15 @@ public:
|
||||||
CardDragItem(CardItem *_item,
|
CardDragItem(CardItem *_item,
|
||||||
int _id,
|
int _id,
|
||||||
const QPointF &_hotSpot,
|
const QPointF &_hotSpot,
|
||||||
bool _faceDown,
|
bool _forceFaceDown,
|
||||||
AbstractCardDragItem *parentDrag = 0);
|
AbstractCardDragItem *parentDrag = 0);
|
||||||
int getId() const
|
int getId() const
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
bool getFaceDown() const
|
bool isForceFaceDown() const
|
||||||
{
|
{
|
||||||
return faceDown;
|
return forceFaceDown;
|
||||||
}
|
}
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||||
void updatePosition(const QPointF &cursorScenePos) override;
|
void updatePosition(const QPointF &cursorScenePos) override;
|
||||||
|
|
|
||||||
|
|
@ -212,10 +212,12 @@ void CardItem::setAttachedTo(CardItem *_attachedTo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the fields that should be reset after a zone transition
|
||||||
|
*/
|
||||||
void CardItem::resetState(bool keepAnnotations)
|
void CardItem::resetState(bool keepAnnotations)
|
||||||
{
|
{
|
||||||
attacking = false;
|
attacking = false;
|
||||||
facedown = false;
|
|
||||||
counters.clear();
|
counters.clear();
|
||||||
pt.clear();
|
pt.clear();
|
||||||
if (!keepAnnotations) {
|
if (!keepAnnotations) {
|
||||||
|
|
@ -251,10 +253,10 @@ void CardItem::processCardInfo(const ServerInfo_Card &_info)
|
||||||
setDoesntUntap(_info.doesnt_untap());
|
setDoesntUntap(_info.doesnt_untap());
|
||||||
}
|
}
|
||||||
|
|
||||||
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown)
|
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown)
|
||||||
{
|
{
|
||||||
deleteDragItem();
|
deleteDragItem();
|
||||||
dragItem = new CardDragItem(this, _id, _pos, faceDown);
|
dragItem = new CardDragItem(this, _id, _pos, forceFaceDown);
|
||||||
dragItem->setVisible(false);
|
dragItem->setVisible(false);
|
||||||
scene()->addItem(dragItem);
|
scene()->addItem(dragItem);
|
||||||
dragItem->updatePosition(_scenePos);
|
dragItem->updatePosition(_scenePos);
|
||||||
|
|
@ -352,7 +354,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
|
||||||
// Use the buttonDownPos to align the hot spot with the position when
|
// Use the buttonDownPos to align the hot spot with the position when
|
||||||
// the user originally clicked
|
// the user originally clicked
|
||||||
createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), facedown || forceFaceDown);
|
createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), forceFaceDown);
|
||||||
dragItem->grabMouse();
|
dragItem->grabMouse();
|
||||||
|
|
||||||
int childIndex = 0;
|
int childIndex = 0;
|
||||||
|
|
@ -366,8 +368,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
childPos = card->pos() - pos();
|
childPos = card->pos() - pos();
|
||||||
else
|
else
|
||||||
childPos = QPointF(childIndex * CARD_WIDTH / 2, 0);
|
childPos = QPointF(childIndex * CARD_WIDTH / 2, 0);
|
||||||
CardDragItem *drag =
|
CardDragItem *drag = new CardDragItem(card, card->getId(), childPos, forceFaceDown, dragItem);
|
||||||
new CardDragItem(card, card->getId(), childPos, card->getFaceDown() || forceFaceDown, dragItem);
|
|
||||||
drag->setPos(dragItem->pos() + childPos);
|
drag->setPos(dragItem->pos() + childPos);
|
||||||
scene()->addItem(drag);
|
scene()->addItem(drag);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ public:
|
||||||
void processCardInfo(const ServerInfo_Card &_info);
|
void processCardInfo(const ServerInfo_Card &_info);
|
||||||
|
|
||||||
bool animationEvent();
|
bool animationEvent();
|
||||||
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown);
|
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool forceFaceDown);
|
||||||
void deleteDragItem();
|
void deleteDragItem();
|
||||||
void drawArrow(const QColor &arrowColor);
|
void drawArrow(const QColor &arrowColor);
|
||||||
void drawAttachArrow();
|
void drawAttachArrow();
|
||||||
|
|
|
||||||
|
|
@ -314,9 +314,17 @@ void MessageLogWidget::logMoveCard(Player *player,
|
||||||
finalStr = tr("%1 puts %2 into play%3.");
|
finalStr = tr("%1 puts %2 into play%3.");
|
||||||
}
|
}
|
||||||
} else if (targetZoneName == GRAVE_ZONE_NAME) {
|
} else if (targetZoneName == GRAVE_ZONE_NAME) {
|
||||||
|
if (card->getFaceDown()) {
|
||||||
|
finalStr = tr("%1 puts %2%3 into their graveyard face down.");
|
||||||
|
} else {
|
||||||
finalStr = tr("%1 puts %2%3 into their graveyard.");
|
finalStr = tr("%1 puts %2%3 into their graveyard.");
|
||||||
|
}
|
||||||
} else if (targetZoneName == EXILE_ZONE_NAME) {
|
} else if (targetZoneName == EXILE_ZONE_NAME) {
|
||||||
|
if (card->getFaceDown()) {
|
||||||
|
finalStr = tr("%1 exiles %2%3 face down.");
|
||||||
|
} else {
|
||||||
finalStr = tr("%1 exiles %2%3.");
|
finalStr = tr("%1 exiles %2%3.");
|
||||||
|
}
|
||||||
} else if (targetZoneName == HAND_ZONE_NAME) {
|
} else if (targetZoneName == HAND_ZONE_NAME) {
|
||||||
finalStr = tr("%1 moves %2%3 to their hand.");
|
finalStr = tr("%1 moves %2%3 to their hand.");
|
||||||
} else if (targetZoneName == DECK_ZONE_NAME) {
|
} else if (targetZoneName == DECK_ZONE_NAME) {
|
||||||
|
|
@ -335,11 +343,19 @@ void MessageLogWidget::logMoveCard(Player *player,
|
||||||
finalStr = tr("%1 moves %2%3 to sideboard.");
|
finalStr = tr("%1 moves %2%3 to sideboard.");
|
||||||
} else if (targetZoneName == STACK_ZONE_NAME) {
|
} else if (targetZoneName == STACK_ZONE_NAME) {
|
||||||
soundEngine->playSound("play_card");
|
soundEngine->playSound("play_card");
|
||||||
|
if (card->getFaceDown()) {
|
||||||
|
finalStr = tr("%1 plays %2%3 face down.");
|
||||||
|
} else {
|
||||||
finalStr = tr("%1 plays %2%3.");
|
finalStr = tr("%1 plays %2%3.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fourthArg = targetZoneName;
|
fourthArg = targetZoneName;
|
||||||
|
if (card->getFaceDown()) {
|
||||||
|
finalStr = tr("%1 moves %2%3 to custom zone '%4' face down.");
|
||||||
|
} else {
|
||||||
finalStr = tr("%1 moves %2%3 to custom zone '%4'.");
|
finalStr = tr("%1 moves %2%3 to custom zone '%4'.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString message = finalStr.arg(sanitizeHtml(player->getPlayerInfo()->getName()), cardStr, nameFrom.second);
|
QString message = finalStr.arg(sanitizeHtml(player->getPlayerInfo()->getName()), cardStr, nameFrom.second);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,10 @@ void CardZoneLogic::addCard(CardItem *card, const bool reorganize, const int x,
|
||||||
|
|
||||||
for (auto *view : views) {
|
for (auto *view : views) {
|
||||||
if (qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->prepareAddCard(x)) {
|
if (qobject_cast<ZoneViewZoneLogic *>(view->getLogic())->prepareAddCard(x)) {
|
||||||
view->getLogic()->addCard(new CardItem(player, nullptr, card->getCardRef(), card->getId()), reorganize, x,
|
auto copy = new CardItem(player, nullptr, card->getCardRef(), card->getId());
|
||||||
y);
|
copy->setFaceDown(card->getFaceDown());
|
||||||
|
|
||||||
|
view->getLogic()->addCard(copy, reorganize, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,13 @@ void PileZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZoneL
|
||||||
cmd.set_x(0);
|
cmd.set_x(0);
|
||||||
cmd.set_y(0);
|
cmd.set_y(0);
|
||||||
|
|
||||||
for (int i = 0; i < dragItems.size(); ++i)
|
for (int i = 0; i < dragItems.size(); ++i) {
|
||||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId());
|
auto cardToMove = cmd.mutable_cards_to_move()->add_card();
|
||||||
|
cardToMove->set_card_id(dragItems[i]->getId());
|
||||||
|
if (dragItems[i]->isForceFaceDown()) {
|
||||||
|
cardToMove->set_face_down(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
@ -101,12 +106,12 @@ void PileZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
if (getLogic()->getCards().isEmpty())
|
if (getLogic()->getCards().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
||||||
bool bottomCard = event->modifiers().testFlag(Qt::ControlModifier);
|
bool bottomCard = event->modifiers().testFlag(Qt::ControlModifier);
|
||||||
CardItem *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first();
|
CardItem *card = bottomCard ? getLogic()->getCards().last() : getLogic()->getCards().first();
|
||||||
const int cardid =
|
const int cardid =
|
||||||
getLogic()->contentsKnown() ? card->getId() : (bottomCard ? getLogic()->getCards().size() - 1 : 0);
|
getLogic()->contentsKnown() ? card->getId() : (bottomCard ? getLogic()->getCards().size() - 1 : 0);
|
||||||
CardDragItem *drag = card->createDragItem(cardid, event->pos(), event->scenePos(), faceDown);
|
CardDragItem *drag = card->createDragItem(cardid, event->pos(), event->scenePos(), forceFaceDown);
|
||||||
drag->grabMouse();
|
drag->grabMouse();
|
||||||
setCursor(Qt::OpenHandCursor);
|
setCursor(Qt::OpenHandCursor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,11 @@ void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||||
|
|
||||||
for (CardDragItem *item : dragItems) {
|
for (CardDragItem *item : dragItems) {
|
||||||
if (item) {
|
if (item) {
|
||||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(item->getId());
|
auto cardToMove = cmd.mutable_cards_to_move()->add_card();
|
||||||
|
cardToMove->set_card_id(item->getId());
|
||||||
|
if (item->isForceFaceDown()) {
|
||||||
|
cardToMove->set_face_down(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,8 +134,10 @@ void TableZone::handleDropEventByGrid(const QList<CardDragItem *> &dragItems,
|
||||||
for (const auto &item : dragItems) {
|
for (const auto &item : dragItems) {
|
||||||
CardToMove *ctm = cmd.mutable_cards_to_move()->add_card();
|
CardToMove *ctm = cmd.mutable_cards_to_move()->add_card();
|
||||||
ctm->set_card_id(item->getId());
|
ctm->set_card_id(item->getId());
|
||||||
ctm->set_face_down(item->getFaceDown());
|
if (item->isForceFaceDown()) {
|
||||||
if (startZone->getName() != getLogic()->getName() && !item->getFaceDown()) {
|
ctm->set_face_down(true);
|
||||||
|
}
|
||||||
|
if (startZone->getName() != getLogic()->getName() && !item->isForceFaceDown()) {
|
||||||
const auto &card = item->getItem()->getCard();
|
const auto &card = item->getItem()->getCard();
|
||||||
if (card) {
|
if (card) {
|
||||||
ctm->set_pt(card.getInfo().getPowTough().toStdString());
|
ctm->set_pt(card.getInfo().getPowTough().toStdString());
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,10 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
|
||||||
for (int i = 0; i < cardList.size(); ++i) {
|
for (int i = 0; i < cardList.size(); ++i) {
|
||||||
auto card = cardList[i];
|
auto card = cardList[i];
|
||||||
CardRef cardRef = {QString::fromStdString(card->name()), QString::fromStdString(card->provider_id())};
|
CardRef cardRef = {QString::fromStdString(card->name()), QString::fromStdString(card->provider_id())};
|
||||||
getLogic()->addCard(new CardItem(getLogic()->getPlayer(), this, cardRef, card->id()), false, i);
|
auto copy = new CardItem(getLogic()->getPlayer(), this, cardRef, card->id());
|
||||||
|
copy->setFaceDown(card->face_down());
|
||||||
|
|
||||||
|
getLogic()->addCard(copy, false, i);
|
||||||
}
|
}
|
||||||
reorganizeCards();
|
reorganizeCards();
|
||||||
} else if (!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->contentsKnown()) {
|
} else if (!qobject_cast<ZoneViewZoneLogic *>(getLogic())->getOriginalZone()->contentsKnown()) {
|
||||||
|
|
@ -91,8 +94,10 @@ void ZoneViewZone::initializeCards(const QList<const ServerInfo_Card *> &cardLis
|
||||||
int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size());
|
int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size());
|
||||||
for (int i = 0; i < number; i++) {
|
for (int i = 0; i < number; i++) {
|
||||||
CardItem *card = c.at(i);
|
CardItem *card = c.at(i);
|
||||||
getLogic()->addCard(new CardItem(getLogic()->getPlayer(), this, card->getCardRef(), card->getId()), false,
|
auto copy = new CardItem(getLogic()->getPlayer(), this, card->getCardRef(), card->getId());
|
||||||
i);
|
copy->setFaceDown(card->getFaceDown());
|
||||||
|
|
||||||
|
getLogic()->addCard(copy, false, i);
|
||||||
}
|
}
|
||||||
reorganizeCards();
|
reorganizeCards();
|
||||||
}
|
}
|
||||||
|
|
@ -107,6 +112,7 @@ void ZoneViewZone::zoneDumpReceived(const Response &r)
|
||||||
auto cardName = QString::fromStdString(cardInfo.name());
|
auto cardName = QString::fromStdString(cardInfo.name());
|
||||||
auto cardProviderId = QString::fromStdString(cardInfo.provider_id());
|
auto cardProviderId = QString::fromStdString(cardInfo.provider_id());
|
||||||
auto card = new CardItem(getLogic()->getPlayer(), this, {cardName, cardProviderId}, cardInfo.id(), getLogic());
|
auto card = new CardItem(getLogic()->getPlayer(), this, {cardName, cardProviderId}, cardInfo.id(), getLogic());
|
||||||
|
card->setFaceDown(cardInfo.face_down());
|
||||||
getLogic()->rawInsertCard(card, i);
|
getLogic()->rawInsertCard(card, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,8 +285,13 @@ void ZoneViewZone::handleDropEvent(const QList<CardDragItem *> &dragItems,
|
||||||
cmd.set_y(0);
|
cmd.set_y(0);
|
||||||
cmd.set_is_reversed(qobject_cast<ZoneViewZoneLogic *>(getLogic())->getIsReversed());
|
cmd.set_is_reversed(qobject_cast<ZoneViewZoneLogic *>(getLogic())->getIsReversed());
|
||||||
|
|
||||||
for (int i = 0; i < dragItems.size(); ++i)
|
for (int i = 0; i < dragItems.size(); ++i) {
|
||||||
cmd.mutable_cards_to_move()->add_card()->set_card_id(dragItems[i]->getId());
|
auto cardToMove = cmd.mutable_cards_to_move()->add_card();
|
||||||
|
cardToMove->set_card_id(dragItems[i]->getId());
|
||||||
|
if (dragItems[i]->isForceFaceDown()) {
|
||||||
|
cardToMove->set_face_down(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
getLogic()->getPlayer()->getPlayerActions()->sendGameCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ CardInfoPictureArtCropWidget::CardInfoPictureArtCropWidget(QWidget *parent)
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap CardInfoPictureArtCropWidget::getProcessedBackground(const QSize &targetSize)
|
QPixmap CardInfoPictureArtCropWidget::getBackground()
|
||||||
{
|
{
|
||||||
// Load the full-resolution card image, not a pre-scaled one
|
// Load the full-resolution card image, not a pre-scaled one
|
||||||
QPixmap fullResPixmap;
|
QPixmap fullResPixmap;
|
||||||
|
|
@ -17,10 +17,8 @@ QPixmap CardInfoPictureArtCropWidget::getProcessedBackground(const QSize &target
|
||||||
} else {
|
} else {
|
||||||
CardPictureLoader::getCardBackPixmap(fullResPixmap, QSize(745, 1040));
|
CardPictureLoader::getCardBackPixmap(fullResPixmap, QSize(745, 1040));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail-safe if loading failed
|
|
||||||
if (fullResPixmap.isNull()) {
|
if (fullResPixmap.isNull()) {
|
||||||
return QPixmap(targetSize);
|
return QPixmap(); // return null qpixmap
|
||||||
}
|
}
|
||||||
|
|
||||||
const QSize sz = fullResPixmap.size();
|
const QSize sz = fullResPixmap.size();
|
||||||
|
|
@ -33,9 +31,7 @@ QPixmap CardInfoPictureArtCropWidget::getProcessedBackground(const QSize &target
|
||||||
|
|
||||||
foilRect = foilRect.intersected(fullResPixmap.rect()); // always clamp to source bounds
|
foilRect = foilRect.intersected(fullResPixmap.rect()); // always clamp to source bounds
|
||||||
|
|
||||||
// Crop first, then scale for best quality
|
// return full resolution image crop
|
||||||
QPixmap cropped = fullResPixmap.copy(foilRect);
|
QPixmap cropped = fullResPixmap.copy(foilRect);
|
||||||
QPixmap scaled = cropped.scaled(targetSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
return cropped;
|
||||||
|
|
||||||
return scaled;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ class CardInfoPictureArtCropWidget : public CardInfoPictureWidget
|
||||||
public:
|
public:
|
||||||
explicit CardInfoPictureArtCropWidget(QWidget *parent = nullptr);
|
explicit CardInfoPictureArtCropWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
// Returns a processed (cropped & scaled) version of the pixmap
|
// Returns a cropped version of the pixmap
|
||||||
QPixmap getProcessedBackground(const QSize &targetSize);
|
QPixmap getBackground();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CARD_INFO_PICTURE_ART_CROP_WIDGET_H
|
#endif // CARD_INFO_PICTURE_ART_CROP_WIDGET_H
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@
|
||||||
#include <libcockatrice/card/database/card_database_manager.h>
|
#include <libcockatrice/card/database/card_database_manager.h>
|
||||||
#include <libcockatrice/models/database/card_set/card_sets_model.h>
|
#include <libcockatrice/models/database/card_set/card_sets_model.h>
|
||||||
|
|
||||||
#define SORT_RESET -1
|
|
||||||
|
|
||||||
WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||||
{
|
{
|
||||||
setOrderIsSorted = false;
|
setOrderIsSorted = false;
|
||||||
|
|
@ -97,7 +95,6 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||||
view->setDropIndicatorShown(true);
|
view->setDropIndicatorShown(true);
|
||||||
view->setDragDropMode(QAbstractItemView::InternalMove);
|
view->setDragDropMode(QAbstractItemView::InternalMove);
|
||||||
|
|
||||||
view->sortByColumn(SetsModel::SortKeyCol, Qt::AscendingOrder);
|
|
||||||
view->setColumnHidden(SetsModel::SortKeyCol, true);
|
view->setColumnHidden(SetsModel::SortKeyCol, true);
|
||||||
view->setColumnHidden(SetsModel::IsKnownCol, true);
|
view->setColumnHidden(SetsModel::IsKnownCol, true);
|
||||||
view->setColumnHidden(SetsModel::PriorityCol, true);
|
view->setColumnHidden(SetsModel::PriorityCol, true);
|
||||||
|
|
@ -196,10 +193,10 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||||
auto headerState = SettingsCache::instance().layouts().getSetsDialogHeaderState();
|
auto headerState = SettingsCache::instance().layouts().getSetsDialogHeaderState();
|
||||||
if (!headerState.isEmpty()) {
|
if (!headerState.isEmpty()) {
|
||||||
view->header()->restoreState(headerState);
|
view->header()->restoreState(headerState);
|
||||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
|
||||||
} else {
|
} else {
|
||||||
view->header()->resizeSections(QHeaderView::ResizeToContents);
|
view->header()->resizeSections(QHeaderView::ResizeToContents);
|
||||||
}
|
}
|
||||||
|
resetSort();
|
||||||
connect(view->header(), &QHeaderView::geometriesChanged, this, &WndSets::saveHeaderState);
|
connect(view->header(), &QHeaderView::geometriesChanged, this, &WndSets::saveHeaderState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,6 +236,13 @@ void WndSets::rebuildMainLayout(int actionToTake)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WndSets::resetSort()
|
||||||
|
{
|
||||||
|
view->sortByColumn(SetsModel::SortKeyCol, Qt::AscendingOrder);
|
||||||
|
sortIndex = -1;
|
||||||
|
sortWarning->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
void WndSets::includeRebalancedCardsChanged(bool _includeRebalancedCards)
|
void WndSets::includeRebalancedCardsChanged(bool _includeRebalancedCards)
|
||||||
{
|
{
|
||||||
includeRebalancedCards = _includeRebalancedCards;
|
includeRebalancedCards = _includeRebalancedCards;
|
||||||
|
|
@ -260,9 +264,9 @@ void WndSets::actRestore()
|
||||||
|
|
||||||
void WndSets::actRestoreOriginalOrder()
|
void WndSets::actRestoreOriginalOrder()
|
||||||
{
|
{
|
||||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
|
||||||
model->restoreOriginalOrder();
|
model->restoreOriginalOrder();
|
||||||
sortWarning->setVisible(false);
|
view->selectionModel()->reset();
|
||||||
|
resetSort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WndSets::actDisableResetButton(const QString &filterString)
|
void WndSets::actDisableResetButton(const QString &filterString)
|
||||||
|
|
@ -288,11 +292,12 @@ void WndSets::actSort(int index)
|
||||||
sortIndex = index;
|
sortIndex = index;
|
||||||
sortWarning->setVisible(true);
|
sortWarning->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
resetSort();
|
||||||
sortIndex = -1;
|
|
||||||
sortWarning->setVisible(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!view->selectionModel()->selection().empty()) {
|
||||||
|
view->scrollTo(view->selectionModel()->selectedRows().first());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WndSets::actIgnoreWarning()
|
void WndSets::actIgnoreWarning()
|
||||||
|
|
@ -301,23 +306,18 @@ void WndSets::actIgnoreWarning()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
model->sort(sortIndex, sortOrder);
|
model->sort(sortIndex, sortOrder);
|
||||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
resetSort();
|
||||||
sortIndex = -1;
|
|
||||||
sortWarning->setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WndSets::actDisableSortButtons(int index)
|
void WndSets::actDisableSortButtons(int index)
|
||||||
{
|
{
|
||||||
if (index != SORT_RESET) {
|
if (index != SetsModel::SortKeyCol) {
|
||||||
view->setDragEnabled(false);
|
view->setDragEnabled(false);
|
||||||
setOrderIsSorted = true;
|
setOrderIsSorted = true;
|
||||||
} else {
|
} else {
|
||||||
setOrderIsSorted = false;
|
setOrderIsSorted = false;
|
||||||
view->setDragEnabled(true);
|
view->setDragEnabled(true);
|
||||||
}
|
}
|
||||||
if (!view->selectionModel()->selection().empty()) {
|
|
||||||
view->scrollTo(view->selectionModel()->selectedRows().first());
|
|
||||||
}
|
|
||||||
actToggleButtons(view->selectionModel()->selection(), QItemSelection());
|
actToggleButtons(view->selectionModel()->selection(), QItemSelection());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,6 @@ private:
|
||||||
QHBoxLayout *filterBox;
|
QHBoxLayout *filterBox;
|
||||||
int sortIndex;
|
int sortIndex;
|
||||||
Qt::SortOrder sortOrder;
|
Qt::SortOrder sortOrder;
|
||||||
void closeEvent(QCloseEvent *ev) override;
|
|
||||||
void saveHeaderState();
|
|
||||||
void rebuildMainLayout(int actionToTake);
|
|
||||||
bool setOrderIsSorted;
|
bool setOrderIsSorted;
|
||||||
bool includeRebalancedCards;
|
bool includeRebalancedCards;
|
||||||
enum
|
enum
|
||||||
|
|
@ -56,6 +53,11 @@ private:
|
||||||
SOME_SETS_SELECTED
|
SOME_SETS_SELECTED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void closeEvent(QCloseEvent *ev) override;
|
||||||
|
void saveHeaderState();
|
||||||
|
void rebuildMainLayout(int actionToTake);
|
||||||
|
void resetSort();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WndSets(QWidget *parent = nullptr);
|
explicit WndSets(QWidget *parent = nullptr);
|
||||||
~WndSets() override;
|
~WndSets() override;
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ void HomeWidget::initializeBackgroundFromSource()
|
||||||
cardChangeTimer->stop();
|
cardChangeTimer->stop();
|
||||||
background = QPixmap("theme:backgrounds/home");
|
background = QPixmap("theme:backgrounds/home");
|
||||||
backgroundSourceDeck = DeckList();
|
backgroundSourceDeck = DeckList();
|
||||||
|
backgroundSourceCard->setCard(ExactCard());
|
||||||
updateButtonsToBackgroundColor();
|
updateButtonsToBackgroundColor();
|
||||||
update();
|
update();
|
||||||
break;
|
break;
|
||||||
|
|
@ -138,7 +139,7 @@ void HomeWidget::updateRandomCard()
|
||||||
|
|
||||||
connect(newCard.getCardPtr().data(), &CardInfo::pixmapUpdated, this, &HomeWidget::updateBackgroundProperties);
|
connect(newCard.getCardPtr().data(), &CardInfo::pixmapUpdated, this, &HomeWidget::updateBackgroundProperties);
|
||||||
backgroundSourceCard->setCard(newCard);
|
backgroundSourceCard->setCard(newCard);
|
||||||
background = backgroundSourceCard->getProcessedBackground(size());
|
background = backgroundSourceCard->getBackground(size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HomeWidget::onBackgroundShuffleFrequencyChanged()
|
void HomeWidget::onBackgroundShuffleFrequencyChanged()
|
||||||
|
|
@ -151,7 +152,7 @@ void HomeWidget::onBackgroundShuffleFrequencyChanged()
|
||||||
|
|
||||||
void HomeWidget::updateBackgroundProperties()
|
void HomeWidget::updateBackgroundProperties()
|
||||||
{
|
{
|
||||||
background = backgroundSourceCard->getProcessedBackground(size());
|
background = backgroundSourceCard->getBackground();
|
||||||
updateButtonsToBackgroundColor();
|
updateButtonsToBackgroundColor();
|
||||||
update(); // Triggers repaint
|
update(); // Triggers repaint
|
||||||
}
|
}
|
||||||
|
|
@ -309,14 +310,17 @@ void HomeWidget::paintEvent(QPaintEvent *event)
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
background = background.scaled(size(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
if (!background.isNull()) {
|
||||||
|
QSize widgetSize = size() * devicePixelRatio();
|
||||||
|
QPixmap toDraw = background.scaled(widgetSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||||
|
|
||||||
// Draw already-scaled background centered
|
// Draw scaled background centered
|
||||||
QSize widgetSize = size();
|
QSize bgSize = toDraw.size();
|
||||||
QSize bgSize = background.size();
|
QPoint topLeft((widgetSize.width() - bgSize.width()) / (devicePixelRatio() * 2), // undo scaling for painter
|
||||||
QPoint topLeft((widgetSize.width() - bgSize.width()) / 2, (widgetSize.height() - bgSize.height()) / 2);
|
(widgetSize.height() - bgSize.height()) / (devicePixelRatio() * 2));
|
||||||
|
|
||||||
painter.drawPixmap(topLeft, background);
|
painter.drawPixmap(topLeft, toDraw);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw translucent black overlay with rounded corners
|
// Draw translucent black overlay with rounded corners
|
||||||
QRectF overlayRect(5, 5, width() - 10, height() - 10);
|
QRectF overlayRect(5, 5, width() - 10, height() - 10);
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ QVariant SetsModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case SortKeyCol:
|
case SortKeyCol:
|
||||||
return QString("%1").arg(set->getSortKey(), 8, 10, QChar('0'));
|
return QString("%1").arg(index.row(), 8, 10, QChar('0'));
|
||||||
case IsKnownCol:
|
case IsKnownCol:
|
||||||
return set->getIsKnown();
|
return set->getIsKnown();
|
||||||
case SetTypeCol:
|
case SetTypeCol:
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,35 @@ shouldDestroyOnMove(const Server_Card *card, const Server_CardZone *startZone, c
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determines whether the moved card should be face-down
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
shouldBeFaceDown(const MoveCardStruct &cardStruct, const Server_CardZone *startZone, const Server_CardZone *targetZone)
|
||||||
|
{
|
||||||
|
if (!targetZone) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// being face-down only makes sense for public zones
|
||||||
|
if (targetZone->getType() != ServerInfo_Zone::PublicZone) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// face-down property in proto takes precedence
|
||||||
|
if (cardStruct.cardToMove->has_face_down()) {
|
||||||
|
return cardStruct.cardToMove->face_down();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to keep face-down the same if zone didn't change.
|
||||||
|
// Compare using zone names because face-down is maintained when changing controllers.
|
||||||
|
if (startZone && startZone->getName() == targetZone->getName()) {
|
||||||
|
return cardStruct.card->getFaceDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges,
|
Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges,
|
||||||
Server_CardZone *startzone,
|
Server_CardZone *startzone,
|
||||||
const QList<const CardToMove *> &_cards,
|
const QList<const CardToMove *> &_cards,
|
||||||
|
|
@ -257,10 +286,7 @@ Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges,
|
||||||
|
|
||||||
for (auto cardStruct : cardsToMove) {
|
for (auto cardStruct : cardsToMove) {
|
||||||
Server_Card *card = cardStruct.card;
|
Server_Card *card = cardStruct.card;
|
||||||
const CardToMove *thisCardProperties = cardStruct.cardToMove;
|
|
||||||
int originalPosition = cardStruct.position;
|
int originalPosition = cardStruct.position;
|
||||||
bool faceDown = targetzone->hasCoords() &&
|
|
||||||
(thisCardProperties->has_face_down() ? thisCardProperties->face_down() : card->getFaceDown());
|
|
||||||
|
|
||||||
bool sourceBeingLookedAt;
|
bool sourceBeingLookedAt;
|
||||||
int position = startzone->removeCard(card, sourceBeingLookedAt);
|
int position = startzone->removeCard(card, sourceBeingLookedAt);
|
||||||
|
|
@ -315,6 +341,8 @@ Response::ResponseCode Server_AbstractPlayer::moveCard(GameEventStorage &ges,
|
||||||
++xIndex;
|
++xIndex;
|
||||||
int newX = isReversed ? targetzone->getCards().size() - xCoord + xIndex : xCoord + xIndex;
|
int newX = isReversed ? targetzone->getCards().size() - xCoord + xIndex : xCoord + xIndex;
|
||||||
|
|
||||||
|
bool faceDown = shouldBeFaceDown(cardStruct, startzone, targetzone);
|
||||||
|
|
||||||
if (targetzone->hasCoords()) {
|
if (targetzone->hasCoords()) {
|
||||||
newX = targetzone->getFreeGridColumn(newX, yCoord, card->getName(), faceDown);
|
newX = targetzone->getFreeGridColumn(newX, yCoord, card->getName(), faceDown);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ message CardToMove {
|
||||||
// Id of the card in its current zone
|
// Id of the card in its current zone
|
||||||
optional sint32 card_id = 1 [default = -1];
|
optional sint32 card_id = 1 [default = -1];
|
||||||
|
|
||||||
// Places the card face down, hiding its name
|
// If true, places the card face down, hiding its name.
|
||||||
|
// If false, forcibly turns the card face up.
|
||||||
|
// If not set, defers the resulting face down state to the server.
|
||||||
optional bool face_down = 2;
|
optional bool face_down = 2;
|
||||||
|
|
||||||
// When moving add this value to the power/toughness field of the card
|
// When moving add this value to the power/toughness field of the card
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue