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 diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 1abaf0276..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); } @@ -6160,7 +6162,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; } 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/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/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; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 3d65cd041..37736c980 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() @@ -1079,7 +1080,24 @@ 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++) { @@ -1092,30 +1110,31 @@ void GameObserver::Affinity() } } bool DoReduceIncrease = false; - if (card->has(Constants::AFFINITYARTIFACTS) || + 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) + && + 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(); - 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); if (card->getManaCost()->getAlternative()) @@ -1170,6 +1189,7 @@ void GameObserver::Affinity() }//end } } + AffinityNeedsUpdate = false; } void GameObserver::Render() @@ -1579,6 +1599,7 @@ int GameObserver::receiveEvent(WEvent * e) SAFE_DELETE(ev); eventsQueue.pop(); } + AffinityNeedsUpdate = true; return result; } 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 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)) { 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: diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 1af7ac8bc..2cab2b17f 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -2774,9 +2774,12 @@ 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++) { + tcb = tf.createTargetChooser("dredgeable", card); + int toDredge = tcb->countValidTargets(); + SAFE_DELETE(tcb); vectorselection; //look for other draw replacement effects list::iterator it; @@ -2801,16 +2804,14 @@ WEvent * MTGDredgeRule::replace(WEvent * event) } //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 +2821,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; }