diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 392c89eb4..5681d7994 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -6208,6 +6208,7 @@ class AACascade: public ActivatedAbility { public: string nbcardsStr; + MTGCardInstance * castingThis; vectorselectedCards; vectoroldOrder; vectornewOrder; diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 6b5fddb79..2f520043c 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -133,6 +133,7 @@ class GameObserver{ int isInPlay(MTGCardInstance * card); int isInGrave(MTGCardInstance * card); int isInExile(MTGCardInstance * card); + int isInHand(MTGCardInstance * card); virtual void Update(float dt); void Render(); void ButtonPressed(PlayGuiObject*); diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 4a59bb206..b06b2e656 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -92,6 +92,7 @@ public: bool isPhased; bool isCascaded; int phasedTurn; + bool handEffects; bool graveEffects; bool exileEffects; bool suspended; diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index 4262b0624..c1f792a09 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -104,6 +104,9 @@ int OrderedAIAction::getEfficiency() { target = a->source; } + + if (AACastCard * CC = dynamic_cast (a)) + return 99; switch (a->aType) { diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 0369afc0c..e5ced563c 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1143,76 +1143,97 @@ AACascade::AACascade(GameObserver* observer, int _id, MTGCardInstance * _source, selectedCards.clear(); oldOrder.clear(); newOrder.clear(); + castingThis = NULL; } - int AACascade::resolve() +int AACascade::resolve() +{ + Player * player = source->controller(); + if (!player) + return 0; + WParsedInt numCards(nbcardsStr, NULL, source); + MTGLibrary * library = player->game->library; + MTGRemovedFromGame * exile = player->game->exile; + MTGCardInstance * viable = NULL; + int counter = 0; + bool found = false; + for (int i = 0; i < numCards.getValue(); i++) { - Player * player = source->controller(); - if (player) + //*//*//*// + if (found) + continue; + ////////////////////////////////////////////// + if (!library->nb_cards) + continue; + ////////////////////////////////////////////// + while (library->nb_cards && !found) { - WParsedInt numCards(nbcardsStr, NULL, source); - MTGLibrary * library = player->game->library; - MTGRemovedFromGame * exile = player->game->exile; - MTGCardInstance * viable = NULL; - int counter = 0; - for (int i = 0; i < numCards.getValue(); i++) + viable = library->cards[library->nb_cards -1]; + if (!found) { - if (library->nb_cards) + if (!viable->isLand() && (viable->getManaCost()->getConvertedCost() < source->getManaCost()->getConvertedCost())) { - for(int z = library->nb_cards-1; z >= 0; z--) - { - if(!library->cards[z]->isLand() && (library->cards[z]->getManaCost()->getConvertedCost() < source->getManaCost()->getConvertedCost())) - { - viable = library->cards[z]; - player->game->putInZone(viable, library, exile); - { - for(int j=0; j < library->nb_cards; j++) - { - if(library->cards[j]->isCascaded) - { - library->cards[j]->isCascaded = false; - selectedCards.push_back(library->cards[j]); - } - } - if(selectedCards.size()) - { - std::random_shuffle ( selectedCards.begin(), selectedCards.end() ); - for(unsigned int i = 0; i < selectedCards.size();++i) - { - oldOrder = library->cards; - newOrder.push_back(selectedCards[i]); - for(unsigned int k = 0;k < oldOrder.size();++k) - { - MTGCardInstance * rearranged = oldOrder[k]; - if(rearranged != selectedCards[i]) - newOrder.push_back(rearranged); - } - library->cards = newOrder; - } - } - } - toCastCard(viable->next); - return 1; - } - else - { - library->cards[library->nb_cards - 1]->isCascaded=true; - counter++; - } - } + viable = player->game->putInZone(viable, library, exile); + viable->isCascaded = true; + castingThis = viable; + found = true; + } + else + { + viable = player->game->putInZone(viable, library, exile); + viable->isCascaded = true; + counter++; } } } - return 1; + + //*//*//*//* } + //////////////////////////////////////////// + for (int j = 0; j < exile->nb_cards; j++) + { + if (exile->cards[j]->isCascaded) + { + MTGCardInstance * CardToPutBack = exile->cards[j];; + CardToPutBack->isCascaded = false; + selectedCards.push_back(CardToPutBack); + } + } + ////////////////////////////////////////// + if (selectedCards.size()) + { + do + { + MTGCardInstance * toMove = selectedCards.back(); + if (toMove) + { + MTGAbility * a = NEW AALibraryBottom(game, game->mLayers->actionLayer()->getMaxId(), source, toMove); + a->oneShot = 1; + a->resolve(); + SAFE_DELETE(a); + selectedCards.pop_back(); + } + } while (selectedCards.size()); + + if (castingThis) + { + while (castingThis->next) + castingThis = castingThis->next; + toCastCard(castingThis); + } + } + ////////////////////////////////////// + return 1; +} void AACascade::toCastCard(MTGCardInstance * thisCard) { MTGAbility *ac = NEW AACastCard(game, game->mLayers->actionLayer()->getMaxId(), thisCard, thisCard,false,false,true,"","",false,false); - MayAbility *ma1 = NEW MayAbility(game, game->mLayers->actionLayer()->getMaxId(), ac->clone(), thisCard,true); + MayAbility *ma1 = NEW MayAbility(game, game->mLayers->actionLayer()->getMaxId(), ac->clone(), thisCard,false); MTGAbility *ga1 = NEW GenericAddToGame(game, game->mLayers->actionLayer()->getMaxId(), thisCard,NULL,ma1->clone()); SAFE_DELETE(ac); SAFE_DELETE(ma1); ga1->resolve(); + SAFE_DELETE(ga1); return; } @@ -7291,6 +7312,7 @@ MTGCardInstance * AACastCard::makeCard() MTGCardInstance * card = NULL; MTGCard * cardData = MTGCollection()->getCardByName(cardNamed); card = NEW MTGCardInstance(cardData, source->controller()->game); + card->owner = source->controller(); source->controller()->game->temp->addCard(card); return card; } @@ -7311,6 +7333,7 @@ int AACastCard::resolveSpell() MTGCard * cardToCopy = MTGCollection()->getCardById(_target->getId()); MTGCardInstance * myDummy = NULL; myDummy = NEW MTGCardInstance(cardToCopy, source->controller()->game); + myDummy->setObserver(source->controller()->getObserver()); source->controller()->game->garbage->addCard(myDummy); _target = myDummy; _target->isToken = 1; diff --git a/projects/mtg/src/Counters.cpp b/projects/mtg/src/Counters.cpp index b01c57644..a08c4402e 100644 --- a/projects/mtg/src/Counters.cpp +++ b/projects/mtg/src/Counters.cpp @@ -2,6 +2,7 @@ #include "Counters.h" #include "MTGCardInstance.h" +#include "AllAbilities.h" Counter::Counter(MTGCardInstance * _target, int _power, int _toughness) { @@ -187,10 +188,13 @@ int Counters::removeCounter(const char * _name, int _power, int _toughness) if (target->suspended && !target->counters->hasCounter("time",0,0)) { GameObserver * game = target->getObserver(); - MTGCardInstance * copy = target->controller()->game->putInZone(target, target->currentZone, target->controller()->game->stack); - - game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, NULL,1, 0); - game->targetChooser = NULL; + MTGAbility *ac = NEW AACastCard(game, game->mLayers->actionLayer()->getMaxId(), target, target, false, false, true, "", "", false, false); + MayAbility *ma1 = NEW MayAbility(game, game->mLayers->actionLayer()->getMaxId(), ac->clone(), target, true); + MTGAbility *ga1 = NEW GenericAddToGame(game, game->mLayers->actionLayer()->getMaxId(), target, NULL, ma1->clone()); + SAFE_DELETE(ac); + SAFE_DELETE(ma1); + ga1->resolve(); + SAFE_DELETE(ga1); } return mCount; } diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index fbae3701c..33efc8d53 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -249,6 +249,8 @@ LifeCost::LifeCost(TargetChooser *_tc) int LifeCost::canPay() { MTGCardInstance * _target = (MTGCardInstance *) target; + if (!_target) + return 0; if (_target->controller()->life <= 0 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) || _target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) || _target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE)) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index faa869fdb..7cca9d03e 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1568,7 +1568,17 @@ int GameObserver::isInExile(MTGCardInstance * card) } return 0; } +int GameObserver::isInHand(MTGCardInstance * card) +{ + for (int i = 0; i < 2; i++) + { + MTGGameZone * hand = players[i]->game->hand; + if (players[i]->game->isInZone(card, hand)) + return 1; + } + return 0; +} void GameObserver::cleanupPhase() { currentPlayer->cleanupPhase(); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index dbd525a22..1262e0a36 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -3982,13 +3982,14 @@ int AbilityFactory::getAbilities(vector * v, Spell * spell, MTGCar { card->graveEffects = false; card->exileEffects = false; - + card->handEffects = false; for (int i = 0; i < 2; ++i) { MTGPlayerCards * zones = observer->players[i]->game; if (dest == zones->hand) { magicText = card->magicTexts["hand"]; + card->handEffects = true; break; } if (dest == zones->graveyard) @@ -4891,6 +4892,8 @@ int MTGAbility::testDestroy() return 1; if (forceDestroy == -1) return 0; + if (source->handEffects && game->isInHand(source)) + return 0; if(source->graveEffects && game->isInGrave(source)) return 0; if(source->exileEffects && game->isInExile(source)) @@ -5934,13 +5937,26 @@ int AManaProducer::isReactingToClick(MTGCardInstance * _card, ManaCost * mana) int result = 0; if (!mana) mana = game->currentlyActing()->getManaPool(); - if (_card == source && (!tap || !source->isTapped()) && game->currentlyActing()->game->inPlay->hasCard(source) - && (source->hasType(Subtypes::TYPE_LAND) || !tap || !source->hasSummoningSickness()) && !source->isPhased) + //please do not condense the following, I broke it apart for readability, it was far to difficult to tell what exactly happened before with it all in a single line. + //and far to prone to bugs. + if (_card == source) { - ManaCost * cost = getCost(); - if (!cost || (mana->canAfford(cost) && (!cost->extraCosts || cost->extraCosts->canPay())))/*counter cost bypass react to click*/ + if (!tap || (tap && !source->isTapped())) { - result = 1; + if (!source->hasSummoningSickness()) + { + if (game->currentlyActing()->game->inPlay->hasCard(source) && (source->hasType(Subtypes::TYPE_LAND) || !tap || !source->hasSummoningSickness())) + { + if (!source->isPhased) + { + ManaCost * cost = getCost(); + if (!cost || (mana->canAfford(cost) && (!cost->extraCosts || cost->extraCosts->canPay())))/*counter cost bypass react to click*/ + { + result = 1; + } + } + } + } } } return result;