Merge pull request #1134 from ctrlaltca/related_cards

Related cards
This commit is contained in:
ctrlaltca 2015-06-22 17:22:47 +02:00
commit 2415ba2605
8 changed files with 110 additions and 14 deletions

View file

@ -492,13 +492,16 @@ CardInfo::CardInfo(CardDatabase *_db,
const QString &_powtough, const QString &_powtough,
const QString &_text, const QString &_text,
const QStringList &_colors, const QStringList &_colors,
const QStringList &_relatedCards,
bool _upsideDownArt,
int _loyalty, int _loyalty,
bool _cipt, bool _cipt,
int _tableRow, int _tableRow,
const SetList &_sets, const SetList &_sets,
const QStringMap &_customPicURLs, const QStringMap &_customPicURLs,
const QStringMap &_customPicURLsHq, const QStringMap &_customPicURLsHq,
MuidMap _muIds) MuidMap _muIds
)
: db(_db), : db(_db),
name(_name), name(_name),
isToken(_isToken), isToken(_isToken),
@ -509,6 +512,8 @@ CardInfo::CardInfo(CardDatabase *_db,
powtough(_powtough), powtough(_powtough),
text(_text), text(_text),
colors(_colors), colors(_colors),
relatedCards(_relatedCards),
upsideDownArt(_upsideDownArt),
loyalty(_loyalty), loyalty(_loyalty),
customPicURLs(_customPicURLs), customPicURLs(_customPicURLs),
customPicURLsHq(_customPicURLsHq), customPicURLsHq(_customPicURLsHq),
@ -590,7 +595,13 @@ void CardInfo::loadPixmap(QPixmap &pixmap)
void CardInfo::imageLoaded(const QImage &image) void CardInfo::imageLoaded(const QImage &image)
{ {
if (!image.isNull()) { if (!image.isNull()) {
QPixmapCache::insert(pixmapCacheKey, QPixmap::fromImage(image)); if(upsideDownArt)
{
QImage mirrorImage = image.mirrored(true, true);
QPixmapCache::insert(pixmapCacheKey, QPixmap::fromImage(mirrorImage));
} else {
QPixmapCache::insert(pixmapCacheKey, QPixmap::fromImage(image));
}
emit pixmapUpdated(); emit pixmapUpdated();
} }
} }
@ -695,6 +706,10 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
for (int i = 0; i < colors.size(); i++) for (int i = 0; i < colors.size(); i++)
xml.writeTextElement("color", colors[i]); xml.writeTextElement("color", colors[i]);
const QStringList &related = info->getRelatedCards();
for (int i = 0; i < related.size(); i++)
xml.writeTextElement("related", related[i]);
xml.writeTextElement("manacost", info->getManaCost()); xml.writeTextElement("manacost", info->getManaCost());
xml.writeTextElement("cmc", info->getCmc()); xml.writeTextElement("cmc", info->getCmc());
xml.writeTextElement("type", info->getCardType()); xml.writeTextElement("type", info->getCardType());
@ -708,6 +723,8 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
xml.writeTextElement("cipt", "1"); xml.writeTextElement("cipt", "1");
if (info->getIsToken()) if (info->getIsToken())
xml.writeTextElement("token", "1"); xml.writeTextElement("token", "1");
if (info->getUpsideDownArt())
xml.writeTextElement("upsidedown", "1");
xml.writeEndElement(); // card xml.writeEndElement(); // card
return xml; return xml;
@ -862,7 +879,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens)
break; break;
if (xml.name() == "card") { if (xml.name() == "card") {
QString name, manacost, cmc, type, pt, text; QString name, manacost, cmc, type, pt, text;
QStringList colors; QStringList colors, relatedCards;
QStringMap customPicURLs, customPicURLsHq; QStringMap customPicURLs, customPicURLsHq;
MuidMap muids; MuidMap muids;
SetList sets; SetList sets;
@ -870,6 +887,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens)
int loyalty = 0; int loyalty = 0;
bool cipt = false; bool cipt = false;
bool isToken = false; bool isToken = false;
bool upsideDown = false;
while (!xml.atEnd()) { while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::EndElement) if (xml.readNext() == QXmlStreamReader::EndElement)
break; break;
@ -900,10 +918,14 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens)
} }
} else if (xml.name() == "color") } else if (xml.name() == "color")
colors << xml.readElementText(); colors << xml.readElementText();
else if (xml.name() == "related")
relatedCards << xml.readElementText();
else if (xml.name() == "tablerow") else if (xml.name() == "tablerow")
tableRow = xml.readElementText().toInt(); tableRow = xml.readElementText().toInt();
else if (xml.name() == "cipt") else if (xml.name() == "cipt")
cipt = (xml.readElementText() == "1"); cipt = (xml.readElementText() == "1");
else if (xml.name() == "upsidedown")
upsideDown = (xml.readElementText() == "1");
else if (xml.name() == "loyalty") else if (xml.name() == "loyalty")
loyalty = xml.readElementText().toInt(); loyalty = xml.readElementText().toInt();
else if (xml.name() == "token") else if (xml.name() == "token")
@ -911,7 +933,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens)
} }
if (isToken == tokens) { if (isToken == tokens) {
addCard(new CardInfo(this, name, isToken, manacost, cmc, type, pt, text, colors, loyalty, cipt, tableRow, sets, customPicURLs, customPicURLsHq, muids)); addCard(new CardInfo(this, name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, upsideDown, loyalty, cipt, tableRow, sets, customPicURLs, customPicURLsHq, muids));
} }
} }
} }

