From 4b1c59424e1cd1feed4d838ad3e7baee18a376df Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 26 Dec 2015 19:57:20 +0100 Subject: [PATCH] Implement reverse-related tag for cards --- cockatrice/src/carddatabase.cpp | 33 +++++++++++++++++++++++++++++++-- cockatrice/src/carddatabase.h | 12 ++++++++++++ cockatrice/src/main.cpp | 3 +++ cockatrice/src/player.cpp | 28 ++++++++++++++++++++++++++-- cockatrice/src/window_main.cpp | 1 + doc/cards.xsd | 1 + oracle/src/oracleimporter.cpp | 9 ++++++--- oracle/src/oracleimporter.h | 2 +- 8 files changed, 81 insertions(+), 8 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 05fca91d..41a4976e 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -167,6 +167,7 @@ CardInfo::CardInfo(CardDatabase *_db, const QString &_text, const QStringList &_colors, const QStringList &_relatedCards, + const QStringList &_reverseRelatedCards, bool _upsideDownArt, int _loyalty, bool _cipt, @@ -186,6 +187,7 @@ CardInfo::CardInfo(CardDatabase *_db, text(_text), colors(_colors), relatedCards(_relatedCards), + reverseRelatedCards(_reverseRelatedCards), upsideDownArt(_upsideDownArt), loyalty(_loyalty), customPicURLs(_customPicURLs), @@ -298,6 +300,10 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) for (int i = 0; i < related.size(); i++) xml.writeTextElement("related", related[i]); + const QStringList &reverseRelated = info->getReverseRelatedCards(); + for (int i = 0; i < reverseRelated.size(); i++) + xml.writeTextElement("reverse-related", reverseRelated[i]); + xml.writeTextElement("manacost", info->getManaCost()); xml.writeTextElement("cmc", info->getCmc()); xml.writeTextElement("type", info->getCardType()); @@ -447,7 +453,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens) break; if (xml.name() == "card") { QString name, manacost, cmc, type, pt, text; - QStringList colors, relatedCards; + QStringList colors, relatedCards, reverseRelatedCards; QStringMap customPicURLs; MuidMap muids; SetList sets; @@ -485,6 +491,8 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens) colors << xml.readElementText(); else if (xml.name() == "related") relatedCards << xml.readElementText(); + else if (xml.name() == "reverse-related") + reverseRelatedCards << xml.readElementText(); else if (xml.name() == "tablerow") tableRow = xml.readElementText().toInt(); else if (xml.name() == "cipt") @@ -498,7 +506,7 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml, bool tokens) } if (isToken == tokens) { - addCard(new CardInfo(this, name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, upsideDown, loyalty, cipt, tableRow, sets, customPicURLs, muids)); + addCard(new CardInfo(this, name, isToken, manacost, cmc, type, pt, text, colors, relatedCards, reverseRelatedCards, upsideDown, loyalty, cipt, tableRow, sets, customPicURLs, muids)); } } } @@ -642,6 +650,27 @@ void CardDatabase::loadCustomCardDatabases(const QString &path) } } +void CardDatabase::refreshCachedReverseRelatedCards() +{ + foreach(CardInfo * card, cards) + card->resetReverseRelatedCards2Me(); + + foreach(CardInfo * card, cards) + { + if(card->getReverseRelatedCards().isEmpty()) + continue; + + QString relatedCardName = card->getName(); + foreach(QString targetCard, card->getReverseRelatedCards()) + { + if (!cards.contains(targetCard)) + continue; + + cards.value(targetCard)->addReverseRelatedCards2Me(relatedCardName); + } + } +} + QStringList CardDatabase::getAllColors() const { QSet colors; diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index ed06f64d..1cb8544a 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -78,7 +78,12 @@ private: QString powtough; QString text; QStringList colors; + // the cards i'm related to QStringList relatedCards; + // the card i'm reverse-related to + QStringList reverseRelatedCards; + // the cards thare are reverse-related to me + QStringList reverseRelatedCardsToMe; bool upsideDownArt; int loyalty; QStringMap customPicURLs; @@ -86,6 +91,7 @@ private: bool cipt; int tableRow; QString pixmapCacheKey; + public: CardInfo(CardDatabase *_db, const QString &_name = QString(), @@ -97,6 +103,7 @@ public: const QString &_text = QString(), const QStringList &_colors = QStringList(), const QStringList &_relatedCards = QStringList(), + const QStringList &_reverseRelatedCards = QStringList(), bool _upsideDownArt = false, int _loyalty = 0, bool _cipt = false, @@ -126,6 +133,10 @@ public: void setColors(const QStringList &_colors) { colors = _colors; emit cardInfoChanged(this); } const QStringList &getColors() const { return colors; } const QStringList &getRelatedCards() const { return relatedCards; } + const QStringList &getReverseRelatedCards() const { return reverseRelatedCards; } + const QStringList &getReverseRelatedCards2Me() const { return reverseRelatedCardsToMe; } + void resetReverseRelatedCards2Me() { reverseRelatedCardsToMe = QStringList(); } + void addReverseRelatedCards2Me(QString & cardName) { reverseRelatedCardsToMe.append(cardName); } bool getUpsideDownArt() const { return upsideDownArt; } QString getCustomPicURL(const QString &set) const { return customPicURLs.value(set); } int getMuId(const QString &set) const { return muIds.value(set); } @@ -216,6 +227,7 @@ public: LoadStatus getLoadStatus() const { return loadStatus; } bool getLoadSuccess() const { return loadStatus == Ok; } bool hasDetectedFirstRun(); + void refreshCachedReverseRelatedCards(); public slots: LoadStatus loadCardDatabase(const QString &path, bool tokens = false); void loadCustomCardDatabases(const QString &path); diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index cf4adb0b..10d01bfc 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -200,6 +200,9 @@ int main(int argc, char *argv[]) qDebug() << "Could not create " + dataDir + "/customsets folder."; } + // when all the cards have been loaded, resolve the reverse-related tags + db->refreshCachedReverseRelatedCards(); + if (settingsValid()) { qDebug("main(): starting main program"); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index ce33e24a..135b4056 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -1146,7 +1146,8 @@ void Player::actCreateRelatedCard() cmd.set_annotation(settingsCache->getAnnotateTokens() ? cardInfo->getText().toStdString() : QString().toStdString()); cmd.set_destroy_on_zone_change(true); cmd.set_target_zone(sourceCard->getZone()->getName().toStdString()); - cmd.set_target_card_id(sourceCard->getId()); + if(!cardInfo->getIsToken()) + cmd.set_target_card_id(sourceCard->getId()); sendGameCommand(cmd); } @@ -2362,7 +2363,8 @@ void Player::updateCardMenu(CardItem *card) cardMenu->addAction(aPeek); QStringList relatedCards = card->getInfo()->getRelatedCards(); - if(relatedCards.size()) + QStringList reverserelatedCards2Me = card->getInfo()->getReverseRelatedCards2Me(); + if(relatedCards.size() || reverserelatedCards2Me.size()) { QMenu * createRelatedCardMenu = cardMenu->addMenu(tr("Cr&eate related card")); @@ -2370,6 +2372,11 @@ void Player::updateCardMenu(CardItem *card) QAction *a = createRelatedCardMenu->addAction(relatedCards.at(i)); connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard())); } + + for (int i = 0; i < reverserelatedCards2Me.size(); ++i) { + QAction *a = createRelatedCardMenu->addAction(reverserelatedCards2Me.at(i)); + connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard())); + } } cardMenu->addSeparator(); cardMenu->addAction(aAttach); @@ -2393,6 +2400,23 @@ void Player::updateCardMenu(CardItem *card) } else if (card->getZone()->getName() == "stack") { cardMenu->addAction(aDrawArrow); cardMenu->addMenu(moveMenu); + + QStringList relatedCards = card->getInfo()->getRelatedCards(); + QStringList reverserelatedCards2Me = card->getInfo()->getReverseRelatedCards2Me(); + if(relatedCards.size() || reverserelatedCards2Me.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())); + } + + for (int i = 0; i < reverserelatedCards2Me.size(); ++i) { + QAction *a = createRelatedCardMenu->addAction(reverserelatedCards2Me.at(i)); + connect(a, SIGNAL(triggered()), this, SLOT(actCreateRelatedCard())); + } + } } else { cardMenu->addAction(aPlay); cardMenu->addAction(aPlayFacedown); diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 17eaf5ba..91a52223 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -798,6 +798,7 @@ void MainWindow::cardUpdateFinished(int, QProcess::ExitStatus) // this will force a database reload settingsCache->setCardDatabasePath(settingsCache->getCardDatabasePath()); + settingsCache->setTokenDatabasePath(settingsCache->getTokenDatabasePath()); } void MainWindow::refreshShortcuts() diff --git a/doc/cards.xsd b/doc/cards.xsd index 11a51307..1e145e32 100644 --- a/doc/cards.xsd +++ b/doc/cards.xsd @@ -35,6 +35,7 @@ + diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 8eef9a2f..7659f465 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -67,6 +67,7 @@ CardInfo *OracleImporter::addCard(const QString &setName, const QString &cardText, const QStringList & colors, const QStringList & relatedCards, + const QStringList & reverseRelatedCards, bool upsideDown ) { @@ -95,7 +96,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")); // insert the card and its properties - card = new CardInfo(this, cardName, isToken, cardCost, cmc, cardType, cardPT, cardText, colors, relatedCards, upsideDown, cardLoyalty, cipt); + card = new CardInfo(this, cardName, isToken, cardCost, cmc, cardType, cardPT, cardText, colors, relatedCards, reverseRelatedCards, upsideDown, cardLoyalty, cipt); int tableRow = 1; QString mainCardType = card->getMainCardType(); if ((mainCardType == "Land") || mArtifact) @@ -146,6 +147,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data) QString cardText; QStringList colors; QStringList relatedCards; + QStringList reverseRelatedCards; // dummy int cardId; int cardLoyalty; bool upsideDown = false; @@ -192,7 +194,7 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data) colors.clear(); extractColors(map.value("colors").toStringList(), colors); - CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cmc, cardType, cardPT, cardLoyalty, cardText, colors, relatedCards, upsideDown); + CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cmc, cardType, cardPT, cardLoyalty, cardText, colors, relatedCards, reverseRelatedCards, upsideDown); if (!set->contains(card)) { card->addToSet(set); @@ -276,10 +278,11 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data) colors.removeDuplicates(); relatedCards = QStringList(); + reverseRelatedCards = QStringList(); upsideDown = false; // add the card - CardInfo *card = addCard(set->getShortName(), cardName, false, muid, cardCost, cmc, cardType, cardPT, cardLoyalty, cardText, colors, relatedCards, upsideDown); + CardInfo *card = addCard(set->getShortName(), cardName, false, muid, cardCost, cmc, cardType, cardPT, cardLoyalty, cardText, colors, relatedCards, reverseRelatedCards, upsideDown); if (!set->contains(card)) { card->addToSet(set); diff --git a/oracle/src/oracleimporter.h b/oracle/src/oracleimporter.h index 17092ea5..6a30e65b 100644 --- a/oracle/src/oracleimporter.h +++ b/oracle/src/oracleimporter.h @@ -30,7 +30,7 @@ private: QVariantMap setsMap; 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, const QStringList & relatedCards, bool upsideDown); + 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, const QStringList & reverseRelatedCards, bool upsideDown); signals: void setIndexChanged(int cardsImported, int setIndex, const QString &setName); void dataReadProgress(int bytesRead, int totalBytes);