From 76f1591b585b6ca16d55af585a962152d0262e48 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Mon, 4 Jul 2016 10:43:07 -0400 Subject: [PATCH 1/9] removed WParsedInt "morethanfour", "plusone","plustwo","plusthree" added 2 things first plus/plusend, minus/minusend written many ways damage:type:*:myhandminus2minusend would deal damage equal to the cards in my hand -2 damage:type:creature:mybattlefieldplustype:creature:opponentbattlefieldplusend damage equal to the number of creatures in my battlefield plus the number of creatures in opponents battlefield. now there are special cases where we need to know the value BEFORE applying multipliers. life: is one of them. I added "math/mathend" auto=@each opponent upkeep:target(opponent) life:-mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent in the example above, without "math" the "-" would be used for the first section of the minus parsed int, instead of being applied as a multiplier for the total of the number. this is extremely flexible, and can contain any Wparsed int in both parts, you can add or subtract and use the differences between to values as the value of the parsedInt. --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 62 ++++++-- projects/mtg/include/AllAbilities.h | 150 ++++++++++--------- 2 files changed, 132 insertions(+), 80 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 1a3d0d5ce..8b3661598 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1032,7 +1032,7 @@ type=Enchantment [/card] [card] name=AEther Burst -target=creature|battlefield +target=creature|battlefield auto=moveto(ownerhand) text=Return up to X target creatures to their owners' hands, where X is one plus the number of cards named AEther Burst in all graveyards as you cast AEther Burst. mana={1}{U} @@ -3666,7 +3666,7 @@ toughness=1+* [/card] [card] name=An-Havva Inn -auto=life:plusonetype:creature[green]|battlefield controller +auto=life:type:creature[green]|battlefieldplus1plusend controller text=You gain X plus 1 life, where X is the number of green creatures on the battlefield. mana={1}{G}{G} type=Sorcery @@ -10107,7 +10107,7 @@ type=Sorcery [card] name=Black Vise auto=name(choose opponent) notatarget(opponent) deplete:0 -auto=@each targetedplayer upkeep:damage:morethanfourcards targetedplayer +auto=@each targetedplayer upkeep:damage:type:*:opponenthandminus4minusend targetedplayer text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={1} type=Artifact @@ -54292,7 +54292,7 @@ type=Artifact [/card] [card] name=Iron Maiden -auto=@each opponent upkeep:damage:morethanfourcards opponent +auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent text=At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={3} type=Artifact @@ -57844,7 +57844,7 @@ type=Instant [card] name=Kindle target=creature,player -auto=damage:plustwotype:kindle:graveyard +auto=damage:type:kindle:graveyardplus2plusend text=Kindle deals X damage to target creature or player, where X is 2 plus the number of cards named Kindle in all graveyards. mana={1}{R} type=Instant @@ -61435,7 +61435,7 @@ toughness=5 [card] name=Lhurgoyf alias=1111 -anyzone=type:creature:graveyard/plusonetype:creature:graveyard cdaactive +anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. mana={2}{G}{G} type=Creature @@ -68000,7 +68000,7 @@ type=Legendary Land [card] name=Mind Burst target=player -auto=ability$!name(discard) target(*|myhand) reject!$ targetedplayer +auto=ability$!name(discard) target(*|myhandplus1plusend) reject!$ targetedplayer text=Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards. mana={1}{B} type=Sorcery @@ -109175,7 +109175,7 @@ toughness=7 [/card] [card] name=Tarmogoyf -anyzone=gravecardtypes/plusonegravecardtypes cdaactive +anyzone=gravecardtypes/gravecardtypesplus1plusend cdaactive text=Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (The card types are artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal.) mana={1}{G} type=Creature @@ -119960,7 +119960,7 @@ toughness=3 [/card] [card] name=Viseling -auto=@each opponent upkeep:damage:morethanfourcards opponent +auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent text=At the beginning of each opponent's upkeep, Viseling deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={4} type=Artifact Creature @@ -120035,7 +120035,7 @@ type=Instant [/card] [card] name=Vitalizing Cascade -auto=life:Xplusthree +auto=life:Xplus3plusend text=You gain X plus 3 life. mana={X}{G}{W} type=Instant @@ -121775,7 +121775,7 @@ toughness=4 [card] name=Wall of Tombstones abilities=defender -auto=@each my upkeep:transforms((,settoughness=plusonetype:creature:mygraveyard)) forever +auto=@each my upkeep:transforms((,settoughness=type:creature:mygraveyardplus1plusend)) forever text=Defender (This creature can't attack.) -- At the beginning of your upkeep, Wall of Tombstones's toughness becomes 1 plus the number of creature cards in your graveyard. (This effect lasts indefinitely.) mana={1}{B} type=Creature @@ -127351,6 +127351,46 @@ subtype=Orc Warrior power=7 toughness=2 [/card] +###### +######unsorted +[card] +name=Dark Suspicions +auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] +name=Bulwark +auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] +name=Roiling Horror +anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive +autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +suspend(0)={X}{b}{b}{b} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] +name=Dark Deal +auto=count(type:*:myhand) +auto=all(*|myhand) reject +auto=draw:countedamountplus1plusend controller +auto=count(type:*:opponenthand) +auto=all(*|opponenthand) reject +auto=draw:countedamountplus1plusend opponent +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 5a652b823..a7045d5e9 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -179,10 +179,8 @@ private: bool halfdown = false; bool twice = false; bool thrice = false; - bool plusone = false; - bool plustwo = false; - bool plusthree = false; bool other = false;//othertype:[subtype] + if (!target) target = card; int multiplier = 1; if (s[0] == '-') @@ -231,24 +229,7 @@ private: size_t tXXX = s.find("thrice"); s.erase(tXXX,tXXX + 6); } - if(s.find("plusone") != string::npos) - { - plusone = true; - size_t pOne = s.find("plusone"); - s.erase(pOne,pOne + 7); - } - if(s.find("plustwo") != string::npos) - { - plustwo = true; - size_t pTwo = s.find("plustwo"); - s.erase(pTwo,pTwo + 7); - } - if(s.find("plusthree") != string::npos) - { - plusthree = true; - size_t pThree = s.find("plusthree"); - s.erase(pThree,pThree + 9); - } + if(s.find("othertype") != string::npos) { other = true; @@ -273,7 +254,47 @@ private: size_t otc = s.find("otherconvertedcost"); s.erase(otc,otc + 5); } - if(s == "prex") + + if (s.find("plusend") != string::npos || s.find("minusend") != string::npos || s.find("math") != string::npos) + { + //plus#plusend and minus#minusend splits the first part and second parts and parses the + //ints for each part, then either adds or subtracts those 2 variables as specified. + vectormathFound = parseBetween(s, "math", "mathend", true); + if (mathFound.size())//maths allows us to get the value before applying multipliers + { + WParsedInt numPar(mathFound[1], NULL, card); + intValue = numPar.getValue(); + + } + else + { + vectorplusSplit = parseBetween(s, "", "plus", true); + if (plusSplit.size()) + { + WParsedInt numPar(plusSplit[1], NULL, card); + intValue = numPar.getValue(); + } + vectorplusFound = parseBetween(s, "plus", "plusend", true); + if (plusFound.size()) + { + WParsedInt numPar(plusFound[1], NULL, card); + intValue += numPar.getValue(); + } + vectorminusSplit = parseBetween(s, "", "minus", true); + if (minusSplit.size()) + { + WParsedInt numPar(minusSplit[1], NULL, card); + intValue = numPar.getValue(); + } + vectorminusFound = parseBetween(s, "minus", "minusend", true); + if (minusFound.size()) + { + WParsedInt numPar(minusFound[1], NULL, card); + intValue -= numPar.getValue(); + } + } + } + else if(s == "prex") { if (card->setX > -1) { @@ -806,12 +827,18 @@ private: else if (s == "pbasiclandtypes")//Basic Land types { MTGGameZone * checkZone = card->controller()->inPlay(); - intValue = - cardHasTypeinZone("forest",checkZone) + - cardHasTypeinZone("plains",checkZone) + - cardHasTypeinZone("swamp",checkZone) + - cardHasTypeinZone("island",checkZone) + - cardHasTypeinZone("mountain",checkZone); + intValue = //mtg rules 205.4c + cardHasTypeinZone("waste", checkZone) + + cardHasTypeinZone("forest", checkZone) + + cardHasTypeinZone("plains", checkZone) + + cardHasTypeinZone("swamp", checkZone) + + cardHasTypeinZone("island", checkZone) + + cardHasTypeinZone("mountain", checkZone) + + cardHasTypeinZone("snow-covered forest", checkZone) + + cardHasTypeinZone("snow-covered plains", checkZone) + + cardHasTypeinZone("snow-covered swamp", checkZone) + + cardHasTypeinZone("snow-covered island", checkZone) + + cardHasTypeinZone("snow-covered mountain", checkZone); } else if (s == "myname")//Name of the card you control { @@ -858,13 +885,6 @@ private: cardHasTypeinZone("artifact",checkZone); } } - else if (s == "morethanfourcards") - { - intValue = 0; - int damage = card->playerTarget ? card->playerTarget->game->hand->nb_cards - 4 : card->controller()->opponent()->game->hand->nb_cards - 4; - if ( damage > 0 ) - intValue = damage; - } else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable { intValue = 0; @@ -889,42 +909,34 @@ private: if (card->revealedLast) intValue = card->revealedLast->getManaCost()->getConvertedCost(); } - else + else if(!intValue)//found nothing, try parsing a atoi { intValue = atoi(s.c_str()); - } - if(intValue > 0) - { - if(halfup) - { - if(intValue%2 == 1) - intValue++; - intValue = intValue/2; - } - if(halfdown) - intValue = intValue/2; - if(twice) - intValue = intValue*2; - if(thrice) - intValue = intValue*3; - if(plusone) - intValue = intValue+1; - if(plustwo) - intValue = intValue+2; - if(plusthree) - intValue = intValue+3; - } - else - { - if(plusone) - intValue = intValue+1; - if(plustwo) - intValue = intValue+2; - if(plusthree) - intValue = intValue+3; - } - intValue *= multiplier; - } + } + if (intValue > 0)//dont divide by 0 the rest are valid. + { + if (halfup) + { + if (intValue % 2 == 1) + intValue++; + intValue = intValue / 2; + } + if (halfdown) + intValue = intValue / 2; + } + if (twice) + intValue = intValue * 2; + if (thrice) + intValue = intValue * 3; + if (intValue < 0) + { + //we remove "-" at the start and are parsing for real values. + //if we ended up with a value less than 0, then we return just 0 + intValue = 0; + } + + intValue *= multiplier; + } public: int countDevotionTo(MTGCardInstance * card, MTGGameZone * zone, int color1, int color2) From 2b8f1b350c3971cbc1d88a72c343c887bbfc5232 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Mon, 4 Jul 2016 11:18:07 -0400 Subject: [PATCH 2/9] added bonus events for eldrazi and werewolves --- projects/mtg/include/MTGRules.h | 4 ++++ projects/mtg/src/MTGRules.cpp | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 355932ccf..084273425 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -58,6 +58,10 @@ public: int Angel[2]; bool dragonbonusgranted[2]; int dragon[2]; + bool eldrazibonusgranted[2]; + int eldrazi[2]; + bool werewolfbonusgranted[2]; + int werewolf[2]; int receiveEvent(WEvent * event); void grantAward(string awardName,int amount); diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 753cf3a1f..6d61dc687 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -49,6 +49,10 @@ PermanentAbility(observer, _id) Angel[i] = 0; dragonbonusgranted[i] = false; dragon[i] = 0; + eldrazibonusgranted[i] = false; + eldrazi[i] = 0; + werewolfbonusgranted[i] = false; + werewolf[i] = 0; } } @@ -171,6 +175,10 @@ int MTGEventBonus::receiveEvent(WEvent * event) Angel[currentPlayer->getId()]++; if(e->card->hasType("dragon")||e->card->hasType("wurm")||e->card->hasType("drake")||e->card->hasType("snake")||e->card->hasType("hydra")) dragon[currentPlayer->getId()]++; + if (e->card->hasType("eldrazi")) + eldrazi[currentPlayer->getId()]++; + if (e->card->hasType("werewolf") || e->card->hasType("wolf")) + werewolf[currentPlayer->getId()]++; } if(toys[currentPlayer->getId()] > 30 && !toybonusgranted[currentPlayer->getId()]) { @@ -228,6 +236,16 @@ int MTGEventBonus::receiveEvent(WEvent * event) grantAward("Teeth And Scales!",300); dragonbonusgranted[currentPlayer->getId()] = true; } + if (eldrazi[currentPlayer->getId()] > 30 && !eldrazibonusgranted[currentPlayer->getId()]) + { + grantAward("Colorblind!", 300); + eldrazibonusgranted[currentPlayer->getId()] = true; + } + if (werewolf[currentPlayer->getId()] > 30 && !werewolfbonusgranted[currentPlayer->getId()]) + { + grantAward("Full Moon!", 300); + werewolfbonusgranted[currentPlayer->getId()] = true; + } } } //bonus for dealing 100+ damage from a single source From c018e3dcc241d8c56c4628733406d567fbe511d0 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Mon, 4 Jul 2016 15:13:35 -0400 Subject: [PATCH 3/9] fixed a ton of memleaks, narrowed down the memleaks to just the computeNewCost function. still working on a fix for this. --- projects/mtg/src/AllAbilities.cpp | 2 + projects/mtg/src/Damage.cpp | 2 +- projects/mtg/src/MTGCardInstance.cpp | 30 +++---- projects/mtg/src/MTGRules.cpp | 116 ++++++++++++++------------- projects/mtg/src/ManaCost.cpp | 26 +++--- 5 files changed, 95 insertions(+), 81 deletions(-) diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index a5b673f3a..bb3c3f39d 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1319,6 +1319,7 @@ int AACopier::resolve() MTGCard* clone = MTGCollection()->getCardById(_target->copiedID); MTGCardInstance * myClone = NEW MTGCardInstance(clone, source->controller()->game); source->copy(myClone); + SAFE_DELETE(myClone); source->isACopier = true; source->copiedID = _target->getMTGId(); source->modifiedbAbi = _target->modifiedbAbi; @@ -6133,6 +6134,7 @@ int AProduceMana::produce() { AManaProducer *amp = NEW AManaProducer(game, game->mLayers->actionLayer()->getMaxId(), source, source->controller(), ManaCost::parseManaCost(ManaDescription,NULL,source), NULL, 0,"",false); amp->resolve(); + SAFE_DELETE(amp);//once you call resolve() on a ability, you can safely delete it. } return 1; } diff --git a/projects/mtg/src/Damage.cpp b/projects/mtg/src/Damage.cpp index 9177b442d..b5a94633c 100644 --- a/projects/mtg/src/Damage.cpp +++ b/projects/mtg/src/Damage.cpp @@ -251,7 +251,7 @@ int Damage::resolve() target->lifeLostThisTurn += damage; if ( typeOfDamage == 1 && target == source->controller()->opponent() )//add vector prowledtypes. { - vector values = MTGAllCards::getCreatureValuesById(); + vector values = MTGAllCards::getCreatureValuesById();//getting a weird crash here. rarely. for (size_t i = 0; i < values.size(); ++i) { if ( source->hasSubtype( values[i] ) && find(source->controller()->prowledTypes.begin(), source->controller()->prowledTypes.end(), values[i])==source->controller()->prowledTypes.end() ) diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 1c89311f5..a96ade840 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -962,20 +962,22 @@ JQuadPtr MTGCardInstance::getIcon() ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * newCost, ManaCost * refCost, bool noTrinisphere) { + //this function introduces a nasty memleak, it also cant be safe_deleted at the locations if its not used as it leads to a wild nullpointer crash. if(!card) return NULL; - + ManaCost * cardUnchangedCost = NEW ManaCost(); + cardUnchangedCost->copy(newCost); if(card->getIncreasedManaCost()->getConvertedCost()) - newCost->add(card->getIncreasedManaCost()); + cardUnchangedCost->add(card->getIncreasedManaCost()); if(card->getReducedManaCost()->getConvertedCost()) - newCost->remove(card->getReducedManaCost()); + cardUnchangedCost->remove(card->getReducedManaCost()); if(refCost->extraCosts) - newCost->extraCosts = refCost->extraCosts; + cardUnchangedCost->extraCosts = refCost->extraCosts; //affinity int color = 0; string type = ""; ManaCost * original = NEW ManaCost(); - original->copy(newCost); + original->copy(cardUnchangedCost); int reducem = 0; bool resetCost = false; @@ -987,7 +989,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new if(!resetCost) { resetCost = true; - newCost->copy(original); + cardUnchangedCost->copy(original); } TargetChooserFactory tf(observer); TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); @@ -1006,7 +1008,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new SAFE_DELETE(tcn); ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); for(int j = 0; j < reducem; j++) - newCost->remove(removingCost); + cardUnchangedCost->remove(removingCost); SAFE_DELETE(removingCost); } }//end2 @@ -1035,7 +1037,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new color = 1; type = "creature"; } - newCost->copy(original); + cardUnchangedCost->copy(original); int reduce = 0; if(card->has(Constants::AFFINITYGREENCREATURES)) { @@ -1047,8 +1049,8 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new else reduce = card->controller()->game->battlefield->countByType(type); for(int i = 0; i < reduce;i++) - if(newCost->getCost(color) > 0) - newCost->remove(color,1); + if(cardUnchangedCost->getCost(color) > 0) + cardUnchangedCost->remove(color,1); }//end3 if(!noTrinisphere) @@ -1056,9 +1058,9 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new //trinisphere... now how to implement kicker recomputation if(card->has(Constants::TRINISPHERE)) { - for(int jj = newCost->getConvertedCost(); jj < 3; jj++) + for(int jj = cardUnchangedCost->getConvertedCost(); jj < 3; jj++) { - newCost->add(Constants::MTG_COLOR_ARTIFACT, 1); + cardUnchangedCost->add(Constants::MTG_COLOR_ARTIFACT, 1); card->countTrini++; } } @@ -1066,7 +1068,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new { if(card->countTrini) { - newCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); + cardUnchangedCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); card->countTrini=0; } } @@ -1074,7 +1076,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new SAFE_DELETE(original); - return newCost; + return cardUnchangedCost; } MTGCardInstance * MTGCardInstance::getNextPartner() diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 6d61dc687..99269961b 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -709,7 +709,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * return 0;//overload has its own rule if(!card->getManaCost()->getAlternative()) return 0; - ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative()); + ManaCost * alternateCost = card->computeNewCost(card,card->model->data->getManaCost()->getAlternative(),card->getManaCost()->getAlternative()); if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) { @@ -773,7 +773,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) if ( !isReactingToClick(card)) return 0; - ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative()); + ManaCost * alternateCost = card->computeNewCost(card,card->model->data->getManaCost()->getAlternative(),card->getManaCost()->getAlternative()); card->paymenttype = MTGAbility::ALTERNATIVE_COST; if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) @@ -942,7 +942,7 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getBuyback()) return 0; - ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback()); + ManaCost * buybackCost = card->computeNewCost(card,card->model->data->getManaCost()->getBuyback(),card->getManaCost()->getBuyback()); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -956,7 +956,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback()); + ManaCost * buybackCost = card->computeNewCost(card,card->model->data->getManaCost()->getBuyback(),card->getManaCost()->getBuyback()); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -996,7 +996,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getFlashback()) return 0; - ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback()); + ManaCost * flashbackCost = card->computeNewCost(card,card->model->data->getManaCost()->getFlashback(),card->getManaCost()->getFlashback()); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1007,7 +1007,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGFlashBackRule::reactToClick(MTGCardInstance * card) { - ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback()); + ManaCost * flashbackCost = card->computeNewCost(card,card->model->data->getManaCost()->getFlashback(),card->getManaCost()->getFlashback()); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1049,17 +1049,17 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) Player * player = game->currentlyActing(); if(!card->getManaCost()->getRetrace()) return 0; - ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace()); + if (!player->game->graveyard->hasCard(card)) + { + return 0; + } + auto retraceCost = card->computeNewCost(card, card->model->data->getManaCost()->getRetrace(), card->getManaCost()->getRetrace()); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { retraceCost->extraCosts->costs[i]->setSource(card); - } - - if (!player->game->graveyard->hasCard(card)) - return 0; - - return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost ); + } + return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost); } @@ -1068,7 +1068,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace()); + ManaCost * retraceCost = card->computeNewCost(card,card->model->data->getManaCost()->getRetrace(),card->getManaCost()->getRetrace()); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1245,7 +1245,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY) return 0; ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph()); + ManaCost * morph = card->computeNewCost(card,card->model->data->getManaCost()->getMorph(),card->getManaCost()->getMorph()); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1274,7 +1274,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card) Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph()); + ManaCost * morph = card->computeNewCost(card,card->model->data->getManaCost()->getMorph(),card->getManaCost()->getMorph()); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1364,23 +1364,26 @@ MTGAlternativeCostRule(observer, _id) int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if(!card->has(Constants::PAYZERO)) - return 0; - Player * player = game->currentlyActing(); - ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL)); - ManaCost * newCost = card->computeNewCost(card,cost,cost); - if(newCost->extraCosts) - for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } - - if(card->isLand()) - return 0; - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) - return 0; - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - return 0; + if (!card->has(Constants::PAYZERO)) + return 0; + Player * player = game->currentlyActing(); + if (card->isLand() || (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))) + { + //only allowed to pay zero for cards in library??? above is "if you dont have it in hand, grave, or exile" + return 0; + } + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + { + return 0; + } + ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + ManaCost * newCost = card->computeNewCost(card, cost, cost); + SAFE_DELETE(cost); + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } if(card->has(Constants::CANPLAYFROMGRAVEYARD)) CustomName = "Zero Cast From Graveyard"; else if(card->has(Constants::CANPLAYFROMEXILE)) @@ -1430,22 +1433,26 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { if (card->alias != 11000) return 0; - Player * player = game->currentlyActing(); - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); - ManaCost * newCost = card->computeNewCost(card,cost,cost); + if (card->isLand()) + { + return 0; + } + Player * player = card->controller(); + if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) + { + return 0; + } + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + { + return 0; + } + ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getAlternative(), card->getManaCost()->getAlternative()); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { newCost->extraCosts->costs[i]->setSource(card); } - if (card->isLand()) - return 0; - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) - return 0; - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - return 0; - return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } @@ -1455,7 +1462,7 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card) return 0; ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); - ManaCost * newCost = card->computeNewCost(card,cost,cost); + ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getAlternative(), card->getManaCost()->getAlternative()); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { @@ -1489,23 +1496,24 @@ int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { if (!card->model) return 0; - //Player * player = game->currentlyActing(); if (!card->model->data->getManaCost()->getBestow()) return 0; if (card->isInPlay(game)) return 0; - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow()); - ManaCost * newCost = card->computeNewCost(card, cost, cost); + if (card->isLand()) + { + return 0; + } + if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) + { + return 0; + } + ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getBestow(), card->getManaCost()->getBestow()); if (newCost->extraCosts) for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) { newCost->extraCosts->costs[i]->setSource(card); } - SAFE_DELETE(cost); - if (card->isLand()) - return 0; - if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) - return 0; return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } @@ -1515,8 +1523,7 @@ int MTGBestowRule::reactToClick(MTGCardInstance * card) return 0; //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash //TODO::::we need to get to the source of this leak and fix it. - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow()); - ManaCost * newCost = card->computeNewCost(card, cost, cost); + ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getBestow(), card->getManaCost()->getBestow()); if (newCost->extraCosts) for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) @@ -2895,6 +2902,7 @@ int MTGPersistRule::receiveEvent(WEvent * event) } AAMover *putinplay = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), copy, copy,"ownerbattlefield",code,NULL,undying,persist); putinplay->oneShot = true; + game->mLayers->actionLayer()->garbage.push_back(putinplay); putinplay->fireAbility(); return 1; } diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index de9991d65..bdde06e50 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -389,11 +389,10 @@ ManaCost::ManaCost(ManaCost * manaCost) { cost[i] = manaCost->getCost(i); } - hybrids = manaCost->hybrids; - - kicker = NEW ManaCost( manaCost->kicker ); - if(kicker) - kicker->isMulti = manaCost->isMulti; + hybrids = manaCost->hybrids; + kicker = NEW ManaCost(manaCost->kicker); + if (kicker) + kicker->isMulti = manaCost->isMulti; Retrace = NEW ManaCost( manaCost->Retrace ); BuyBack = NEW ManaCost( manaCost->BuyBack ); alternative = NEW ManaCost( manaCost->alternative ); @@ -401,8 +400,11 @@ ManaCost::ManaCost(ManaCost * manaCost) morph = NEW ManaCost( manaCost->morph ); suspend = NEW ManaCost( manaCost->suspend ); Bestow = NEW ManaCost(manaCost->Bestow); - - extraCosts = manaCost->extraCosts ? manaCost->extraCosts->clone() : NULL; + extraCosts = NULL; + if (manaCost->extraCosts) + { + extraCosts = manaCost->extraCosts->clone(); + } manaUsedToCast = NULL; xColor = manaCost->xColor; } @@ -430,8 +432,12 @@ ManaCost::ManaCost(const ManaCost& manaCost) morph = NEW ManaCost( manaCost.morph ); suspend = NEW ManaCost( manaCost.suspend ); Bestow = NEW ManaCost(manaCost.Bestow); + extraCosts = NULL; + if (manaCost.extraCosts) + { + extraCosts = manaCost.extraCosts->clone(); + } - extraCosts = manaCost.extraCosts ? manaCost.extraCosts->clone() : NULL; manaUsedToCast = NULL; xColor = manaCost.xColor; } @@ -480,7 +486,6 @@ void ManaCost::x() { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return; } @@ -491,7 +496,6 @@ int ManaCost::hasX() { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return 0; } if (xColor > 0) @@ -504,7 +508,6 @@ void ManaCost::specificX(int color) { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return; } xColor = color; @@ -515,7 +518,6 @@ int ManaCost::hasSpecificX() { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return 0; } if(xColor > 0) From 861366dd711f0298d86ef266ad67a65c8aef39a3 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Wed, 6 Jul 2016 00:02:15 -0400 Subject: [PATCH 4/9] Fixed the memleaks caused by computeNewCost, moved them to gameobserver where affinity takes place, removed repeative code that was in game observer, moved the game observer components into computenewcost, removed the calls for "new mana" in all alternative play type that were added with this function. --- projects/mtg/src/GameObserver.cpp | 299 +++++++++------------------ projects/mtg/src/MTGCardInstance.cpp | 263 ++++++++++++----------- projects/mtg/src/MTGRules.cpp | 28 +-- projects/mtg/src/ManaCost.cpp | 1 + 4 files changed, 266 insertions(+), 325 deletions(-) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 693b232c2..03463f74f 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1049,7 +1049,7 @@ void GameObserver::Affinity() { MTGGameZone * dzones[] = { players[dd]->game->graveyard, players[dd]->game->hand, players[dd]->game->library, players[dd]->game->exile }; for (int kk = 0; kk < 4; kk++) - { + { MTGGameZone * zone = dzones[kk]; for (int cc = zone->nb_cards - 1; cc >= 0; cc--) {//start @@ -1057,208 +1057,115 @@ void GameObserver::Affinity() if (!card) continue; - /////////////////////////// - //reset extracost shadows// - /////////////////////////// - card->isExtraCostTarget = false; - if (mExtraPayment != NULL) - { - for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) - { - - if (mExtraPayment->costs[ec]->tc) - { - vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - Targetable * cardMasked = *it; - dynamic_cast(cardMasked)->isExtraCostTarget = true; - } - - } - } - } - //////////////////////////// - bool NewAffinityFound = false; - for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) - { - if (!card->cardsAbilities[na]) - break; - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if (newAff) - { - NewAffinityFound = true; - } - } - bool DoReduceIncrease = false; - if (card->has(Constants::AFFINITYARTIFACTS) || - card->has(Constants::AFFINITYFOREST) || - card->has(Constants::AFFINITYGREENCREATURES) || - card->has(Constants::AFFINITYISLAND) || - card->has(Constants::AFFINITYMOUNTAIN) || - card->has(Constants::AFFINITYPLAINS) || - card->has(Constants::AFFINITYSWAMP) || - card->has(Constants::TRINISPHERE) || - card->getIncreasedManaCost()->getConvertedCost() || - card->getReducedManaCost()->getConvertedCost() || - NewAffinityFound) - DoReduceIncrease = true; - if (!DoReduceIncrease) - continue; - //above we check if there are even any cards that effect cards manacost - //if there are none, leave this function. manacost->copy( is a very expensive funtion - //1mb a sec to run at all time even when no known reducers or increasers are in play. - //memory snapshot shots pointed to this as such a heavy load that games with many cards inplay - //would slow to a crawl. - //only do any of the following if a card with the stated ability is in your hand. - int color = 0; - string type = ""; - - ManaCost * original = NEW ManaCost(); - original->copy(card->model->data->getManaCost()); - if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost()) - {//start1 - if(card->getIncreasedManaCost()->getConvertedCost()) - original->add(card->getIncreasedManaCost()); - if(card->getReducedManaCost()->getConvertedCost()) - original->remove(card->getReducedManaCost()); - if(card->getManaCost()) - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) + /////////////////////////// + //reset extracost shadows// + /////////////////////////// + card->isExtraCostTarget = false; + if (mExtraPayment != NULL) + { + for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + + if (mExtraPayment->costs[ec]->tc) { - card->getManaCost()->extraCosts->costs[i]->setSource(card); + vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + Targetable * cardMasked = *it; + dynamic_cast(cardMasked)->isExtraCostTarget = true; + } + } } - }//end1 - int reducem = 0; - bool resetCost = false; - for(unsigned int na = 0; na < card->cardsAbilities.size();na++) - {//start2 - if (!card->cardsAbilities[na]) - break; + } + //////////////////////////// + bool NewAffinityFound = false; + for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) + { + if (!card->cardsAbilities[na]) + break; ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if(newAff) + if (newAff) { - if(!resetCost) - { - resetCost = true; - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) - { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) - { - card->getManaCost()->extraCosts->costs[i]->setSource(card); - } - } - } - TargetChooserFactory tf(this); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); + NewAffinityFound = true; + } + } + bool DoReduceIncrease = false; + if (card->has(Constants::AFFINITYARTIFACTS) || + card->has(Constants::AFFINITYFOREST) || + card->has(Constants::AFFINITYGREENCREATURES) || + card->has(Constants::AFFINITYISLAND) || + card->has(Constants::AFFINITYMOUNTAIN) || + card->has(Constants::AFFINITYPLAINS) || + card->has(Constants::AFFINITYSWAMP) || + card->has(Constants::TRINISPHERE) || + card->getIncreasedManaCost()->getConvertedCost() || + card->getReducedManaCost()->getConvertedCost() || + NewAffinityFound) + DoReduceIncrease = true; + if (!DoReduceIncrease) + continue; + //above we check if there are even any cards that effect cards manacost + //if there are none, leave this function. manacost->copy( is a very expensive funtion + //1mb a sec to run at all time even when no known reducers or increasers are in play. + //memory snapshot shots pointed to this as such a heavy load that games with many cards inplay + //would slow to a crawl. + //only do any of the following if a card with the stated ability is in your hand. + //kicker is an addon to normal cost, suspend is not casting. add cost as needed EXACTLY as seen below. + card->getManaCost()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost())); + card->getManaCost()->copy(newCost); + SAFE_DELETE(newCost); + if (card->getManaCost()->getAlternative()) + { + card->getManaCost()->getAlternative()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative())); + card->getManaCost()->getAlternative()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getBestow()) + { + card->getManaCost()->getBestow()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow())); + card->getManaCost()->getBestow()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getRetrace()) + { + card->getManaCost()->getRetrace()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace())); + card->getManaCost()->getRetrace()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getBuyback()) + { + card->getManaCost()->getBuyback()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback())); + card->getManaCost()->getBuyback()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getFlashback()) + { + card->getManaCost()->getFlashback()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback())); + card->getManaCost()->getFlashback()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getMorph()) + { + card->getManaCost()->getMorph()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph())); + card->getManaCost()->getMorph()->copy(newCost); + SAFE_DELETE(newCost); + } - for (int w = 0; w < 2; ++w) - { - Player *p = this->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) - { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - { - reducem += z->countByCanTarget(tcn); - } - } - } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for(int j = 0; j < reducem; j++) - card->getManaCost()->remove(removingCost); - SAFE_DELETE(removingCost); - } - }//end2 - if(card->has(Constants::AFFINITYARTIFACTS)|| - card->has(Constants::AFFINITYFOREST)|| - card->has(Constants::AFFINITYGREENCREATURES)|| - card->has(Constants::AFFINITYISLAND)|| - card->has(Constants::AFFINITYMOUNTAIN)|| - card->has(Constants::AFFINITYPLAINS)|| - card->has(Constants::AFFINITYSWAMP)) - {//start3 - if (card->has(Constants::AFFINITYARTIFACTS)) - { - type = "artifact"; - } - else if (card->has(Constants::AFFINITYSWAMP)) - { - type = "swamp"; - } - else if (card->has(Constants::AFFINITYMOUNTAIN)) - { - type = "mountain"; - } - else if (card->has(Constants::AFFINITYPLAINS)) - { - type = "plains"; - } - else if (card->has(Constants::AFFINITYISLAND)) - { - type = "island"; - } - else if (card->has(Constants::AFFINITYFOREST)) - { - type = "forest"; - } - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) - { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) - { - card->getManaCost()->extraCosts->costs[i]->setSource(card); - } - } - int reduce = 0; - if(card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(this); - TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); - reduce = card->controller()->game->battlefield->countByCanTarget(tc); - SAFE_DELETE(tc); - } - else - { - reduce = card->controller()->game->battlefield->countByType(type); - } - for(int i = 0; i < reduce;i++) - { - if(card->getManaCost()->getCost(color) > 0) - card->getManaCost()->remove(color,1); - } - }//end3 - //trinisphere... now how to implement kicker recomputation - - if(card->has(Constants::TRINISPHERE)) - { - for(int jj = card->getManaCost()->getConvertedCost(); jj < 3; jj++) - { - card->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1); - card->countTrini++; - } - } - else - { - if(card->countTrini) - { - card->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); - card->countTrini=0; - } - } - - SAFE_DELETE(original); }//end } } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index a96ade840..bdb240071 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -960,123 +960,156 @@ JQuadPtr MTGCardInstance::getIcon() return WResourceManager::Instance()->RetrieveCard(this, CACHE_THUMB); } -ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * newCost, ManaCost * refCost, bool noTrinisphere) +ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cost, ManaCost * Data, bool noTrinisphere) { - //this function introduces a nasty memleak, it also cant be safe_deleted at the locations if its not used as it leads to a wild nullpointer crash. - if(!card) - return NULL; - ManaCost * cardUnchangedCost = NEW ManaCost(); - cardUnchangedCost->copy(newCost); - if(card->getIncreasedManaCost()->getConvertedCost()) - cardUnchangedCost->add(card->getIncreasedManaCost()); - if(card->getReducedManaCost()->getConvertedCost()) - cardUnchangedCost->remove(card->getReducedManaCost()); - if(refCost->extraCosts) - cardUnchangedCost->extraCosts = refCost->extraCosts; - //affinity - int color = 0; - string type = ""; - ManaCost * original = NEW ManaCost(); - original->copy(cardUnchangedCost); - - int reducem = 0; - bool resetCost = false; - for(unsigned int na = 0; na < card->cardsAbilities.size();na++) - {//start2 - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if(newAff) - { - if(!resetCost) - { - resetCost = true; - cardUnchangedCost->copy(original); - } - TargetChooserFactory tf(observer); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); - - for (int w = 0; w < 2; ++w) - { - Player *p = observer->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) - { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - reducem += z->countByCanTarget(tcn); - } - } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for(int j = 0; j < reducem; j++) - cardUnchangedCost->remove(removingCost); - SAFE_DELETE(removingCost); - } - }//end2 - if(card->has(Constants::AFFINITYARTIFACTS)|| - card->has(Constants::AFFINITYFOREST)|| - card->has(Constants::AFFINITYGREENCREATURES)|| - card->has(Constants::AFFINITYISLAND)|| - card->has(Constants::AFFINITYMOUNTAIN)|| - card->has(Constants::AFFINITYPLAINS)|| - card->has(Constants::AFFINITYSWAMP)) - {//start3 - if (card->has(Constants::AFFINITYARTIFACTS)) - type = "artifact"; - else if (card->has(Constants::AFFINITYSWAMP)) - type = "swamp"; - else if (card->has(Constants::AFFINITYMOUNTAIN)) - type = "mountain"; - else if (card->has(Constants::AFFINITYPLAINS)) - type = "plains"; - else if (card->has(Constants::AFFINITYISLAND)) - type = "island"; - else if (card->has(Constants::AFFINITYFOREST)) - type = "forest"; - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - cardUnchangedCost->copy(original); - int reduce = 0; - if(card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(observer); - TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); - reduce = card->controller()->game->battlefield->countByCanTarget(tc); - SAFE_DELETE(tc); - } - else - reduce = card->controller()->game->battlefield->countByType(type); - for(int i = 0; i < reduce;i++) - if(cardUnchangedCost->getCost(color) > 0) - cardUnchangedCost->remove(color,1); - }//end3 - - if(!noTrinisphere) - { - //trinisphere... now how to implement kicker recomputation - if(card->has(Constants::TRINISPHERE)) - { - for(int jj = cardUnchangedCost->getConvertedCost(); jj < 3; jj++) - { - cardUnchangedCost->add(Constants::MTG_COLOR_ARTIFACT, 1); - card->countTrini++; - } - } - else - { - if(card->countTrini) - { - cardUnchangedCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); - card->countTrini=0; - } - } - } - + int color = 0; + string type = ""; + ManaCost * original = NEW ManaCost(); + original->copy(Data); + if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost()) + {//start1 + if (card->getIncreasedManaCost()->getConvertedCost()) + original->add(card->getIncreasedManaCost()); + if (card->getReducedManaCost()->getConvertedCost()) + original->remove(card->getReducedManaCost()); + + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + }//end1 + int reducem = 0; + bool resetCost = false; + for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) + {//start2 + if (!card->cardsAbilities[na]) + break; + ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); + if (newAff) + { + if (!resetCost) + { + resetCost = true; + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + } + TargetChooserFactory tf(getObserver()); + TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL); + + for (int w = 0; w < 2; ++w) + { + Player *p = getObserver()->players[w]; + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) + { + MTGGameZone * z = zones[k]; + if (tcn->targetsZone(z)) + { + reducem += z->countByCanTarget(tcn); + } + } + } + SAFE_DELETE(tcn); + ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); + for (int j = 0; j < reducem; j++) + original->remove(removingCost); + SAFE_DELETE(removingCost); + } + }//end2 + if (card->has(Constants::AFFINITYARTIFACTS) || + card->has(Constants::AFFINITYFOREST) || + card->has(Constants::AFFINITYGREENCREATURES) || + card->has(Constants::AFFINITYISLAND) || + card->has(Constants::AFFINITYMOUNTAIN) || + card->has(Constants::AFFINITYPLAINS) || + card->has(Constants::AFFINITYSWAMP)) + {//start3 + if (card->has(Constants::AFFINITYARTIFACTS)) + { + type = "artifact"; + } + else if (card->has(Constants::AFFINITYSWAMP)) + { + type = "swamp"; + } + else if (card->has(Constants::AFFINITYMOUNTAIN)) + { + type = "mountain"; + } + else if (card->has(Constants::AFFINITYPLAINS)) + { + type = "plains"; + } + else if (card->has(Constants::AFFINITYISLAND)) + { + type = "island"; + } + else if (card->has(Constants::AFFINITYFOREST)) + { + type = "forest"; + } + else if (card->has(Constants::AFFINITYGREENCREATURES)) + { + color = 1; + type = "creature"; + } + + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + int reduce = 0; + if (card->has(Constants::AFFINITYGREENCREATURES)) + { + TargetChooserFactory tf(getObserver()); + TargetChooser * tc = tf.createTargetChooser("creature[green]", NULL); + reduce = card->controller()->game->battlefield->countByCanTarget(tc); + SAFE_DELETE(tc); + } + else + { + reduce = card->controller()->game->battlefield->countByType(type); + } + for (int i = 0; i < reduce; i++) + { + if (Cost->getCost(color) > 0) + Cost->remove(color, 1); + } + }//end3 + //trinisphere... now how to implement kicker recomputation + + if (card->has(Constants::TRINISPHERE)) + { + for (int jj = Cost->getConvertedCost(); jj < 3; jj++) + { + Cost->add(Constants::MTG_COLOR_ARTIFACT, 1); + card->countTrini++; + } + } + else + { + if (card->countTrini) + { + Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); + card->countTrini = 0; + } + } SAFE_DELETE(original); - - return cardUnchangedCost; + return Cost; } MTGCardInstance * MTGCardInstance::getNextPartner() diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 99269961b..7cd9fcfea 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -709,7 +709,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * return 0;//overload has its own rule if(!card->getManaCost()->getAlternative()) return 0; - ManaCost * alternateCost = card->computeNewCost(card,card->model->data->getManaCost()->getAlternative(),card->getManaCost()->getAlternative()); + ManaCost * alternateCost = card->getManaCost()->getAlternative(); if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) { @@ -773,7 +773,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) if ( !isReactingToClick(card)) return 0; - ManaCost * alternateCost = card->computeNewCost(card,card->model->data->getManaCost()->getAlternative(),card->getManaCost()->getAlternative()); + ManaCost * alternateCost = card->getManaCost()->getAlternative(); card->paymenttype = MTGAbility::ALTERNATIVE_COST; if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) @@ -942,7 +942,7 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getBuyback()) return 0; - ManaCost * buybackCost = card->computeNewCost(card,card->model->data->getManaCost()->getBuyback(),card->getManaCost()->getBuyback()); + ManaCost * buybackCost = card->getManaCost()->getBuyback(); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -956,7 +956,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * buybackCost = card->computeNewCost(card,card->model->data->getManaCost()->getBuyback(),card->getManaCost()->getBuyback()); + ManaCost * buybackCost = card->getManaCost()->getBuyback(); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -996,7 +996,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getFlashback()) return 0; - ManaCost * flashbackCost = card->computeNewCost(card,card->model->data->getManaCost()->getFlashback(),card->getManaCost()->getFlashback()); + ManaCost * flashbackCost = card->getManaCost()->getFlashback(); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1007,7 +1007,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGFlashBackRule::reactToClick(MTGCardInstance * card) { - ManaCost * flashbackCost = card->computeNewCost(card,card->model->data->getManaCost()->getFlashback(),card->getManaCost()->getFlashback()); + ManaCost * flashbackCost = card->getManaCost()->getFlashback(); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1053,7 +1053,7 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { return 0; } - auto retraceCost = card->computeNewCost(card, card->model->data->getManaCost()->getRetrace(), card->getManaCost()->getRetrace()); + auto retraceCost = card->getManaCost()->getRetrace(); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1068,7 +1068,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * retraceCost = card->computeNewCost(card,card->model->data->getManaCost()->getRetrace(),card->getManaCost()->getRetrace()); + ManaCost * retraceCost = card->getManaCost()->getRetrace(); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1245,7 +1245,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY) return 0; ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->computeNewCost(card,card->model->data->getManaCost()->getMorph(),card->getManaCost()->getMorph()); + ManaCost * morph = card->getManaCost()->getMorph(); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1274,7 +1274,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card) Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->computeNewCost(card,card->model->data->getManaCost()->getMorph(),card->getManaCost()->getMorph()); + ManaCost * morph = card->getManaCost()->getMorph(); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1446,7 +1446,7 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { return 0; } - ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getAlternative(), card->getManaCost()->getAlternative()); + ManaCost * newCost = card->getManaCost()->getAlternative(); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { @@ -1462,7 +1462,7 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card) return 0; ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); - ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getAlternative(), card->getManaCost()->getAlternative()); + ManaCost * newCost = card->getManaCost()->getAlternative(); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { @@ -1508,7 +1508,7 @@ int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { return 0; } - ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getBestow(), card->getManaCost()->getBestow()); + ManaCost * newCost = card->getManaCost()->getBestow(); if (newCost->extraCosts) for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) { @@ -1523,7 +1523,7 @@ int MTGBestowRule::reactToClick(MTGCardInstance * card) return 0; //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash //TODO::::we need to get to the source of this leak and fix it. - ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getBestow(), card->getManaCost()->getBestow()); + ManaCost * newCost = card->getManaCost()->getBestow(); if (newCost->extraCosts) for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index bdde06e50..f1d5d208c 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -601,6 +601,7 @@ void ManaCost::copy(ManaCost * _manaCost) hybrids = _manaCost->hybrids; SAFE_DELETE(extraCosts); + if (_manaCost->extraCosts) { extraCosts = _manaCost->extraCosts->clone(); From 2ca7b2310be0d3016a4e0f8e79b895f425753f8a Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Wed, 6 Jul 2016 00:43:11 -0400 Subject: [PATCH 5/9] trying to manuelly add changes --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 106 +++++++++---------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 5d6fa903a..ce55bb4a1 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -11945,7 +11945,7 @@ toughness=1 [/card] [card] name=Blustersquall -alias=11000 +abilities=overload other={3}{U} name(Overload) target=creature|opponentbattlefield auto=overload tap all(creature|opponentbattlefield) @@ -12646,7 +12646,7 @@ subtype=Equipment [/card] [card] name=Boneyard Wurm -alias=1111 + anyzone=type:creature:mygraveyard/type:creature:mygraveyard cdaactive text=Boneyard Wurm's power and toughness are each equal to the number of creature cards in your graveyard. mana={1}{G} @@ -15448,7 +15448,7 @@ subtype=Forest Plains [/card] [card] name=Cantivore -alias=1111 + abilities=vigilance anyzone=type:enchantment:graveyard/type:enchantment:graveyard cdaactive text=Vigilance -- Cantivore's power and toughness are each equal to the number of enchantment cards in all graveyards. @@ -17740,7 +17740,7 @@ type=Sorcery [/card] [card] name=Chemister's Trick -alias=11000 +abilities=overload other={3}{U}{R} name(Overload) target=creature|opponentbattlefield auto=paidmana -2/0 @@ -18074,7 +18074,7 @@ toughness=2 [/card] [card] name=Cho-Manno's Blessing -alias=1000 + abilities=auraward target=creature abilities=flash @@ -19729,7 +19729,7 @@ type=Instant [/card] [card] name=Cognivore -alias=1111 + abilities=flying anyzone=type:instant:graveyard/type:instant:graveyard cdaactive text=Flying -- Cognivore's power and toughness are each equal to the number of instant cards in all graveyards. @@ -19799,7 +19799,7 @@ toughness=1 [/card] [card] name=Coldsteel Heart -alias=1000 + auto=tap auto=chooseacolor {T}:add{chosencolor} chooseend text=Coldsteel Heart enters the battlefield tapped. -- As Coldsteel Heart enters the battlefield, choose a color. -- {T}: Add one mana of the chosen color to your mana pool. @@ -21242,7 +21242,7 @@ type=Instant [/card] [card] name=Counterflux -alias=11000 +abilities=overload other={1}{U}{U}{R} name(Overload) abilities=nofizzle target=*|opponentstack @@ -23086,7 +23086,7 @@ subtype=Aura Curse [/card] [card] name=Curse of Wizardry -alias=1000 + auto=chooseacolor transforms((,newability[@movedto(*[chosencolor]|mystack):life:-1 controller],newability[@movedto(*[chosencolor]|opponentstack):life:-1 opponent])) chooseend text=As Curse of Wizardry enters the battlefield, choose a color. -- Whenever a player casts a spell of the chosen color, that player loses 1 life. mana={2}{B}{B} @@ -23234,7 +23234,7 @@ toughness=4 [/card] [card] name=Cyclonic Rift -alias=11000 +abilities=overload other={6}{U} name(Overload) target=*[-land]|opponentbattlefield auto=overload moveto(ownerhand) all(*[-land]|opponentbattlefield) @@ -26677,7 +26677,7 @@ text=Destroy target artifact with converted mana cost X. It can't be regenerated [/card] [card] name=Detritivore -alias=1111 + anyzone=type:land[-basic]:opponentgraveyard/type:land[-basic]:opponentgraveyard cdaactive autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:destroy target(land[-basic]) suspend(0)={X}{3}{R} @@ -28418,7 +28418,7 @@ type=Instant [/card] [card] name=Downsize -alias=11000 +abilities=overload other={2}{U} name(Overload) target=creature|opponentbattlefield auto=overload -4/0 all(creature|opponentbattlefield) @@ -30847,7 +30847,7 @@ subtype=Aura [/card] [card] name=Dynacharge -alias=11000 +abilities=overload other={2}{R} name(Overload) target=creature|mybattlefield auto=paidmana 2/0 @@ -31693,7 +31693,7 @@ toughness=1 [/card] [card] name=Electrickery -alias=11000 +abilities=overload other={1}{R} name(Overload) target=creature|opponentbattlefield auto=paidmana damage:1 @@ -38491,7 +38491,7 @@ toughness=2 [/card] [card] name=Flickering Ward -alias=1000 + abilities=auraward target=creature auto=chooseacolor teach(creature) protection from(*[chosencolor]) chooseend @@ -38584,7 +38584,7 @@ toughness=1 [/card] [card] name=Floating Shield -alias=1000 + abilities=auraward target=creature auto=chooseacolor teach(creature) protection from(*[chosencolor]) chooseend @@ -47785,7 +47785,7 @@ toughness=3 [/card] [card] name=Hall of Triumph -alias=1000 + auto=activatechooseacolor transforms((,newability[lord(creature[chosencolor]|mybattlefield) 1/1])) forever activatechooseend text=As Hall of Triumph enters the battlefield, choose a color. -- Creatures you control of the chosen color get +1/+1. mana={3} @@ -49639,7 +49639,7 @@ subtype=Equipment [/card] [card] name=Helm of Possession -alias=50120 +abilities=shackler auto={2}{T}{S(creature|mybattlefield)}:shackle target(creature) auto=@each my untap restriction{canuntap}:may untap text=You may choose not to untap Helm of Possession during your untap step. -- {2}, {T}, Sacrifice a creature: Gain control of target creature for as long as you control Helm of Possession and Helm of Possession remains tapped. @@ -50435,7 +50435,7 @@ type=Artifact [/card] [card] name=Hivis of the Scale -alias=50120 +abilities=shackler auto={T}:shackle target(dragon) auto=@each my untap restriction{canuntap}:may untap text=You may choose not to untap Hivis of the Scale during your untap step. -- {T}: Gain control of target Dragon for as long as you control Hivis and Hivis remains tapped. @@ -54270,7 +54270,7 @@ type=Enchantment [/card] [card] name=Iona, Shield of Emeria -alias=1000 + abilities=flying auto=chooseacolor maxCast(*[chosencolor])0 opponent chooseend text=Flying -- As Iona, Shield of Emeria enters the battlefield, choose a color. -- Your opponents can't cast spells of the chosen color. @@ -55493,7 +55493,7 @@ toughness=3 [/card] [card] name=Jihad -alias=1000 + auto=chooseacolor transforms((,newability[aslongas(*[chosencolor]|opponentbattlefield) lord(creature[white]|mybattlefield) 2/1],newability[aslongas(*[chosencolor]|opponentbattlefield) sacrifice <1])) chooseend text=As Jihad enters the battlefield, choose a color and an opponent. -- White creatures get +2/+1 as long as the chosen player controls a nontoken permanent of the chosen color. -- When the chosen player controls no nontoken permanents of the chosen color, sacrifice Jihad. mana={W}{W}{W} @@ -61527,7 +61527,7 @@ toughness=5 [/card] [card] name=Lhurgoyf -alias=1111 + anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. mana={2}{G}{G} @@ -63024,7 +63024,7 @@ toughness=2 [/card] [card] name=Lord of Extinction -alias=1111 + anyzone=type:*:graveyard/type:*:graveyard cdaactive text=Lord of Extinction's power and toughness are each equal to the number of cards in all graveyards. mana={3}{B}{G} @@ -63796,7 +63796,7 @@ type=Instant [/card] [card] name=Lurebound Scarecrow -alias=1000 + auto=chooseacolor aslongas(*[chosencolor]|myBattlefield) sacrifice <1 chooseend text=As Lurebound Scarecrow enters the battlefield, choose a color. -- When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow. mana={3} @@ -64491,7 +64491,7 @@ toughness=6 [/card] [card] name=Magnivore -alias=1111 + abilities=haste anyzone=type:sorcery:graveyard/type:sorcery:graveyard cdaactive text=Haste (This creature can attack the turn it comes under your control.) -- Magnivore's power and toughness are each equal to the number of sorcery cards in all graveyards. @@ -69407,7 +69407,7 @@ toughness=4 [/card] [card] name=Mizzium Mortars -alias=11000 +abilities=overload other={3}{R}{R}{R} name(Overload) target=creature|opponentbattlefield auto=paidmana damage:4 @@ -69418,7 +69418,7 @@ type=Sorcery [/card] [card] name=Mizzium Skin -alias=11000 +abilities=overload other={1}{U} name(Overload) target=creature|mybattlefield auto=paidmana 0/1 @@ -70774,7 +70774,7 @@ toughness=2 [/card] [card] name=Mortivore -alias=1111 + auto={B}:regenerate anyzone=type:creature:graveyard/type:creature:graveyard cdaactive text=Mortivore's power and toughness are each equal to the number of creature cards in all graveyards. -- {B}: Regenerate Mortivore. (The next time this creature would be destroyed this turn, it isn't. Instead tap it, remove all damage from it, and remove it from combat.) @@ -75772,7 +75772,7 @@ toughness=6 [/card] [card] name=Old Man of the Sea -alias=50120 +abilities=shackler auto={T}:shackle target(creature[power<=storedpower]) auto=@each my untap restriction{canuntap}:may untap text=You may choose not to untap Old Man of the Sea during your untap step. -- {T}: Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power. @@ -77807,7 +77807,7 @@ subtype=Equipment [/card] [card] name=Paradise Plume -alias=1000 + auto=chooseacolor transforms((,newability[{T}:add{chosencolor}],newability[@movedto(*[chosencolor]|stack):life:1 controller])) forever chooseend text=As Paradise Plume enters the battlefield, choose a color. -- Whenever a player casts a spell of the chosen color, you may gain 1 life. -- {T}: Add one mana of the chosen color to your mana pool. mana={4} @@ -78639,7 +78639,7 @@ type=Artifact [/card] [card] name=Pentarch Paladin -alias=1000 + abilities=flanking auto=chooseacolor {W}{W}{T}:destroy target(*[chosencolor]) chooseend text=Flanking (Whenever a creature without flanking blocks this creature, the blocking creature gets -1/-1 until end of turn.) -- As Pentarch Paladin enters the battlefield, choose a color. -- {W}{W}, {T}: Destroy target permanent of the chosen color. @@ -78651,7 +78651,7 @@ toughness=3 [/card] [card] name=Pentarch Ward -alias=1000 + abilities=auraward target=creature auto=chooseacolor teach(creature) protection from(*[chosencolor]) chooseend @@ -81977,7 +81977,7 @@ type=Enchantment [/card] [card] name=Prism Ring -alias=1000 + auto=activatechooseacolor transforms((,newability[@movedto(*[chosencolor]|mystack):life:1 controller])) forever activatechooseend text=As Prism Ring enters the battlefield, choose a color. -- Whenever you cast a spell of the chosen color, you gain 1 life. mana={1} @@ -82493,7 +82493,7 @@ toughness=2 [/card] [card] name=Psychic Allergy -alias=1000 + auto=upcost[{S(island|mybattlefield)}{S(island|mybattlefield)}] sacrifice auto=chooseacolor transforms((,newability[@each opponent upkeep:damage:type:*[-token&chosencolor]:opponentbattlefield opponent])) chooseend text=As Psychic Allergy enters the battlefield, choose a color. -- At the beginning of each opponent's upkeep, Psychic Allergy deals X damage to that player, where X is the number of nontoken permanents of the chosen color he or she controls. -- At the beginning of your upkeep, destroy Psychic Allergy unless you sacrifice two Islands. @@ -83714,7 +83714,7 @@ toughness=1 [/card] [card] name=Quirion Elves -alias=1000 + auto={T}:Add{G} auto=chooseacolor {T}:add{chosencolor} chooseend text=As Quirion Elves enters the battlefield, choose a color. -- {T}: Add {G} to your mana pool. -- {T}: Add one mana of the chosen color to your mana pool. @@ -87461,7 +87461,7 @@ toughness=3 [/card] [card] name=Revenant -alias=1111 + abilities=flying anyzone=type:creature:mygraveyard/type:creature:mygraveyard cdaactive text=Flying -- Revenant's power and toughness are each equal to the number of creature cards in your graveyard. @@ -89670,7 +89670,7 @@ toughness=* [/card] [card] name=Rubinia Soulsinger -alias=50120 +abilities=shackler auto={T}:shackle target(creature) auto=@each my untap restriction{canuntap}:may untap text=You may choose not to untap Rubinia Soulsinger during your untap step. -- {T}: Gain control of target creature for as long as you control Rubinia and Rubinia remains tapped. @@ -96134,7 +96134,7 @@ subtype=Shapeshifter [/card] [card] name=Shifting Sky -alias=1000 + auto=chooseacolor lord(*[-land]) becomes(,chosencolor) chooseend text=As Shifting Sky enters the battlefield, choose a color. -- All nonland permanents are the chosen color. mana={2}{U} @@ -97556,7 +97556,7 @@ toughness=1 [/card] [card] name=Silhana Starfletcher -alias=1000 + abilities=reach auto=activatechooseacolor {T}:add{chosencolor} activatechooseend text=Reach (This creature can block creatures with flying.) -- As Silhana Starfletcher enters the battlefield, choose a color. -- {T}: Add one mana of the chosen color to your mana pool. @@ -99583,7 +99583,7 @@ subtype=Equipment [/card] [card] name=Slag Fiend -alias=1111 + anyzone=type:artifact:graveyard/type:artifact:graveyard cdaactive text=Slag Fiend's power and toughness are each equal to the number of artifact cards in all graveyards. mana={R} @@ -100732,7 +100732,7 @@ toughness=3 [/card] [card] name=Sol Grail -alias=1000 + auto=chooseacolor transforms((,newability[{T}:add{chosencolor}])) forever chooseend text=As Sol Grail enters the battlefield, choose a color. -- {T}: Add one mana of the chosen color to your mana pool. mana={3} @@ -103624,7 +103624,7 @@ subtype=Aura [/card] [card] name=Splinterfright -alias=1111 + abilities=trample anyzone=type:creature:mygraveyard/type:creature:mygraveyard cdaactive auto=@each my upkeep:deplete:2 controller @@ -106139,7 +106139,7 @@ toughness=3 [/card] [card] name=Street Spasm -alias=11000 +abilities=overload other={X}{X}{R}{R} name(Overload) target=creature[-flying]|opponentbattlefield auto=paidmana damage:X @@ -109676,7 +109676,7 @@ type=Legendary Land [/card] [card] name=Teferi's Moat -alias=1000 + auto=chooseacolor lord(creature[chosencolor&-flying]|opponentBattlefield) cantattack chooseend text=As Teferi's Moat enters the battlefield, choose a color. -- Creatures of the chosen color without flying can't attack you. mana={3}{W}{U} @@ -109767,7 +109767,7 @@ toughness=2 [/card] [card] name=Teleportal -alias=11000 +abilities=overload other={3}{U}{R} name(Overload) target=creature|mybattlefield auto=paidmana 1/0 @@ -110427,7 +110427,7 @@ type=Artifact [/card] [card] name=Terravore -alias=1111 + abilities=trample anyzone=type:land:graveyard/type:land:graveyard cdaactive text=Trample -- Terravore's power and toughness are each equal to the number of land cards in all graveyards. @@ -116278,7 +116278,7 @@ type=Artifact [/card] [card] name=Umbra Stalker -alias=1111 + anyzone=type:manab:mygraveyard/type:manab:mygraveyard cdaactive text=Chroma - Umbra Stalker's power and toughness are each equal to the number of black mana symbols in the mana costs of cards in your graveyard. mana={4}{B}{B}{B} @@ -118001,7 +118001,7 @@ subtype=Aura [/card] [card] name=Vandalblast -alias=11000 +abilities=overload other={4}{R} name(Overload) target=artifact|opponentbattlefield auto=overload destroy all(artifact|opponentbattlefield) @@ -118395,7 +118395,7 @@ toughness=2 [/card] [card] name=Vedalken Shackles -alias=50120 +abilities=shackler auto={2}{T}:shackle target(creature[power<=type:island:mybattlefield]) auto=@each my untap restriction{canuntap}:may untap text=You may choose not to untap Vedalken Shackles during your untap step. -- {2}, {T}: Gain control of target creature with power less than or equal to the number of Islands you control for as long as Vedalken Shackles remains tapped. @@ -120461,7 +120461,7 @@ toughness=2 [/card] [card] name=Voice of All -alias=1000 + abilities=flying auto=chooseacolor transforms((,newability[protection from(*[chosencolor])],newability[0/0])) forever chooseend text=Flying (This creature can't be blocked except by creatures with flying or reach.) -- As Voice of All enters the battlefield, choose a color. -- Voice of All has protection from the chosen color. (It can't be blocked, targeted, dealt damage, or enchanted by anything of the chosen color.) @@ -122343,7 +122343,7 @@ toughness=1 [/card] [card] name=Ward Sliver -alias=1000 + auto=chooseacolor transforms((,newability[lord(sliver) protection from(*[chosencolor])])) forever chooseend text=As Ward Sliver enters the battlefield, choose a color. -- All Slivers have protection from the chosen color. mana={4}{W} @@ -123048,7 +123048,7 @@ type=Artifact [/card] [card] name=Weapon Surge -alias=11000 +abilities=overload other={1}{R} name(Overload) target=creature|mybattlefield auto=paidmana 1/0 @@ -124336,7 +124336,7 @@ toughness=2 [/card] [card] name=Willow Satyr -alias=50120 +abilities=shackler auto={T}:shackle target(creature[legendary]) auto=@each my untap restriction{canuntap}:may untap text=You may choose not to untap Willow Satyr during your untap step. -- {T}: Gain control of target legendary creature for as long as you control Willow Satyr and Willow Satyr remains tapped. From a748e0337d238a76dc9d065149dbc7500c150424 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Wed, 6 Jul 2016 17:56:17 -0400 Subject: [PATCH 6/9] trying to get my commit in --- .../bin/Res/sets/primitives/borderline.txt | 10 + projects/mtg/bin/Res/sets/primitives/mtg.txt | 182 ++++++++---------- .../bin/Res/sets/primitives/unsupported.txt | 45 ----- 3 files changed, 89 insertions(+), 148 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index 2b2e2c3ba..5ac11eec8 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -352,3 +352,13 @@ mana={B} type=Instant text=Target creature gets +2/+0 and gains deathtouch until end of turn. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.) [/card] +[card] +name=Yixlid Jailer +auto=lord(*|graveyard) loseabilities +text=Cards in graveyards lose all abilities. +mana={1}{B} +type=Creature +subtype=Zombie Wizard +power=2 +toughness=1 +[/card] diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index ce55bb4a1..5a8969ebb 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1043,7 +1043,7 @@ type=Enchantment [/card] [card] name=AEther Burst -target=creature|battlefield +target=creature|battlefield auto=moveto(ownerhand) text=Return up to X target creatures to their owners' hands, where X is one plus the number of cards named AEther Burst in all graveyards as you cast AEther Burst. mana={1}{U} @@ -3677,7 +3677,7 @@ toughness=1+* [/card] [card] name=An-Havva Inn -auto=life:type:creature[green]|battlefieldplus1plusend controller +auto=life:plusonetype:creature[green]|battlefield controller text=You gain X plus 1 life, where X is the number of green creatures on the battlefield. mana={1}{G}{G} type=Sorcery @@ -10126,7 +10126,7 @@ type=Sorcery [card] name=Black Vise auto=name(choose opponent) notatarget(opponent) deplete:0 -auto=@each targetedplayer upkeep:damage:type:*:opponenthandminus4minusend targetedplayer +auto=@each targetedplayer upkeep:damage:morethanfourcards targetedplayer text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={1} type=Artifact @@ -12646,7 +12646,6 @@ subtype=Equipment [/card] [card] name=Boneyard Wurm - anyzone=type:creature:mygraveyard/type:creature:mygraveyard cdaactive text=Boneyard Wurm's power and toughness are each equal to the number of creature cards in your graveyard. mana={1}{G} @@ -15448,7 +15447,6 @@ subtype=Forest Plains [/card] [card] name=Cantivore - abilities=vigilance anyzone=type:enchantment:graveyard/type:enchantment:graveyard cdaactive text=Vigilance -- Cantivore's power and toughness are each equal to the number of enchantment cards in all graveyards. @@ -18074,7 +18072,6 @@ toughness=2 [/card] [card] name=Cho-Manno's Blessing - abilities=auraward target=creature abilities=flash @@ -19729,7 +19726,6 @@ type=Instant [/card] [card] name=Cognivore - abilities=flying anyzone=type:instant:graveyard/type:instant:graveyard cdaactive text=Flying -- Cognivore's power and toughness are each equal to the number of instant cards in all graveyards. @@ -19799,7 +19795,6 @@ toughness=1 [/card] [card] name=Coldsteel Heart - auto=tap auto=chooseacolor {T}:add{chosencolor} chooseend text=Coldsteel Heart enters the battlefield tapped. -- As Coldsteel Heart enters the battlefield, choose a color. -- {T}: Add one mana of the chosen color to your mana pool. @@ -23086,7 +23081,6 @@ subtype=Aura Curse [/card] [card] name=Curse of Wizardry - auto=chooseacolor transforms((,newability[@movedto(*[chosencolor]|mystack):life:-1 controller],newability[@movedto(*[chosencolor]|opponentstack):life:-1 opponent])) chooseend text=As Curse of Wizardry enters the battlefield, choose a color. -- Whenever a player casts a spell of the chosen color, that player loses 1 life. mana={2}{B}{B} @@ -26020,6 +26014,16 @@ mana={3}{U} type=Enchantment [/card] [card] +name=Delver of Secrets +auto=@each my upkeep:reveal:1 optionone name(transform) target(*[instant;sorcery]|reveal) moveto(mylibrary) and!( all(this) transforms((,newability[flip(Insectile Aberration)])) forever )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(mylibrary) optiontwoend revealend +text=At the beginning of your upkeep, look at the top card of your library. You may reveal that card. If an instant or sorcery card is revealed this way, transform Delver of Secrets. +mana={U} +type=Creature +subtype=Human Wizard +power=1 +toughness=1 +[/card] +[card] name=Dematerialize target=* auto=moveTo(ownerhand) @@ -26677,7 +26681,6 @@ text=Destroy target artifact with converted mana cost X. It can't be regenerated [/card] [card] name=Detritivore - anyzone=type:land[-basic]:opponentgraveyard/type:land[-basic]:opponentgraveyard cdaactive autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:destroy target(land[-basic]) suspend(0)={X}{3}{R} @@ -38491,7 +38494,6 @@ toughness=2 [/card] [card] name=Flickering Ward - abilities=auraward target=creature auto=chooseacolor teach(creature) protection from(*[chosencolor]) chooseend @@ -38584,7 +38586,6 @@ toughness=1 [/card] [card] name=Floating Shield - abilities=auraward target=creature auto=chooseacolor teach(creature) protection from(*[chosencolor]) chooseend @@ -39521,6 +39522,13 @@ mana={1}{G} type=Enchantment [/card] [card] +name=Fork in the Road +auto=name(put in hand) moveto(myhand) notatarget(land[basic]|mylibrary) and!(name(put in graveyard) moveto(mygraveyard) notatarget(land[basic]|mylibrary))! oneshot +text=Search your library for up to two basic land cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library. +mana={1}{G} +type=Sorcery +[/card] +[card] name=Forked Bolt target=creature,player auto=damage:1 @@ -39548,13 +39556,6 @@ mana={R}{R} type=Instant [/card] [card] -name=Fork in the Road -auto=name(put in hand) moveto(myhand) notatarget(land[basic]|mylibrary) and!(name(put in graveyard) moveto(mygraveyard) notatarget(land[basic]|mylibrary))! oneshot -text=Search your library for up to two basic land cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library. -mana={1}{G} -type=Sorcery -[/card] -[card] name=Forlorn Pseudamma abilities=intimidate auto=@untapped(this):name(pay 2B for 2/2 Zombie) pay[[{2}{B}]] name(Pay 2B) token(Zombie,Enchantment Creature Zombie,2/2,black) controller @@ -47785,7 +47786,6 @@ toughness=3 [/card] [card] name=Hall of Triumph - auto=activatechooseacolor transforms((,newability[lord(creature[chosencolor]|mybattlefield) 1/1])) forever activatechooseend text=As Hall of Triumph enters the battlefield, choose a color. -- Creatures you control of the chosen color get +1/+1. mana={3} @@ -53868,6 +53868,14 @@ toughness=1 color=green [/card] [card] +name=Insectile Aberration +type=Creature +abilities=flying +subtype=Human Insect +power=3 +toughness=2 +[/card] +[card] name=Inside Out target=creature auto=swap @@ -54270,7 +54278,6 @@ type=Enchantment [/card] [card] name=Iona, Shield of Emeria - abilities=flying auto=chooseacolor maxCast(*[chosencolor])0 opponent chooseend text=Flying -- As Iona, Shield of Emeria enters the battlefield, choose a color. -- Your opponents can't cast spells of the chosen color. @@ -54369,7 +54376,7 @@ type=Artifact [/card] [card] name=Iron Maiden -auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent +auto=@each opponent upkeep:damage:morethanfourcards opponent text=At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={3} type=Artifact @@ -55493,7 +55500,6 @@ toughness=3 [/card] [card] name=Jihad - auto=chooseacolor transforms((,newability[aslongas(*[chosencolor]|opponentbattlefield) lord(creature[white]|mybattlefield) 2/1],newability[aslongas(*[chosencolor]|opponentbattlefield) sacrifice <1])) chooseend text=As Jihad enters the battlefield, choose a color and an opponent. -- White creatures get +2/+1 as long as the chosen player controls a nontoken permanent of the chosen color. -- When the chosen player controls no nontoken permanents of the chosen color, sacrifice Jihad. mana={W}{W}{W} @@ -57931,7 +57937,7 @@ type=Instant [card] name=Kindle target=creature,player -auto=damage:type:kindle:graveyardplus2plusend +auto=damage:plustwotype:kindle:graveyard text=Kindle deals X damage to target creature or player, where X is 2 plus the number of cards named Kindle in all graveyards. mana={1}{R} type=Instant @@ -61527,8 +61533,7 @@ toughness=5 [/card] [card] name=Lhurgoyf - -anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive +anyzone=type:creature:graveyard/plusonetype:creature:graveyard cdaactive text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. mana={2}{G}{G} type=Creature @@ -63024,7 +63029,6 @@ toughness=2 [/card] [card] name=Lord of Extinction - anyzone=type:*:graveyard/type:*:graveyard cdaactive text=Lord of Extinction's power and toughness are each equal to the number of cards in all graveyards. mana={3}{B}{G} @@ -63796,7 +63800,6 @@ type=Instant [/card] [card] name=Lurebound Scarecrow - auto=chooseacolor aslongas(*[chosencolor]|myBattlefield) sacrifice <1 chooseend text=As Lurebound Scarecrow enters the battlefield, choose a color. -- When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow. mana={3} @@ -64491,7 +64494,6 @@ toughness=6 [/card] [card] name=Magnivore - abilities=haste anyzone=type:sorcery:graveyard/type:sorcery:graveyard cdaactive text=Haste (This creature can attack the turn it comes under your control.) -- Magnivore's power and toughness are each equal to the number of sorcery cards in all graveyards. @@ -68100,7 +68102,7 @@ type=Legendary Land [card] name=Mind Burst target=player -auto=ability$!name(discard) target(*|myhandplus1plusend) reject!$ targetedplayer +auto=ability$!name(discard) target(*|myhand) reject!$ targetedplayer text=Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards. mana={1}{B} type=Sorcery @@ -70774,7 +70776,6 @@ toughness=2 [/card] [card] name=Mortivore - auto={B}:regenerate anyzone=type:creature:graveyard/type:creature:graveyard cdaactive text=Mortivore's power and toughness are each equal to the number of creature cards in all graveyards. -- {B}: Regenerate Mortivore. (The next time this creature would be destroyed this turn, it isn't. Instead tap it, remove all damage from it, and remove it from combat.) @@ -77807,7 +77808,6 @@ subtype=Equipment [/card] [card] name=Paradise Plume - auto=chooseacolor transforms((,newability[{T}:add{chosencolor}],newability[@movedto(*[chosencolor]|stack):life:1 controller])) forever chooseend text=As Paradise Plume enters the battlefield, choose a color. -- Whenever a player casts a spell of the chosen color, you may gain 1 life. -- {T}: Add one mana of the chosen color to your mana pool. mana={4} @@ -78639,7 +78639,6 @@ type=Artifact [/card] [card] name=Pentarch Paladin - abilities=flanking auto=chooseacolor {W}{W}{T}:destroy target(*[chosencolor]) chooseend text=Flanking (Whenever a creature without flanking blocks this creature, the blocking creature gets -1/-1 until end of turn.) -- As Pentarch Paladin enters the battlefield, choose a color. -- {W}{W}, {T}: Destroy target permanent of the chosen color. @@ -78651,7 +78650,6 @@ toughness=3 [/card] [card] name=Pentarch Ward - abilities=auraward target=creature auto=chooseacolor teach(creature) protection from(*[chosencolor]) chooseend @@ -81977,7 +81975,6 @@ type=Enchantment [/card] [card] name=Prism Ring - auto=activatechooseacolor transforms((,newability[@movedto(*[chosencolor]|mystack):life:1 controller])) forever activatechooseend text=As Prism Ring enters the battlefield, choose a color. -- Whenever you cast a spell of the chosen color, you gain 1 life. mana={1} @@ -82493,7 +82490,6 @@ toughness=2 [/card] [card] name=Psychic Allergy - auto=upcost[{S(island|mybattlefield)}{S(island|mybattlefield)}] sacrifice auto=chooseacolor transforms((,newability[@each opponent upkeep:damage:type:*[-token&chosencolor]:opponentbattlefield opponent])) chooseend text=As Psychic Allergy enters the battlefield, choose a color. -- At the beginning of each opponent's upkeep, Psychic Allergy deals X damage to that player, where X is the number of nontoken permanents of the chosen color he or she controls. -- At the beginning of your upkeep, destroy Psychic Allergy unless you sacrifice two Islands. @@ -83714,7 +83710,6 @@ toughness=1 [/card] [card] name=Quirion Elves - auto={T}:Add{G} auto=chooseacolor {T}:add{chosencolor} chooseend text=As Quirion Elves enters the battlefield, choose a color. -- {T}: Add {G} to your mana pool. -- {T}: Add one mana of the chosen color to your mana pool. @@ -87461,7 +87456,6 @@ toughness=3 [/card] [card] name=Revenant - abilities=flying anyzone=type:creature:mygraveyard/type:creature:mygraveyard cdaactive text=Flying -- Revenant's power and toughness are each equal to the number of creature cards in your graveyard. @@ -91655,6 +91649,17 @@ power=2 toughness=1 [/card] [card] +name=Sarkhan the Mad +auto=counter(0/0,7,loyalty) +auto={0}:name(0: reveal damage) Reveal:1 revealzone(mylibrary) revealuntil(*|mylibrary) optionone name(put in hand) target(*|reveal) moveto(myhand) optiononeend afterrevealed all(this) damage:revealedmana afterrevealedend revealend +auto={C(0/0,-2,Loyalty)}:name(-2: sacrifice) target(creature) sacrifice and!( token(Dragon,creature dragon,5/5,flying,red) targetcontroller )! +auto={C(0/0,-4,Loyalty)}:name(-4: ultimate) all(creature[dragon]|mybattlefield) transforms((,newability[target(player) dynamicability])) oneshot +text=0: Reveal the top card of your library and put it into your hand. Sarkhan the Mad deals damage to himself equal to that card's converted mana cost. -- -2: Target creature's controller sacrifices it, then that player puts a 5/5 red Dragon creature token with flying onto the battlefield. -- -4: Each Dragon creature you control deals damage equal to its power to target player. +mana={3}{B}{R} +type=Planeswalker +subtype=Sarkhan +[/card] +[card] name=Sarkhan Unbroken auto=counter(0/0,9,Loyalty) auto={C(0/0,1,Loyalty)}:name(+1: Draw card add mana) draw:1 controller && transforms((,newability[activatechooseacolor add{chosencolor} activatechooseend])) forever asSorcery @@ -91688,17 +91693,6 @@ type=Planeswalker subtype=Sarkhan [/card] [card] -name=Sarkhan the Mad -auto=counter(0/0,7,loyalty) -auto={0}:name(0: reveal damage) Reveal:1 revealzone(mylibrary) revealuntil(*|mylibrary) optionone name(put in hand) target(*|reveal) moveto(myhand) optiononeend afterrevealed all(this) damage:revealedmana afterrevealedend revealend -auto={C(0/0,-2,Loyalty)}:name(-2: sacrifice) target(creature) sacrifice and!( token(Dragon,creature dragon,5/5,flying,red) targetcontroller )! -auto={C(0/0,-4,Loyalty)}:name(-4: ultimate) all(creature[dragon]|mybattlefield) transforms((,newability[target(player) dynamicability])) oneshot -text=0: Reveal the top card of your library and put it into your hand. Sarkhan the Mad deals damage to himself equal to that card's converted mana cost. -- -2: Target creature's controller sacrifices it, then that player puts a 5/5 red Dragon creature token with flying onto the battlefield. -- -4: Each Dragon creature you control deals damage equal to its power to target player. -mana={3}{B}{R} -type=Planeswalker -subtype=Sarkhan -[/card] -[card] name=Sarkhan's Rage target=creature,player|battlefield auto=damage:5 @@ -96134,7 +96128,6 @@ subtype=Shapeshifter [/card] [card] name=Shifting Sky - auto=chooseacolor lord(*[-land]) becomes(,chosencolor) chooseend text=As Shifting Sky enters the battlefield, choose a color. -- All nonland permanents are the chosen color. mana={2}{U} @@ -97556,7 +97549,6 @@ toughness=1 [/card] [card] name=Silhana Starfletcher - abilities=reach auto=activatechooseacolor {T}:add{chosencolor} activatechooseend text=Reach (This creature can block creatures with flying.) -- As Silhana Starfletcher enters the battlefield, choose a color. -- {T}: Add one mana of the chosen color to your mana pool. @@ -99583,7 +99575,6 @@ subtype=Equipment [/card] [card] name=Slag Fiend - anyzone=type:artifact:graveyard/type:artifact:graveyard cdaactive text=Slag Fiend's power and toughness are each equal to the number of artifact cards in all graveyards. mana={R} @@ -100732,7 +100723,6 @@ toughness=3 [/card] [card] name=Sol Grail - auto=chooseacolor transforms((,newability[{T}:add{chosencolor}])) forever chooseend text=As Sol Grail enters the battlefield, choose a color. -- {T}: Add one mana of the chosen color to your mana pool. mana={3} @@ -103624,7 +103614,6 @@ subtype=Aura [/card] [card] name=Splinterfright - abilities=trample anyzone=type:creature:mygraveyard/type:creature:mygraveyard cdaactive auto=@each my upkeep:deplete:2 controller @@ -109322,7 +109311,7 @@ toughness=7 [/card] [card] name=Tarmogoyf -anyzone=gravecardtypes/gravecardtypesplus1plusend cdaactive +anyzone=gravecardtypes/plusonegravecardtypes cdaactive text=Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (The card types are artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal.) mana={1}{G} type=Creature @@ -109363,6 +109352,17 @@ power=1 toughness=1 [/card] [card] +name=Tasigur, the Golden Fang +other={delve} name(Delve) +auto={2}{GU}{GU}:deplete:2 controller && ability$! moveto(ownerhand) notatarget(*[-land]|opponentgraveyard) !$ opponent +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- {2}{GU}{GU}: Put the top two cards of your library into your graveyard, then return a nonland card of an opponent's choice from your graveyard to your hand. +mana={5}{B} +type=Legendary Creature +subtype=Human Shaman +power=4 +toughness=5 +[/card] +[card] name=Tasigur's Cruelty auto=ability$!name(discard 2 cards) target(*|myhand) reject!$ opponent text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Each opponent discards two cards. @@ -109676,7 +109676,6 @@ type=Legendary Land [/card] [card] name=Teferi's Moat - auto=chooseacolor lord(creature[chosencolor&-flying]|opponentBattlefield) cantattack chooseend text=As Teferi's Moat enters the battlefield, choose a color. -- Creatures of the chosen color without flying can't attack you. mana={3}{W}{U} @@ -110427,7 +110426,6 @@ type=Artifact [/card] [card] name=Terravore - abilities=trample anyzone=type:land:graveyard/type:land:graveyard cdaactive text=Trample -- Terravore's power and toughness are each equal to the number of land cards in all graveyards. @@ -116278,7 +116276,6 @@ type=Artifact [/card] [card] name=Umbra Stalker - anyzone=type:manab:mygraveyard/type:manab:mygraveyard cdaactive text=Chroma - Umbra Stalker's power and toughness are each equal to the number of black mana symbols in the mana costs of cards in your graveyard. mana={4}{B}{B}{B} @@ -120128,7 +120125,7 @@ toughness=3 [/card] [card] name=Viseling -auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent +auto=@each opponent upkeep:damage:morethanfourcards opponent text=At the beginning of each opponent's upkeep, Viseling deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={4} type=Artifact Creature @@ -120203,7 +120200,7 @@ type=Instant [/card] [card] name=Vitalizing Cascade -auto=life:Xplus3plusend +auto=life:Xplusthree text=You gain X plus 3 life. mana={X}{G}{W} type=Instant @@ -120461,7 +120458,6 @@ toughness=2 [/card] [card] name=Voice of All - abilities=flying auto=chooseacolor transforms((,newability[protection from(*[chosencolor])],newability[0/0])) forever chooseend text=Flying (This creature can't be blocked except by creatures with flying or reach.) -- As Voice of All enters the battlefield, choose a color. -- Voice of All has protection from the chosen color. (It can't be blocked, targeted, dealt damage, or enchanted by anything of the chosen color.) @@ -121955,7 +121951,7 @@ toughness=4 [card] name=Wall of Tombstones abilities=defender -auto=@each my upkeep:transforms((,settoughness=type:creature:mygraveyardplus1plusend)) forever +auto=@each my upkeep:transforms((,settoughness=plusonetype:creature:mygraveyard)) forever text=Defender (This creature can't attack.) -- At the beginning of your upkeep, Wall of Tombstones's toughness becomes 1 plus the number of creature cards in your graveyard. (This effect lasts indefinitely.) mana={1}{B} type=Creature @@ -122343,7 +122339,6 @@ toughness=1 [/card] [card] name=Ward Sliver - auto=chooseacolor transforms((,newability[lord(sliver) protection from(*[chosencolor])])) forever chooseend text=As Ward Sliver enters the battlefield, choose a color. -- All Slivers have protection from the chosen color. mana={4}{W} @@ -126579,6 +126574,16 @@ power=3 toughness=3 [/card] [card] +name=Yisan, the Wanderer Bard +auto={2}{G}{T}{C(0/0,1,Verse)}:name(search creature) Reveal:type:*:mylibrary revealzone(mylibrary) revealtype(*[creature]|mylibrary) optionone target(creature[manacost=counter{0%0.1.Verse}]|reveal) moveto(mybattlefield) and!( all(*|reveal) moveto(mylibrary) )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(mylibrary) and!( all(*|reveal) moveto(mylibrary) )! optiontwoend afterrevealed shuffle afterrevealedend revealend +text={2}{G}, {T}, Put a verse counter on Yisan, the Wanderer Bard: Search your library for a creature card with converted mana cost equal to the number of verse counters on Yisan, put it onto the battlefield, then shuffle your library. +mana={2}{G} +type=Legendary Creature +subtype=Human Rogue +power=2 +toughness=3 +[/card] +[card] name=Yoke of the Damned target=creature auto=@movedTo(graveyard) from(creature|battlefield):destroy @@ -126741,6 +126746,17 @@ power=2 toughness=1 [/card] [card] +name=Zameck Guildmage +auto={G}{U}:name(1/1 counters) emblem transforms((,newability[@movedto(creature|myBattlefield):all(trigger[to]) counter(1/1.1)])) ueot +auto={G}{U}{C(1/1,-1),*|mybattlefield}:name(remove a 1/1 counter) draw:1 +text={G}{U}: This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it. -- {G}{U}, Remove a +1/+1 counter from a creature you control: Draw a card. +mana={G}{U} +type=Creature +subtype=Elf Wizard +power=2 +toughness=2 +[/card] +[card] name=Zanam Djinn abilities=flying auto=this(variable{commonblue}>0) -2/-2 @@ -127539,46 +127555,6 @@ subtype=Orc Warrior power=7 toughness=2 [/card] -###### -######unsorted -[card] -name=Dark Suspicions -auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] -name=Bulwark -auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] -name=Roiling Horror -anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive -autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -suspend(0)={X}{b}{b}{b} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] -name=Dark Deal -auto=count(type:*:myhand) -auto=all(*|myhand) reject -auto=draw:countedamountplus1plusend controller -auto=count(type:*:opponenthand) -auto=all(*|opponenthand) reject -auto=draw:countedamountplus1plusend opponent -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index a59319600..853855c96 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -4005,15 +4005,6 @@ mana={2}{B} type=Sorcery [/card] [card] -name=Delver of Secrets -text=At the beginning of your upkeep, look at the top card of your library. You may reveal that card. If an instant or sorcery card is revealed this way, transform Delver of Secrets. -mana={U} -type=Creature -subtype=Human Wizard -power=1 -toughness=1 -[/card] -[card] name=Dementia Sliver text=All Slivers have "{T}: Name a card. Target opponent reveals a card at random from his or her hand. If it's the named card, that player discards it. Activate this ability only during your turn." mana={3}{U}{B} @@ -17769,15 +17760,6 @@ mana={1}{W} type=Sorcery [/card] [card] -name=Tasigur, the Golden Fang -text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- {2}{GU}{GU}: Put the top two cards of your library into your graveyard, then return a nonland card of an opponent's choice from your graveyard to your hand. -mana={5}{B} -type=Legendary Creature -subtype=Human Shaman -power=4 -toughness=5 -[/card] -[card] name=Task Mage Assembly text=When there are no creatures on the battlefield, sacrifice Task Mage Assembly. -- {2}: Task Mage Assembly deals 1 damage to target creature. Any player may activate this ability but only any time he or she could cast a sorcery. mana={2}{R} @@ -20322,24 +20304,6 @@ power=3 toughness=6 [/card] [card] -name=Yisan, the Wanderer Bard -text={2}{G}, {T}, Put a verse counter on Yisan, the Wanderer Bard: Search your library for a creature card with converted mana cost equal to the number of verse counters on Yisan, put it onto the battlefield, then shuffle your library. -mana={2}{G} -type=Legendary Creature -subtype=Human Rogue -power=2 -toughness=3 -[/card] -[card] -name=Yixlid Jailer -text=Cards in graveyards lose all abilities. -mana={1}{B} -type=Creature -subtype=Zombie Wizard -power=2 -toughness=1 -[/card] -[card] name=Yosei, the Morning Star text=Flying -- When Yosei, the Morning Star dies, target player skips his or her next untap step. Tap up to five target permanents that player controls. mana={4}{W}{W} @@ -20382,15 +20346,6 @@ power=3 toughness=3 [/card] [card] -name=Zameck Guildmage -text={G}{U}: This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it. -- {G}{U}, Remove a +1/+1 counter from a creature you control: Draw a card. -mana={G}{U} -type=Creature -subtype=Elf Wizard -power=2 -toughness=2 -[/card] -[card] name=Zealous Inquisitor text={1}{W}: The next 1 damage that would be dealt to Zealous Inquisitor this turn is dealt to target creature instead. mana={2}{W} From 5cdcf4799463caeee533c31e4de712c84c334958 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Wed, 6 Jul 2016 18:08:33 -0400 Subject: [PATCH 7/9] merged my changes to the base --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 62 ++++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 5a8969ebb..8e9c0ad75 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1043,7 +1043,7 @@ type=Enchantment [/card] [card] name=AEther Burst -target=creature|battlefield +target=creature|battlefield auto=moveto(ownerhand) text=Return up to X target creatures to their owners' hands, where X is one plus the number of cards named AEther Burst in all graveyards as you cast AEther Burst. mana={1}{U} @@ -3677,7 +3677,7 @@ toughness=1+* [/card] [card] name=An-Havva Inn -auto=life:plusonetype:creature[green]|battlefield controller +auto=life:type:creature[green]|battlefieldplus1plusend controller text=You gain X plus 1 life, where X is the number of green creatures on the battlefield. mana={1}{G}{G} type=Sorcery @@ -10126,7 +10126,7 @@ type=Sorcery [card] name=Black Vise auto=name(choose opponent) notatarget(opponent) deplete:0 -auto=@each targetedplayer upkeep:damage:morethanfourcards targetedplayer +auto=@each targetedplayer upkeep:damage:type:*:opponenthandminus4minusend targetedplayer text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={1} type=Artifact @@ -54376,7 +54376,7 @@ type=Artifact [/card] [card] name=Iron Maiden -auto=@each opponent upkeep:damage:morethanfourcards opponent +auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent text=At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={3} type=Artifact @@ -57937,7 +57937,7 @@ type=Instant [card] name=Kindle target=creature,player -auto=damage:plustwotype:kindle:graveyard +auto=damage:type:kindle:graveyardplus2plusend text=Kindle deals X damage to target creature or player, where X is 2 plus the number of cards named Kindle in all graveyards. mana={1}{R} type=Instant @@ -61533,7 +61533,7 @@ toughness=5 [/card] [card] name=Lhurgoyf -anyzone=type:creature:graveyard/plusonetype:creature:graveyard cdaactive +anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. mana={2}{G}{G} type=Creature @@ -68102,7 +68102,7 @@ type=Legendary Land [card] name=Mind Burst target=player -auto=ability$!name(discard) target(*|myhand) reject!$ targetedplayer +auto=ability$!name(discard) target(*|myhandplus1plusend) reject!$ targetedplayer text=Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards. mana={1}{B} type=Sorcery @@ -109311,7 +109311,7 @@ toughness=7 [/card] [card] name=Tarmogoyf -anyzone=gravecardtypes/plusonegravecardtypes cdaactive +anyzone=gravecardtypes/gravecardtypesplus1plusend cdaactive text=Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (The card types are artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal.) mana={1}{G} type=Creature @@ -120125,7 +120125,7 @@ toughness=3 [/card] [card] name=Viseling -auto=@each opponent upkeep:damage:morethanfourcards opponent +auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent text=At the beginning of each opponent's upkeep, Viseling deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={4} type=Artifact Creature @@ -120200,7 +120200,7 @@ type=Instant [/card] [card] name=Vitalizing Cascade -auto=life:Xplusthree +auto=life:Xplus3plusend text=You gain X plus 3 life. mana={X}{G}{W} type=Instant @@ -121951,7 +121951,7 @@ toughness=4 [card] name=Wall of Tombstones abilities=defender -auto=@each my upkeep:transforms((,settoughness=plusonetype:creature:mygraveyard)) forever +auto=@each my upkeep:transforms((,settoughness=type:creature:mygraveyardplus1plusend)) forever text=Defender (This creature can't attack.) -- At the beginning of your upkeep, Wall of Tombstones's toughness becomes 1 plus the number of creature cards in your graveyard. (This effect lasts indefinitely.) mana={1}{B} type=Creature @@ -127555,6 +127555,46 @@ subtype=Orc Warrior power=7 toughness=2 [/card] +###### +######unsorted +[card] +name=Dark Suspicions +auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] +name=Bulwark +auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] +name=Roiling Horror +anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive +autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +suspend(0)={X}{b}{b}{b} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] +name=Dark Deal +auto=count(type:*:myhand) +auto=all(*|myhand) reject +auto=draw:countedamountplus1plusend controller +auto=count(type:*:opponenthand) +auto=all(*|opponenthand) reject +auto=draw:countedamountplus1plusend opponent +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] From 867e1b87313b094e4b48de18fa487a0c11371ba7 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Wed, 6 Jul 2016 18:24:45 -0400 Subject: [PATCH 8/9] fixes --- projects/mtg/src/MTGRules.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 657a54cf6..15783bf81 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1053,7 +1053,7 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { return 0; } - auto retraceCost = card->getManaCost()->getRetrace(); + ManaCost * retraceCost = card->getManaCost()->getRetrace(); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1378,7 +1378,6 @@ int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) } ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); ManaCost * newCost = card->computeNewCost(card, cost, cost); - SAFE_DELETE(cost); if (newCost->extraCosts) for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) { From 7b8b197a358400617b8a30a2c0d596be172a6c3b Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Wed, 6 Jul 2016 19:08:41 -0400 Subject: [PATCH 9/9] another fix --- projects/mtg/src/MTGRules.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 15783bf81..6fbf93c05 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1459,8 +1459,6 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card) { if (!isReactingToClick(card)) return 0; - - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); ManaCost * newCost = card->getManaCost()->getAlternative(); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++)