mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-01-09 03:42:58 -08:00
Better support Double-Faced Cards (#4753)
* Better support Double-Faced Cards This patch allows cards to be (virtually) transformed into other cards while preserving their state, essentially implemeting the MTG mechanic of the same name. On the server side, this is implemented by allowing cards to be "stashed away". A card that is stashed away is not in any zone, but is instead owned by another card. When a token is destroyed due to a zone change, if it had a card stashed away, that card is placed in the target zone instead of the token. On the database side, `attach="transform"` is used on `<reverse>` and `<reverse-related>` to indicate that the created token should be transformed this way. Old servers ignore the new field in `Command_CreateToken` and will perform a regular attachment, as currently. * Address review comments * Prevent tokens from being stashed * format.sh
This commit is contained in:
@@ -19,13 +19,18 @@
|
||||
***************************************************************************/
|
||||
#include "server_card.h"
|
||||
|
||||
#include "pb/event_set_card_attr.pb.h"
|
||||
#include "pb/event_set_card_counter.pb.h"
|
||||
#include "pb/serverinfo_card.pb.h"
|
||||
#include "server_cardzone.h"
|
||||
#include "server_player.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone)
|
||||
: zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false),
|
||||
facedown(false), color(), ptString(), annotation(), destroyOnZoneChange(false), doesntUntap(false), parentCard(0)
|
||||
facedown(false), color(), ptString(), annotation(), destroyOnZoneChange(false), doesntUntap(false), parentCard(0),
|
||||
stashedCard(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -37,6 +42,11 @@ Server_Card::~Server_Card()
|
||||
|
||||
if (parentCard)
|
||||
parentCard->removeAttachedCard(this);
|
||||
|
||||
if (stashedCard) {
|
||||
stashedCard->deleteLater();
|
||||
stashedCard = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Server_Card::resetState()
|
||||
@@ -51,11 +61,20 @@ void Server_Card::resetState()
|
||||
|
||||
QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue, bool allCards)
|
||||
{
|
||||
if (attribute == AttrTapped && avalue != "1" && allCards && doesntUntap)
|
||||
return QVariant(tapped).toString();
|
||||
|
||||
return setAttribute(attribute, avalue);
|
||||
}
|
||||
|
||||
QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue, Event_SetCardAttr *event)
|
||||
{
|
||||
if (event)
|
||||
event->set_attribute(attribute);
|
||||
|
||||
switch (attribute) {
|
||||
case AttrTapped: {
|
||||
bool value = avalue == "1";
|
||||
if (!(!value && allCards && doesntUntap))
|
||||
setTapped(value);
|
||||
setTapped(avalue == "1");
|
||||
break;
|
||||
}
|
||||
case AttrAttacking:
|
||||
@@ -69,6 +88,8 @@ QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue
|
||||
break;
|
||||
case AttrPT:
|
||||
setPT(avalue);
|
||||
if (event)
|
||||
event->set_attr_value(getPT().toStdString());
|
||||
return getPT();
|
||||
case AttrAnnotation:
|
||||
setAnnotation(avalue);
|
||||
@@ -77,15 +98,22 @@ QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue
|
||||
setDoesntUntap(avalue == "1");
|
||||
break;
|
||||
}
|
||||
if (event)
|
||||
event->set_attr_value(avalue.toStdString());
|
||||
return avalue;
|
||||
}
|
||||
|
||||
void Server_Card::setCounter(int id, int value)
|
||||
void Server_Card::setCounter(int id, int value, Event_SetCardCounter *event)
|
||||
{
|
||||
if (value)
|
||||
counters.insert(id, value);
|
||||
else
|
||||
counters.remove(id);
|
||||
|
||||
if (event) {
|
||||
event->set_counter_id(id);
|
||||
event->set_counter_value(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Server_Card::setParentCard(Server_Card *_parentCard)
|
||||
|
||||
Reference in New Issue
Block a user