View file

@ -132,6 +132,8 @@ private:
QString powtough; QString powtough;
QString text; QString text;
QStringList colors; QStringList colors;
QStringList relatedCards;
bool upsideDownArt;
int loyalty; int loyalty;
QStringMap customPicURLs, customPicURLsHq; QStringMap customPicURLs, customPicURLsHq;
MuidMap muIds; MuidMap muIds;
@ -148,13 +150,16 @@ public:
const QString &_powtough = QString(), const QString &_powtough = QString(),
const QString &_text = QString(), const QString &_text = QString(),
const QStringList &_colors = QStringList(), const QStringList &_colors = QStringList(),
const QStringList &_relatedCards = QStringList(),
bool _upsideDownArt = false,
int _loyalty = 0, int _loyalty = 0,
bool _cipt = false, bool _cipt = false,
int _tableRow = 0, int _tableRow = 0,
const SetList &_sets = SetList(), const SetList &_sets = SetList(),
const QStringMap &_customPicURLs = QStringMap(), const QStringMap &_customPicURLs = QStringMap(),
const QStringMap &_customPicURLsHq = QStringMap(), const QStringMap &_customPicURLsHq = QStringMap(),
MuidMap muids = MuidMap()); MuidMap muids = MuidMap()
);
~CardInfo(); ~CardInfo();
const QString &getName() const { return name; } const QString &getName() const { return name; }
const QString &getSimpleName() const { return simpleName; } const QString &getSimpleName() const { return simpleName; }
@ -174,6 +179,8 @@ public:
void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); } void setText(const QString &_text) { text = _text; emit cardInfoChanged(this); }
void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); } void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); }
const QStringList &getColors() const { return colors; } const QStringList &getColors() const { return colors; }
const QStringList &getRelatedCards() const { return relatedCards; }
bool getUpsideDownArt() const { return upsideDownArt; }
QString getCustomPicURL(const QString &set) const { return customPicURLs.value(set); } QString getCustomPicURL(const QString &set) const { return customPicURLs.value(set); }
QString getCustomPicURLHq(const QString &set) const { return customPicURLsHq.value(set); } QString getCustomPicURLHq(const QString &set) const { return customPicURLsHq.value(set); }
int getMuId(const QString &set) const { return muIds.value(set); } int getMuId(const QString &set) const { return muIds.value(set); }

View file

