From 0ff7e54ff466809a8a33f7ff4c2a0326b1d8b976 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Thu, 7 Jul 2016 20:47:25 -0400 Subject: [PATCH 01/13] this is a good enough fix as waste is colorless which is artifact, and all we do is barrow the kbitmask from land. --- projects/mtg/src/CardPrimitive.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 0ed61cd68..bddc43ed4 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -426,6 +426,9 @@ uint8_t CardPrimitive::ConvertColorToBitMask(int inColor) case Constants::MTG_COLOR_LAND: value = kColorBitMask_Land; break; + case Constants::MTG_COLOR_WASTE://the true colorless mana shares the kbitmask of land. kbitmask dictates the color of the quad(no image boarder), and the symbol. nothing more. + value = kColorBitMask_Land; + break; default: break; From c0c52e57df8c7922e512dbca2a9776d65d933e27 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Fri, 8 Jul 2016 17:48:27 -0400 Subject: [PATCH 02/13] what a dumb typo. surprised it was in the engine that way for so long. --- projects/mtg/include/AllAbilities.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 1abaf0276..6d677c33b 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -6160,7 +6160,7 @@ public: { if(forceDestroy != -1) return 1; - if(!(source->hasType(Subtypes::TYPE_INSTANT)||source->hasType(Subtypes::TYPE_INSTANT)) && !source->isInPlay(game)) + if(!(source->hasType(Subtypes::TYPE_INSTANT)||source->hasType(Subtypes::TYPE_SORCERY)) && !source->isInPlay(game)) return 1; return 0; } From ee91e0698de85cc9da65f2f81c2dbeb4ef8b4b39 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 00:11:21 -0400 Subject: [PATCH 03/13] corrected some logic with computenewcost. there is a bug im working on with newaffinity and cards that contain targetchoosers with CD tcs. experimental change also added with lords. im making the abilities grants by lord forcedalive until the lord is removed from game. some instances of forcedalive in master primitives did not contain abilities which resolved, meaning they would contenue even though the source had left play. --- projects/mtg/include/AllAbilities.h | 2 ++ projects/mtg/src/GameObserver.cpp | 5 +++-- projects/mtg/src/MTGCardInstance.cpp | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 6d677c33b..392c89eb4 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -3256,6 +3256,7 @@ public: } else { + a->forcedAlive = 1; a->addToGame(); abilities[d] = a; } @@ -3278,6 +3279,7 @@ public: if (abilities.find(card) != abilities.end() && !(forceDestroy == -1 && forcedAlive == 1)) //only embelms have forcedestroy = -1 and forcedalive = 1 { + abilities[card]->forcedAlive = 0; game->removeObserver(abilities[card]); abilities.erase(card); } diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 3d65cd041..28801ae3c 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1079,7 +1079,8 @@ void GameObserver::Affinity() } } } - //////////////////////////// + + /////////////////////// bool NewAffinityFound = false; for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) { @@ -1114,7 +1115,7 @@ void GameObserver::Affinity() //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(); + ManaCost *newCost = NEW ManaCost(); newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost())); card->getManaCost()->copy(newCost); SAFE_DELETE(newCost); diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index e5fc325fe..9fcbee96d 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -970,6 +970,14 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos string type = ""; ManaCost * original = NEW ManaCost(); original->copy(Data); + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost()) {//start1 if (card->getIncreasedManaCost()->getConvertedCost()) @@ -1076,6 +1084,13 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos Cost->extraCosts->costs[i]->setSource(card); } } + 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)) { From 14f65c55b5c627374c3ba19f567670ff7c3b08ef Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 00:48:08 -0400 Subject: [PATCH 04/13] going to try only updating affinity() when cards move from anywhere to anywhere to help minimize the calls to this function. this atleast allows me to debug albeit slowly the follow issue ive been working to fix. not sure when this was introduced but it was not happening when i first coded this function. manacost->copy() did not slow the game to a crawl. anyways, trinisphere and any card containing other={H(land[basic]|mybattlefield)}{1} name(Pay /1/ and Return a Basic Land to Hand) cost such as this with a CD tc. --- projects/mtg/include/GameObserver.h | 1 + projects/mtg/src/GameObserver.cpp | 33 +++++++++++++++++------------ projects/mtg/src/MTGGameZones.cpp | 1 + 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 0e1a096eb..6b5fddb79 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -124,6 +124,7 @@ class GameObserver{ void gameStateBasedEffects(); void enchantmentStatus(); void Affinity(); + bool AffinityNeedsUpdate; void addObserver(MTGAbility * observer); bool removeObserver(ActionElement * observer); void startGame(GameType, Rules * rules); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 28801ae3c..9db6fbdb9 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -53,6 +53,7 @@ void GameObserver::cleanup() actionsList.clear(); gameTurn.clear(); OpenedDisplay = NULL; + AffinityNeedsUpdate = false; } GameObserver::~GameObserver() @@ -1092,20 +1093,22 @@ void GameObserver::Affinity() 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) + //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; + if(!AffinityNeedsUpdate)//we only adjust cost when cards move from anywhere to anywhere. 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 @@ -1117,6 +1120,7 @@ void GameObserver::Affinity() 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()) @@ -1171,6 +1175,7 @@ void GameObserver::Affinity() }//end } } + AffinityNeedsUpdate = false; } void GameObserver::Render() diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 8e995dd69..18e697aba 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -328,6 +328,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone bool shufflelibrary = card->basicAbilities[(int)Constants::SHUFFLELIBRARYDEATH]; bool inplaytoinplay = false; bool ripToken = false; + g->AffinityNeedsUpdate = true;//we refresh affinity whenever a card is moved from anywhere to anywhere. if (g->players[0]->game->battlefield->hasName("Rest in Peace")||g->players[1]->game->battlefield->hasName("Rest in Peace")) ripToken = true; //Madness or Put in Play... From b5976035e37d1addf707b41055638d5863873340 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 00:58:19 -0400 Subject: [PATCH 05/13] actually i changed my mind, instead lets update affinity after events are processed, that should take into account cards untapping,moving, ect.... --- projects/mtg/src/GameObserver.cpp | 3 ++- projects/mtg/src/MTGGameZones.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 9db6fbdb9..993c9d900 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1108,7 +1108,7 @@ void GameObserver::Affinity() // DoReduceIncrease = true; //if (!DoReduceIncrease) // continue; - if(!AffinityNeedsUpdate)//we only adjust cost when cards move from anywhere to anywhere. + if(!AffinityNeedsUpdate)//we only adjust cost when events queqes are complete. 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 @@ -1585,6 +1585,7 @@ int GameObserver::receiveEvent(WEvent * e) SAFE_DELETE(ev); eventsQueue.pop(); } + AffinityNeedsUpdate = true; return result; } diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 18e697aba..8e995dd69 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -328,7 +328,6 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone bool shufflelibrary = card->basicAbilities[(int)Constants::SHUFFLELIBRARYDEATH]; bool inplaytoinplay = false; bool ripToken = false; - g->AffinityNeedsUpdate = true;//we refresh affinity whenever a card is moved from anywhere to anywhere. if (g->players[0]->game->battlefield->hasName("Rest in Peace")||g->players[1]->game->battlefield->hasName("Rest in Peace")) ripToken = true; //Madness or Put in Play... From f82bc394732ea581750fbfb74fa5ffcba6f77b76 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 01:24:55 -0400 Subject: [PATCH 06/13] ok found the massive draw, it was trenisphere. the card lords every single card in the game a mana modifier. affinity normally didnt see these issues cause the cards effected are just either in your hand or the source themselves. but when trin was put in play it would cause 120 cards to have to update thier cost, which can not be done in acceptible cpu time. anyways, this should solve the issue. that card is a desaster, please do not add any more code to support it, though with it in its current state im wondering why its not in supported and is placed in borderline. --- projects/mtg/src/GameObserver.cpp | 56 +++++++++++++++++++------------ 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 993c9d900..37736c980 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1080,7 +1080,23 @@ void GameObserver::Affinity() } } } - + ///we handle trisnisphere seperately because its a desaster. + 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; + } + } /////////////////////// bool NewAffinityFound = false; for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) @@ -1093,28 +1109,26 @@ void GameObserver::Affinity() 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; - if(!AffinityNeedsUpdate)//we only adjust cost when events queqes are complete. + 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->getIncreasedManaCost()->getConvertedCost() || + card->getReducedManaCost()->getConvertedCost() || + NewAffinityFound) + && + AffinityNeedsUpdate + ) + 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(); From 2e928383647af7fbfda223261d2d47f9b51668a5 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 11:38:25 -0400 Subject: [PATCH 07/13] fixed an issue with dredge, where dredge is offered even though theres only one dredger on cards that draw multiple. --- projects/mtg/src/MTGRules.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 1af7ac8bc..5da180505 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -2775,8 +2775,12 @@ WEvent * MTGDredgeRule::replace(WEvent * event) if (e->player == p) { int Dredgers = 0; + vectormenusOfferedWithDredge; for(int draw = 0;draw < e->nb_cards;draw++) { + tcb = tf.createTargetChooser("dredgeable", card); + int toDredge = tcb->countValidTargets(); + SAFE_DELETE(tcb); vectorselection; //look for other draw replacement effects list::iterator it; @@ -2800,17 +2804,16 @@ WEvent * MTGDredgeRule::replace(WEvent * event) } } + int Choices = int(selection.size()); //there is a memleak here that i have no idea what causes it. got it reduced to just 4 bytes but its still bothering me. - if (Dredgers < e->nb_cards) + if (int(menusOfferedWithDredge.size()) < toDredge) { tcb = tf.createTargetChooser("dredgeable", card); tcb->targetter = NULL; - dredgeAbility = NEW dredgeCard(game, game->mLayers->actionLayer()->getMaxId(), card, NULL); dredgeAbility->oneShot = true; dredgeAbility->canBeInterrupted = false; - targetAbility = NEW GenericTargetAbility(game, "Dredge A Card", "", game->mLayers->actionLayer()->getMaxId(), card, tcb->clone(), dredgeAbility->clone()); - SAFE_DELETE(tcb); + targetAbility = NEW GenericTargetAbility(game, "Dredge A Card", "", game->mLayers->actionLayer()->getMaxId(), card, tcb, dredgeAbility->clone()); SAFE_DELETE(dredgeAbility); targetAbility->oneShot = true; targetAbility->canBeInterrupted = false; @@ -2820,18 +2823,21 @@ WEvent * MTGDredgeRule::replace(WEvent * event) MTGAbility * setDredge = targetAbilityAdder->clone(); SAFE_DELETE(targetAbilityAdder); setDredge->oneShot = true; - selection.push_back(setDredge); - targetAbility1 = NEW AADrawer(game, this->GetId(), card, card, NULL, "1", TargetChooser::CONTROLLER, true); - targetAbility1->canBeInterrupted = false; - selection.push_back(targetAbility1); - MTGAbility * menuChoice = NEW MenuAbility(game, this->GetId(), card, card, true, selection, card->controller(), "Dredge or Draw"); - - menuChoice->addToGame(); - } + targetAbility1 = NEW AADrawer(game, this->GetId(), card, card, NULL, "1", TargetChooser::CONTROLLER, true); + targetAbility1->canBeInterrupted = false; + selection.push_back(targetAbility1); + MTGAbility * menuChoice = NEW MenuAbility(game, this->GetId(), card, card, true, selection, card->controller(), "Dredge or Draw"); + menusOfferedWithDredge.push_back(menuChoice); } - + + while (menusOfferedWithDredge.size()) + { + menusOfferedWithDredge[0]->addToGame(); + menusOfferedWithDredge.erase(menusOfferedWithDredge.begin()); + } + SAFE_DELETE(event); return event; } From a8cbdafe6ebe76ac68ebb806159e17e38e4e3061 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 13:12:58 -0400 Subject: [PATCH 08/13] unused variables. --- 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 5da180505..2cab2b17f 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -2774,7 +2774,6 @@ WEvent * MTGDredgeRule::replace(WEvent * event) Player * p = game->players[i]; if (e->player == p) { - int Dredgers = 0; vectormenusOfferedWithDredge; for(int draw = 0;draw < e->nb_cards;draw++) { @@ -2804,7 +2803,6 @@ WEvent * MTGDredgeRule::replace(WEvent * event) } } - int Choices = int(selection.size()); //there is a memleak here that i have no idea what causes it. got it reduced to just 4 bytes but its still bothering me. if (int(menusOfferedWithDredge.size()) < toDredge) { From d247c53136c42e24e950b0e843111c8420306178 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 17:55:08 -0400 Subject: [PATCH 09/13] edge case fix, the issue arises from castcard but I'm fixing it at a higher level since init to zone should always have a valid "player 1" in its first constructor. --- projects/mtg/bin/Res/player/premade/deck1.txt | 18 +++--------------- projects/mtg/bin/Res/sets/primitives/mtg.txt | 15 +++++---------- projects/mtg/bin/Res/test/_tests.txt | 1 + projects/mtg/src/MTGGameZones.cpp | 6 +++++- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/projects/mtg/bin/Res/player/premade/deck1.txt b/projects/mtg/bin/Res/player/premade/deck1.txt index ef32db48a..9d374e7ad 100644 --- a/projects/mtg/bin/Res/player/premade/deck1.txt +++ b/projects/mtg/bin/Res/player/premade/deck1.txt @@ -1,19 +1,7 @@ #NAME:Premade G/R #DESC:A Red/Green deck with simple mechanics to get you started. We recommend you create your own decks to get the full Wagic experience! -Forest (10E) *11 -Mountain (10E) *12 - -Aggressive Urge (10E) *4 -Wall of Wood (10E) *4 -Llanowar Elves (10E) *4 -Mirri, Cat Warrior (10E) -Scion of the Wild (10E) *4 -Primal Rage (10E) *2 - -Lightning Elemental (10E) *4 -Shock (10E) *4 -Firebreathing (10E) *2 -Raging Goblin (10E) *4 -Anaba Bodyguard (10E) *4 +arbor elf *25 +Arbiter of Knollridge *13 +Arbor Colossus *13 diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 508697533..ab02f2be9 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -4288,20 +4288,15 @@ toughness=5 [/card] [card] name=Arbor Colossus -abilities=reach -auto=this(cantargetcard(*[-monstrous]) {3}{G}{G}{G}:becomes(monstrous) forever && counter(1/1,3) && transforms((,newAbility[destroy target(creature[flying]|opponentbattlefield)])) forever -text=Reach -- {3}{G}{G}{G}: Monstrosity 3. (If this creature isn't monstrous, put three +1/+1 counters on it and it becomes monstrous.) -- When Arbor Colossus becomes monstrous, destroy target creature with flying an opponent controls -mana={2}{G}{G}{G} -type=Creature -subtype=Giant -power=6 -toughness=6 +auto=draw:2 +type=instant [/card] [card] name=Arbor Elf -auto={t}:untap target(forest) +autohand={0}:name(Control Magic) activate castcard(normal named!:Control Magic:!) text={T}: Untap target Forest. -mana={G} +mana={g} +dredge=dredge(2) type=Creature subtype=Elf Druid power=1 diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index dc83fac83..b8cfe6b9c 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -1,3 +1,4 @@ +savor the moment.txt ######################## #Internal tests ######################## diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 8e995dd69..5e664c3f8 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -980,7 +980,11 @@ void MTGInPlay::untapAll() MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) { - + if (p2 != p && p2 && (p != p2->opponent())) + { + p = p2->opponent(); + //these cases are generally handled this is a edge case fix. + } switch (zoneId) { case MY_GRAVEYARD: From 78e4407c717fca08a8d4da2cb0027ef821dd4240 Mon Sep 17 00:00:00 2001 From: zethfox Date: Sat, 9 Jul 2016 18:21:52 -0400 Subject: [PATCH 10/13] Revert "edge case fix, the issue arises from castcard but I'm fixing it at a higher level since init to zone should always have a valid "player 1" in its first constructor." This reverts commit d247c53136c42e24e950b0e843111c8420306178. --- projects/mtg/bin/Res/player/premade/deck1.txt | 18 +++++++++++++++--- projects/mtg/bin/Res/sets/primitives/mtg.txt | 15 ++++++++++----- projects/mtg/bin/Res/test/_tests.txt | 1 - projects/mtg/src/MTGGameZones.cpp | 6 +----- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/projects/mtg/bin/Res/player/premade/deck1.txt b/projects/mtg/bin/Res/player/premade/deck1.txt index 9d374e7ad..ef32db48a 100644 --- a/projects/mtg/bin/Res/player/premade/deck1.txt +++ b/projects/mtg/bin/Res/player/premade/deck1.txt @@ -1,7 +1,19 @@ #NAME:Premade G/R #DESC:A Red/Green deck with simple mechanics to get you started. We recommend you create your own decks to get the full Wagic experience! -arbor elf *25 +Forest (10E) *11 +Mountain (10E) *12 + +Aggressive Urge (10E) *4 +Wall of Wood (10E) *4 +Llanowar Elves (10E) *4 +Mirri, Cat Warrior (10E) +Scion of the Wild (10E) *4 +Primal Rage (10E) *2 + +Lightning Elemental (10E) *4 +Shock (10E) *4 +Firebreathing (10E) *2 +Raging Goblin (10E) *4 +Anaba Bodyguard (10E) *4 -Arbiter of Knollridge *13 -Arbor Colossus *13 diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index ab02f2be9..508697533 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -4288,15 +4288,20 @@ toughness=5 [/card] [card] name=Arbor Colossus -auto=draw:2 -type=instant +abilities=reach +auto=this(cantargetcard(*[-monstrous]) {3}{G}{G}{G}:becomes(monstrous) forever && counter(1/1,3) && transforms((,newAbility[destroy target(creature[flying]|opponentbattlefield)])) forever +text=Reach -- {3}{G}{G}{G}: Monstrosity 3. (If this creature isn't monstrous, put three +1/+1 counters on it and it becomes monstrous.) -- When Arbor Colossus becomes monstrous, destroy target creature with flying an opponent controls +mana={2}{G}{G}{G} +type=Creature +subtype=Giant +power=6 +toughness=6 [/card] [card] name=Arbor Elf -autohand={0}:name(Control Magic) activate castcard(normal named!:Control Magic:!) +auto={t}:untap target(forest) text={T}: Untap target Forest. -mana={g} -dredge=dredge(2) +mana={G} type=Creature subtype=Elf Druid power=1 diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index b8cfe6b9c..dc83fac83 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -1,4 +1,3 @@ -savor the moment.txt ######################## #Internal tests ######################## diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 5e664c3f8..8e995dd69 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -980,11 +980,7 @@ void MTGInPlay::untapAll() MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) { - if (p2 != p && p2 && (p != p2->opponent())) - { - p = p2->opponent(); - //these cases are generally handled this is a edge case fix. - } + switch (zoneId) { case MY_GRAVEYARD: From fdde5b7fe90b78b027046ec2639f77914f125d53 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 18:57:01 -0400 Subject: [PATCH 11/13] ok round 3 --- projects/mtg/src/MTGGameZones.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 8e995dd69..5e664c3f8 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -980,7 +980,11 @@ void MTGInPlay::untapAll() MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) { - + if (p2 != p && p2 && (p != p2->opponent())) + { + p = p2->opponent(); + //these cases are generally handled this is a edge case fix. + } switch (zoneId) { case MY_GRAVEYARD: From c4581a8889a324a3860dbf7932c4494a91dde393 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 20:20:55 -0400 Subject: [PATCH 12/13] added imprintedcard as a usable name for castcard --- projects/mtg/src/AllAbilities.cpp | 7 +++++++ projects/mtg/src/MTGAbility.cpp | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 6b84b1c13..af883cebe 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -7189,6 +7189,13 @@ void AACastCard::Update(float dt) return; if(cardNamed.size() && !theNamedCard) { + if (cardNamed.find("imprintedcard") != string::npos) + { + if (source && source->currentimprintName.size()) + { + cardNamed = source->currentimprintName; + } + } theNamedCard = makeCard(); } if(putinplay) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 49eeab63a..dbd525a22 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2503,9 +2503,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG found = s.find("imprint"); if (found != string::npos) { - MTGAbility * a = NEW AAImprint(observer, id, card, target); - a->oneShot = 1; - return a; + if (s.find("imprintedcard") == string::npos) + { + MTGAbility * a = NEW AAImprint(observer, id, card, target); + a->oneShot = 1; + return a; + } } //phaseout From 8b70f5a1149110a91ca2d3171216f541a07986f1 Mon Sep 17 00:00:00 2001 From: zethfoxster Date: Sat, 9 Jul 2016 20:21:40 -0400 Subject: [PATCH 13/13] added isochron and spell binder --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 508697533..2a7fee682 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -54596,6 +54596,14 @@ power=4 toughness=8 [/card] [card] +name=Isochron Scepter +auto=may imprint notatarget(instant[manacost<=2]|myhand) +auto={2}{t}:activate castcard(copied noevent named!:imprintedcard:!) +text=Imprint — When Isochron Scepter enters the battlefield, you may exile an instant card with converted mana cost 2 or less from your hand. -- {2}, {T}: You may copy the exiled card. If you do, you may cast the copy without paying its mana cost. +mana={2} +type=Artifact +[/card] +[card] name=Isolated Chapel auto=aslongas(plains,swamp|myBattlefield) tap(noevent) <1 oneshot auto={T}:Add{W} @@ -102430,6 +102438,16 @@ power=2 toughness=2 [/card] [card] +name=Spellbinder +auto={4}:equip +auto=may imprint notatarget(instant|myhand) +auto=@combatdamaged(player) from(mytgt):activate castcard(copied noevent named!:imprintedcard:!) +text=Imprint — When Spellbinder enters the battlefield, you may exile an instant card from your hand. -- Whenever equipped creature deals combat damage to a player, you may copy the exiled card. If you do, you may cast the copy without paying its mana cost. -- Equip {4} +mana={3} +type=Artifact +subtype=Equipment +[/card] +[card] name=Spell Blast target=*[manacost=prex]|stack auto=fizzle