@ -676,7 +676,7 @@ void Player::retranslateUi()
for (int i = 0; i < allPlayersActions.size(); ++i) for (int i = 0; i < allPlayersActions.size(); ++i)
allPlayersActions[i]->setText(tr("&All players")); allPlayersActions[i]->setText(tr("&All players"));
} }
aPlay->setText(tr("&Play")); aPlay->setText(tr("&Play"));
aHide->setText(tr("&Hide")); aHide->setText(tr("&Hide"));
aPlayFacedown->setText(tr("Play &Face Down")); aPlayFacedown->setText(tr("Play &Face Down"));
@ -1076,6 +1076,30 @@ void Player::actCreatePredefinedToken()
actCreateAnotherToken(); actCreateAnotherToken();
} }
void Player::actCreateRelatedCard()
{
// get the clicked card
CardItem * sourceCard = game->getActiveCard();
if(!sourceCard)
return;
// get the target card name
QAction *action = static_cast<QAction *>(sender());
CardInfo *cardInfo = db->getCard(action->text());
// create the token for the related card
Command_CreateToken cmd;
cmd.set_zone("table");
cmd.set_card_name(cardInfo->getName().toStdString());
cmd.set_color(cardInfo->getColors().isEmpty() ? QString().toStdString() : cardInfo->getColors().first().toLower().toStdString());
cmd.set_pt(cardInfo->getPowTough().toStdString());
cmd.set_destroy_on_zone_change(true);
cmd.set_target_zone(sourceCard->getZone()->getName().toStdString());
cmd.set_target_card_id(sourceCard->getId());
sendGameCommand(cmd);
}
void Player::actSayMessage() void Player::actSayMessage()
{ {
QAction *a = qobject_cast<QAction *>(sender()); QAction *a = qobject_cast<QAction *>(sender());
@ -2247,6 +2271,17 @@ void Player::updateCardMenu(CardItem *card)
cardMenu->addAction(aFlip); cardMenu->addAction(aFlip);
if (card->getFaceDown()) if (card->getFaceDown())
cardMenu->addAction(aPeek); cardMenu->addAction(aPeek);
QStringList relatedCards = card->getInfo()->getRelatedCards();
if(relatedCards.size())
{
QMenu * createRelatedCardMenu = cardMenu->addMenu(tr("Cr&eate related card"));
for (int i = 0; i < relatedCards.size(); ++i) {
QAction *a = createRelatedCardMenu->addAction(relatedCards.at(i));
connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard()));
}
}
cardMenu->addSeparator(); cardMenu->addSeparator();
cardMenu->addAction(aAttach); cardMenu->addAction(aAttach);
if (card->getAttachedTo()) if (card->getAttachedTo())

View file

@ -141,6 +141,7 @@ private slots:
void actOpenDeckInDeckEditor(); void actOpenDeckInDeckEditor();
void actCreatePredefinedToken(); void actCreatePredefinedToken();
void actCreateRelatedCard();
void cardMenuAction(); void cardMenuAction();
void actCardCounterTrigger(); void actCardCounterTrigger();
void actAttach(); void actAttach();

View file

@ -11,6 +11,8 @@ message Command_CreateToken {
optional bool destroy_on_zone_change = 6; optional bool destroy_on_zone_change = 6;
optional sint32 x = 7; optional sint32 x = 7;
optional sint32 y = 8; optional sint32 y = 8;
optional string target_zone = 9;
optional sint32 target_card_id = 10 [default = -1];
} }

View file

@ -1065,7 +1065,7 @@ Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cm
return Response::RespOk; return Response::RespOk;
} }
Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer & rc, GameEventStorage &ges)
{ {
if (spectator) if (spectator)
return Response::RespFunctionNotAllowed; return Response::RespFunctionNotAllowed;
@ -1109,8 +1109,20 @@ Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &
event.set_x(x); event.set_x(x);
event.set_y(y); event.set_y(y);
ges.enqueueGameEvent(event, playerId); ges.enqueueGameEvent(event, playerId);
return Response::RespOk; // chck if the token is a replacement for an existing card
if(cmd.target_card_id() < 0)
return Response::RespOk;
Command_AttachCard cmd2;
cmd2.set_start_zone(cmd.target_zone());
cmd2.set_card_id(cmd.target_card_id());
cmd2.set_target_player_id(zone->getPlayer()->getPlayerId());
cmd2.set_target_zone(cmd.zone());
cmd2.set_target_card_id(card->getId());
return cmdAttachCard(cmd2, rc, ges);
} }
Response::ResponseCode Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) Response::ResponseCode Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges)

View file

@ -65,7 +65,10 @@ CardInfo *OracleImporter::addCard(const QString &setName,
const QString &cardPT, const QString &cardPT,
int cardLoyalty, int cardLoyalty,
const QString &cardText, const QString &cardText,
const QStringList & colors) const QStringList & colors,
const QStringList & relatedCards,
bool upsideDown
)
{ {
QStringList cardTextRows = cardText.split("\n"); QStringList cardTextRows = cardText.split("\n");
bool splitCard = false; bool splitCard = false;
@ -97,7 +100,7 @@ CardInfo *OracleImporter::addCard(const QString &setName,
bool cipt = cardText.contains("Hideaway") || (cardText.contains(cardName + " enters the battlefield tapped") && !cardText.contains(cardName + " enters the battlefield tapped unless")); bool cipt = cardText.contains("Hideaway") || (cardText.contains(cardName + " enters the battlefield tapped") && !cardText.contains(cardName + " enters the battlefield tapped unless"));
card = new CardInfo(this, cardName, isToken, cardCost, cmc, cardType, cardPT, cardText, colors, cardLoyalty, cipt); card = new CardInfo(this, cardName, isToken, cardCost, cmc, cardType, cardPT, cardText, colors, relatedCards, upsideDown, cardLoyalty, cipt);
int tableRow = 1; int tableRow = 1;
QString mainCardType = card->getMainCardType(); QString mainCardType = card->getMainCardType();
if ((mainCardType == "Land") || mArtifact) if ((mainCardType == "Land") || mArtifact)
@ -147,9 +150,11 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
QString cardPT; QString cardPT;
QString cardText; QString cardText;
QStringList colors; QStringList colors;
QStringList relatedCards;
int cardId; int cardId;
int cardLoyalty; int cardLoyalty;
bool cardIsToken = false; bool cardIsToken = false;
bool upsideDown = false;
QMap<int, QVariantMap> splitCards; QMap<int, QVariantMap> splitCards;
while (it.hasNext()) { while (it.hasNext()) {
@ -169,7 +174,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
cardLoyalty = 0; cardLoyalty = 0;
// determine which subcard is the first one in the split // determine which subcard is the first one in the split
QStringList names=map.contains("names") ? map.value("names").toStringList() : QStringList(""); QStringList names=map.contains("names") ? map.value("names").toStringList() : QStringList();
if(names.count()>0 && if(names.count()>0 &&
map.contains("name") && map.contains("name") &&
0 == QString::compare(map.value("name").toString(), names.at(0))) 0 == QString::compare(map.value("name").toString(), names.at(0)))
@ -204,6 +209,8 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
extractColors(card2->value("colors").toStringList(), colors); extractColors(card2->value("colors").toStringList(), colors);
colors.removeDuplicates(); colors.removeDuplicates();
relatedCards = QStringList();
upsideDown = false;
} else { } else {
// first card of a pair; enqueue for later merging // first card of a pair; enqueue for later merging
// Conditional on cardId because promo prints have no muid - see #640 // Conditional on cardId because promo prints have no muid - see #640
@ -222,6 +229,16 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0; cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0; cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0;
cardIsToken = map.value("layout") == "token"; cardIsToken = map.value("layout") == "token";
relatedCards = map.contains("names") ? map.value("names").toStringList() : QStringList();
relatedCards.removeAll(cardName);
if(0 == QString::compare(map.value("layout").toString(), QString("flip"), Qt::CaseInsensitive))
{
QStringList cardNames = map.contains("names") ? map.value("names").toStringList() : QStringList();
upsideDown = (cardNames.indexOf(cardName) > 0);
} else {
upsideDown = false;
}
colors.clear(); colors.clear();
extractColors(map.value("colors").toStringList(), colors); extractColors(map.value("colors").toStringList(), colors);
@ -233,7 +250,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
} }
if (!cardIsToken) { if (!cardIsToken) {
CardInfo *card = addCard(set->getShortName(), cardName, cardIsToken, cardId, cardCost, cmc, cardType, cardPT, cardLoyalty, cardText, colors); CardInfo *card = addCard(set->getShortName(), cardName, cardIsToken, cardId, cardCost, cmc, cardType, cardPT, cardLoyalty, cardText, colors, relatedCards, upsideDown);
if (!set->contains(card)) { if (!set->contains(card)) {
card->addToSet(set); card->addToSet(set);

View file

@ -29,7 +29,7 @@ private:
QVariantMap setsMap; QVariantMap setsMap;
QString dataDir; QString dataDir;
CardInfo *addCard(const QString &setName, QString cardName, bool isToken, int cardId, QString &cardCost, QString &cmc, const QString &cardType, const QString &cardPT, int cardLoyalty, const QString &cardText, const QStringList & colors); CardInfo *addCard(const QString &setName, QString cardName, bool isToken, int cardId, QString &cardCost, QString &cmc, const QString &cardType, const QString &cardPT, int cardLoyalty, const QString &cardText, const QStringList & colors, const QStringList & relatedCards, bool upsideDown);
signals: signals:
void setIndexChanged(int cardsImported, int setIndex, const QString &setName); void setIndexChanged(int cardsImported, int setIndex, const QString &setName);
void dataReadProgress(int bytesRead, int totalBytes); void dataReadProgress(int bytesRead, int totalBytes);