diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 00d4b92d7..40becb8c8 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -4027,58 +4027,61 @@ public: AErgRaiders * a = NEW AErgRaiders(*this); a->isClone = 1; return a; - } + } }; //Fastbond class AFastbond: public TriggeredAbility { public: - int alreadyPlayedALand; - int previous; - AFastbond(int _id, MTGCardInstance * card) : - TriggeredAbility(_id, card) - { - alreadyPlayedALand = 0; - if (source->controller()->canPutLandsIntoPlay == 0) - { - alreadyPlayedALand = 1; - source->controller()->canPutLandsIntoPlay = 1; - } - previous = source->controller()->canPutLandsIntoPlay; - } + int alreadyPlayedALand; + int previous; + AFastbond(int _id, MTGCardInstance * card) : + TriggeredAbility(_id, card) + { + alreadyPlayedALand = 0; + if (source->controller()->landsPlayerCanStillPlay == 0) + { + alreadyPlayedALand = 1; + source->controller()->landsPlayerCanStillPlay += 1; + source->controller()->canPutLandsIntoPlay = true; - void Update(float dt) - { - if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP) - { - alreadyPlayedALand = 0; - } - TriggeredAbility::Update(dt); - } + } + previous = source->controller()->landsPlayerCanStillPlay; + } - int trigger() - { - if (source->controller()->canPutLandsIntoPlay == 0 && previous == 1) - { - previous = 0; - source->controller()->canPutLandsIntoPlay = 1; - if (alreadyPlayedALand) return 1; - alreadyPlayedALand = 1; - return 0; - } - previous = source->controller()->canPutLandsIntoPlay; - return 0; - } + void Update(float dt) + { + if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP) + { + alreadyPlayedALand = 0; + } + TriggeredAbility::Update(dt); + } - int resolve() - { - game->mLayers->stackLayer()->addDamage(source, source->controller(), 1); - game->mLayers->stackLayer()->resolve(); - return 1; - } + int trigger() + { + if (source->controller()->landsPlayerCanStillPlay == 0 && previous >= 1) + { + previous = 0; + source->controller()->canPutLandsIntoPlay = true; + source->controller()->landsPlayerCanStillPlay += 1; + if (alreadyPlayedALand) return 1; + alreadyPlayedALand = 1; + return 0; + } + previous = source->controller()->landsPlayerCanStillPlay; + return 0; + } - virtual ostream& toString(ostream& out) const + int resolve() + { + game->mLayers->stackLayer()->addDamage(source, source->controller(), 1); + game->mLayers->stackLayer()->resolve(); + return 1; + } + + virtual ostream& toString(ostream& out) const { out << "AFastbond ::: alreadyPlayedALand : " << alreadyPlayedALand << " ; previous : " << previous << " ("; return TriggeredAbility::toString(out) << ")"; diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 87d3db6bd..20a37541f 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -71,7 +71,7 @@ class GameObserver{ Player * currentlyActing(); GameObserver(Player * _players[], int _nbplayers); ~GameObserver(); - void stateEffects(); + void gameStateBasedEffects(); void eventOccured(); void addObserver(MTGAbility * observer); void removeObserver(ActionElement * observer); diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 92f9c3e17..a90dc24a7 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -118,15 +118,6 @@ class MTGPersistRule:public MTGAbility{ int testDestroy(); virtual MTGPersistRule * clone() const; }; -//cantcast rules -class MTGCantCasterstart:public MTGAbility{ - public: - MTGCantCasterstart(int _id); - int receiveEvent(WEvent * event); - virtual ostream& toString(ostream& out) const; - int testDestroy(); - virtual MTGCantCasterstart * clone() const; -}; //affinity rules class MTGAffinityRule:public MTGAbility{ public: @@ -145,16 +136,6 @@ class MTGUnearthRule:public MTGAbility{ int testDestroy(); virtual MTGUnearthRule * clone() const; }; -//bury at end of turn effect. -class MTGSneakAttackRule:public MTGAbility{ - public: - MTGSneakAttackRule(int _id); - int receiveEvent(WEvent * event); - virtual ostream& toString(ostream& out) const; - int testDestroy(); - virtual MTGSneakAttackRule * clone() const; -}; - class MTGTokensCleanup:public MTGAbility{ public: vector list; diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index 9753f3cf5..cbca07ec7 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -22,23 +22,27 @@ public: MODE_TEST_SUITE, MODE_HUMAN, MODE_AI, }; - JTexture * mAvatarTex; - JQuad * mAvatar; - int playMode; - int canPutLandsIntoPlay; - int nomaxhandsize; - int castedspellsthisturn; - int onlyonecast; - int castcount; - int nocreatureinstant; - int nospellinstant; - int onlyoneinstant; - int castrestrictedcreature; - int castrestrictedspell; - MTGPlayerCards * game; - string deckFile; - string deckFileSmall; - string deckName; + JTexture * mAvatarTex; + JQuad * mAvatar; + int playMode; + bool canPutLandsIntoPlay; + int landsPlayerCanStillPlay; + bool nomaxhandsize; + int castedspellsthisturn; + bool onlyonecast; + int castcount; + bool nocreatureinstant; + bool nospellinstant; + bool onlyoneinstant; + bool castrestrictedcreature; + bool castrestrictedspell; + bool onlyoneboth; + bool bothrestrictedspell; + bool bothrestrictedcreature; + MTGPlayerCards * game; + string deckFile; + string deckFileSmall; + string deckName; Player(MTGDeck * deck, string deckFile, string deckFileSmall); virtual ~Player(); diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 9e4948c79..215bc4bb5 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -1062,11 +1062,11 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty while ((card = cd.nextmatch(game->hand, card))) { if (!CanHandleCost(card->getManaCost())) continue; - if (card->hasType(Subtypes::TYPE_CREATURE) && this->castrestrictedcreature > 0 && this->castrestrictedspell > 0) continue; - if (card->hasType(Subtypes::TYPE_ENCHANTMENT) && this->castrestrictedspell > 0) continue; - if (card->hasType(Subtypes::TYPE_ARTIFACT) && this->castrestrictedspell > 0) continue; - if (card->hasType(Subtypes::TYPE_SORCERY) && this->castrestrictedspell > 0) continue; - if (card->hasType(Subtypes::TYPE_INSTANT) && this->castrestrictedspell > 0) continue; + if (card->hasType(Subtypes::TYPE_CREATURE) && this->castrestrictedcreature == true && this->castrestrictedspell == true) continue; + if (card->hasType(Subtypes::TYPE_ENCHANTMENT) && this->castrestrictedspell == true) continue; + if (card->hasType(Subtypes::TYPE_ARTIFACT) && this->castrestrictedspell == true) continue; + if (card->hasType(Subtypes::TYPE_SORCERY) && this->castrestrictedspell == true) continue; + if (card->hasType(Subtypes::TYPE_INSTANT) && this->castrestrictedspell == true) continue; if (card->hasType(Subtypes::TYPE_LAND) && !this->canPutLandsIntoPlay) continue; if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->inPlay->findByName(card->name)) continue; int currentCost = card->getManaCost()->getConvertedCost(); @@ -1174,13 +1174,13 @@ int AIPlayerBaka::computeActions() nextCardToPlay = FindCardToPlay(currentMana, "land"); selectAbility(); //look for the most expensive creature we can afford - if (castrestrictedspell == 0 && nospellinstant == 0) + if (castrestrictedspell == false && nospellinstant == false) { - if (onlyonecast == 0 || castcount < 2) + if (onlyonecast == false || castcount < 2) { - if (onlyoneinstant == 0 || castcount < 2) + if (onlyoneinstant == false || castcount < 2) { - if (castrestrictedcreature == 0 && nocreatureinstant == 0) + if (castrestrictedcreature == false && nocreatureinstant == false) { if (!nextCardToPlay) { diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 42d99c249..3217822e4 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -745,7 +745,7 @@ int AAMoreLandPlz::resolve() { player = (Player *) _target; } - player->canPutLandsIntoPlay += additional->getValue(); + player->landsPlayerCanStillPlay += additional->getValue(); } return 1; } @@ -845,7 +845,7 @@ int AANoCreatures::resolve() { player = (Player *) _target; } - player->nocreatureinstant = 1; + player->nocreatureinstant = true; } return 1; } @@ -881,7 +881,7 @@ int AANoSpells::resolve() { player = (Player *) _target; } - player->nospellinstant = 1; + player->nospellinstant = true; } return 1; } @@ -918,7 +918,7 @@ int AAOnlyOne::resolve() { player = (Player *) _target; } - player->onlyoneinstant = 1; + player->onlyoneinstant = true; } return 1; } @@ -1318,7 +1318,7 @@ const char * GenericTargetAbility::getMenuText() { return "Reanimate"; } - else if (dest == g->players[i]->game->library) + else if ((tc->targetsZone(g->players[i]->game->inPlay) && dest == g->players[i]->game->library) || dest == g->players[i]->game->library ) { return "Put in Library"; } diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index ed6d56be6..ee7219b50 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -36,8 +36,6 @@ void DuelLayers::init() action->Add(NEW MTGPersistRule(-1)); action->Add(NEW MTGAffinityRule(-1)); action->Add(NEW MTGUnearthRule(-1)); - action->Add(NEW MTGCantCasterstart(-1)); - action->Add(NEW MTGSneakAttackRule(-1)); action->Add(NEW MTGLifelinkRule(-1)); action->Add(NEW MTGDeathtouchRule(-1)); action->Add(NEW OtherAbilitiesEventReceiver(-1)); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 32516e767..508de3a53 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -106,17 +106,18 @@ void GameObserver::nextGamePhase() //init begin of turn if (currentGamePhase == Constants::MTG_PHASE_BEFORE_BEGIN) - { - cleanupPhase(); - currentPlayer->canPutLandsIntoPlay = 1; - currentPlayer->castedspellsthisturn = 0; - currentPlayer->opponent()->castedspellsthisturn = 0; - currentPlayer->castcount = 0; - currentPlayer->nocreatureinstant = 0; - currentPlayer->nospellinstant = 0; - currentPlayer->onlyoneinstant = 0; - currentPlayer->damageCount = 0; - currentPlayer->preventable = 0; + { + cleanupPhase(); + currentPlayer->canPutLandsIntoPlay = true; + currentPlayer->landsPlayerCanStillPlay = 1; + currentPlayer->castedspellsthisturn = 0; + currentPlayer->opponent()->castedspellsthisturn = 0; + currentPlayer->castcount = 0; + currentPlayer->nocreatureinstant = false; + currentPlayer->nospellinstant = false; + currentPlayer->onlyoneinstant = false; + currentPlayer->damageCount = 0; + currentPlayer->preventable = 0; mLayers->actionLayer()->cleanGarbage(); //clean abilities history for this turn; mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn; mLayers->actionLayer()->Update(0); @@ -136,7 +137,7 @@ void GameObserver::nextGamePhase() if (currentGamePhase == Constants::MTG_PHASE_AFTER_EOT) { //Auto Hand cleaning, in case the player didn't do it himself - while (currentPlayer->game->hand->nb_cards > 7 && currentPlayer->nomaxhandsize < 1) + while (currentPlayer->game->hand->nb_cards > 7 && currentPlayer->nomaxhandsize == false) currentPlayer->game->putInGraveyard(currentPlayer->game->hand->cards[0]); mLayers->actionLayer()->Update(0); return nextGamePhase(); @@ -358,99 +359,268 @@ void GameObserver::Update(float dt) mLayers->actionLayer()->Update(0); } - stateEffects(); - oldGamePhase = currentGamePhase; - - - + gameStateBasedEffects(); + oldGamePhase = currentGamePhase; } //applies damage to creatures after updates //Players life test -void GameObserver::stateEffects() +//Handles game state based effects +void GameObserver::gameStateBasedEffects() { - if (mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) - return; - if (mLayers->actionLayer()->menuObject) - return; - if (targetChooser || mLayers->actionLayer()->isWaitingForAnswer()) - return; - for (int i = 0; i < 2; i++) - { - MTGGameZone * zone = players[i]->game->inPlay; - for (int j = zone->nb_cards - 1; j >= 0; j--) - { - MTGCardInstance * card = zone->cards[j]; - card->afterDamage(); - - //Remove auras that don't have a valid target anymore - if (card->target && !isInPlay(card->target) && !card->hasType("equipment")) - { - players[i]->game->putInGraveyard(card); - } - } - } - for (int i = 0; i < 2; i++) - if (players[i]->life <= 0) - { - int cantlosers = 0; - MTGGameZone * z = players[i]->game->inPlay; - int nbcards = z->nb_cards; - for (int j = 0; j < nbcards; ++j) - { - MTGCardInstance * c = z->cards[j]; - if (c->has(Constants::CANTLOSE) || c->has(Constants::CANTLIFELOSE)) - { - cantlosers++; - } - } - MTGGameZone * k = players[i]->opponent()->game->inPlay; - int onbcards = k->nb_cards; - for (int m = 0; m < onbcards; ++m) - { - MTGCardInstance * e = k->cards[m]; - if (e->has(Constants::CANTWIN)) - { - cantlosers++; - } - } - if (cantlosers < 1) - { - gameOver = players[i]; - } - } - - for (int i = 0; i < 2; i++) - if (players[i]->poisonCount >= 10) - gameOver = players[i]; - - if (combatStep == TRIGGERS) + //check land playability at start; as we want this effect to happen reguardless of unresolved + //effects or menus actions + for (int i = 0; i < 2; i++) + { + if(players[i]->landsPlayerCanStillPlay <= 0) { - if (!mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED) && !targetChooser && !mLayers->actionLayer()->isWaitingForAnswer()) - mLayers->stackLayer()->AddNextCombatStep(); + players[i]->canPutLandsIntoPlay = false; } + else + { + players[i]->canPutLandsIntoPlay = true; + } + } + if (mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) + return; + if (mLayers->actionLayer()->menuObject) + return; + if (targetChooser || mLayers->actionLayer()->isWaitingForAnswer()) + return; - //Auto skip Phases + //////////////////////// + //---apply damage-----// + //after combat effects// + //////////////////////// + for (int i = 0; i < 2; i++) + { + MTGGameZone * zone = players[i]->game->inPlay; + for (int j = zone->nb_cards - 1; j >= 0; j--) + { + MTGCardInstance * card = zone->cards[j]; + card->afterDamage(); + + //Remove auras that don't have a valid target anymore + if (card->target && !isInPlay(card->target) && !card->hasType("equipment")) + { + players[i]->game->putInGraveyard(card); + } + } + } + //------------------------------------- + + for (int i = 0; i < 2; i++) + { + /////////////////////////////////////////////////////////// + //life checks/poison checks also checks cant win or lose.// + /////////////////////////////////////////////////////////// + if (players[i]->life <= 0) + { + int cantlosers = 0; + MTGGameZone * z = players[i]->game->inPlay; + int nbcards = z->nb_cards; + for (int j = 0; j < nbcards; ++j) + { + MTGCardInstance * c = z->cards[j]; + if (c->has(Constants::CANTLOSE) || c->has(Constants::CANTLIFELOSE)) + { + cantlosers++; + } + } + MTGGameZone * k = players[i]->opponent()->game->inPlay; + int onbcards = k->nb_cards; + for (int m = 0; m < onbcards; ++m) + { + MTGCardInstance * e = k->cards[m]; + if (e->has(Constants::CANTWIN)) + { + cantlosers++; + } + } + if (cantlosers < 1) + { + gameOver = players[i]; + } + if (players[i]->poisonCount >= 10) + { + gameOver = players[i]; + } + } + } + ////////////////////////////////////////////////////// + //-------------card based states effects------------// + ////////////////////////////////////////////////////// + //ie:cantcast; extra land; extra turn;no max hand;--// + ////////////////////////////////////////////////////// + + for (int i = 0; i < 2; i++) + { + //checks if a player has a card which has the stated ability in play. + Player * p = players[i]; + MTGGameZone * z = players[i]->game->inPlay; + int nbcards = z->nb_cards; + p->onlyonecast = false; + p->opponent()->onlyonecast = false; + //------------------------------ + if (z->hasAbility(Constants::NOMAXHAND)) + { + p->nomaxhandsize = true; + } + else + { + p->nomaxhandsize = false; + } + //------------------------------ + if (z->hasAbility(Constants::CANTCASTCREATURE)) + { + p->castrestrictedcreature = true; + } + else + { + p->castrestrictedcreature = false; + } + //------------------------------ + if (z->hasAbility(Constants::CANTCAST)) + { + p->castrestrictedspell = true; + } + else + { + p->castrestrictedspell = false; + } + //------------------------------ + if (z->hasAbility(Constants::CANTCASTTWO)) + { + p->onlyonecast = true; + } + else + { + p->onlyonecast = false; + } + //-------------------------------- + if (z->hasAbility(Constants::BOTHCANTCAST)) + { + p->bothrestrictedspell = true; + } + else + { + p->bothrestrictedspell = false; + } + //--------------------------------- + if (z->hasAbility(Constants::BOTHNOCREATURE)) + { + p->bothrestrictedcreature = true; + } + else + { + p->bothrestrictedcreature = false; + } + //----------------------------------- + if (z->hasAbility(Constants::ONLYONEBOTH)) + { + p->onlyoneboth = true; + } + else + { + p->onlyoneboth = false; + } + //------------------------------------ + if(players[0]->bothrestrictedcreature) + players[1]->castrestrictedcreature = true; + //------------------------------------ + if(players[0]->bothrestrictedspell) + players[1]->castrestrictedspell = true; + //------------------------------------ + if(players[0]->onlyoneboth) + players[1]->onlyoneboth = true; + //------------------------------------ + if(players[1]->bothrestrictedcreature) + players[0]->castrestrictedcreature = true; + //------------------------------------ + if(players[1]->bothrestrictedspell) + players[0]->castrestrictedspell = true; + //------------------------------------ + if(players[1]->onlyoneboth) + players[0]->onlyoneboth = true; + //------------------------------------ + ///////////////////////////////////////////////// + //handle end of turn effects while we're at it.// + ///////////////////////////////////////////////// + if( currentGamePhase == Constants::MTG_PHASE_ENDOFTURN) + { + for (int j = 0; j < nbcards; ++j) + { + MTGCardInstance * c = z->cards[j]; + while (c->flanked) + {//undoes the flanking on a card + c->power += 1; + c->addToToughness(1); + c->flanked -= 1; + } + if (c->has(Constants::TREASON)) + { + WEvent * e = NEW WEventCardSacrifice(c); + GameObserver * game = GameObserver::GetInstance(); + game->receiveEvent(e); + p->game->putInGraveyard(c); + } + if (c->has(Constants::UNEARTH)) + p->game->putInExile(c); + if (c->fresh) + c->fresh = 0; + if (c->has(Constants::ONLYONEBOTH)) + { + c->controller()->castcount = 0; + c->controller()->opponent()->castcount = 0; + } + + } + MTGGameZone * f = p->game->graveyard; + for (int k = 0; k < f->nb_cards; k++) + { + MTGCardInstance * card = f->cards[k]; + card->fresh = 0; + } + } + if(z->nb_cards == 0) + { + p->nomaxhandsize = false; + if(!p->bothrestrictedcreature && !p->opponent()->bothrestrictedcreature) + p->castrestrictedcreature = false; + if(!p->bothrestrictedspell && !p->opponent()->bothrestrictedspell) + p->castrestrictedspell = false; + p->onlyonecast = false; + } + } + /////////////////////////////////// + //phase based state effects------// + /////////////////////////////////// + if (combatStep == TRIGGERS) + { + if (!mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED) && !targetChooser && !mLayers->actionLayer()->isWaitingForAnswer()) + mLayers->stackLayer()->AddNextCombatStep(); + } + + //Auto skip Phases GameObserver * game = game->GetInstance(); int skipLevel = (game->currentPlayer->playMode == Player::MODE_TEST_SUITE) ? Constants::ASKIP_NONE : options[Options::ASPHASES].number; - int nrCreatures = currentPlayer->game->inPlay->countByType("Creature"); - - if (skipLevel == Constants::ASKIP_SAFE || skipLevel == Constants::ASKIP_FULL) - { - if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UNTAP || currentGamePhase - == Constants::MTG_PHASE_DRAW || currentGamePhase == Constants::MTG_PHASE_COMBATBEGIN || ((currentGamePhase - == Constants::MTG_PHASE_COMBATATTACKERS) && (nrCreatures == 0)) || currentGamePhase - == Constants::MTG_PHASE_COMBATEND || currentGamePhase == Constants::MTG_PHASE_ENDOFTURN - || ((currentGamePhase == Constants::MTG_PHASE_CLEANUP) && (currentPlayer->game->hand->nb_cards < 8)))) - userRequestNextGamePhase(); - } - if (skipLevel == Constants::ASKIP_FULL) - { - if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UPKEEP || currentGamePhase - == Constants::MTG_PHASE_COMBATDAMAGE)) - userRequestNextGamePhase(); - } + int nrCreatures = currentPlayer->game->inPlay->countByType("Creature"); + if (skipLevel == Constants::ASKIP_SAFE || skipLevel == Constants::ASKIP_FULL) + { + if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UNTAP || currentGamePhase + == Constants::MTG_PHASE_DRAW || currentGamePhase == Constants::MTG_PHASE_COMBATBEGIN || ((currentGamePhase + == Constants::MTG_PHASE_COMBATATTACKERS) && (nrCreatures == 0)) || currentGamePhase + == Constants::MTG_PHASE_COMBATEND || currentGamePhase == Constants::MTG_PHASE_ENDOFTURN + || ((currentGamePhase == Constants::MTG_PHASE_CLEANUP) && (currentPlayer->game->hand->nb_cards < 8)))) + userRequestNextGamePhase(); + } + if (skipLevel == Constants::ASKIP_FULL) + { + if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UPKEEP || currentGamePhase + == Constants::MTG_PHASE_COMBATDAMAGE)) + userRequestNextGamePhase(); + } } void GameObserver::Render() @@ -638,7 +808,7 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object) //Current player's hand if (currentPlayer->game->hand->hasCard(card) && currentGamePhase == Constants::MTG_PHASE_CLEANUP - && currentPlayer->game->hand->nb_cards > 7 && currentPlayer->nomaxhandsize < 1) + && currentPlayer->game->hand->nb_cards > 7 && currentPlayer->nomaxhandsize == false) { currentPlayer->game->putInGraveyard(card); } diff --git a/projects/mtg/src/GuiStatic.cpp b/projects/mtg/src/GuiStatic.cpp index 43845a07b..dd0909d30 100644 --- a/projects/mtg/src/GuiStatic.cpp +++ b/projects/mtg/src/GuiStatic.cpp @@ -97,7 +97,7 @@ void GuiAvatar::Render() r->DrawRect(x0, y0, 34 * actZ, 49 * actZ, ARGB((int)actA, 255, 0, 0)); //Life - char buffer[5]; + char buffer[10]; sprintf(buffer, "%i", life); switch (corner) { diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 818bccfb1..b733926f7 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -53,30 +53,30 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) #ifdef WIN32 cost->Dump(); #endif - if (player->castrestrictedspell > 0 && !card->hasType("land")) + if (player->castrestrictedspell == true && !card->hasType("land")) { return 0; } - if (player->onlyonecast > 0 && player->castcount >= 1) + if (player->onlyonecast == true && player->castcount >= 1) { return 0; } - if (player->nospellinstant > 0) + if (player->nospellinstant == true) { return 0; } - if (player->onlyoneinstant > 0) + if (player->onlyoneinstant == true) { if (player->castcount >= 1) { return 0; } } - if (player->nocreatureinstant > 0 && card->hasType("creature")) + if (player->nocreatureinstant == true && card->hasType("creature")) { return 0; } - if (player->castrestrictedcreature > 0 && card->hasType("creature")) + if (player->castrestrictedcreature == true && card->hasType("creature")) { return 0; } @@ -149,7 +149,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) spell->resolve(); delete spellCost; delete spell; - player->canPutLandsIntoPlay--; + player->landsPlayerCanStillPlay--; } else { @@ -161,7 +161,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) game->targetChooser = NULL; player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; } @@ -171,7 +171,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0); player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; } @@ -258,30 +258,30 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * #ifdef WIN32 cost->Dump(); #endif - if (player->castrestrictedspell > 0 && !card->hasType("land")) + if (player->castrestrictedspell == true && !card->hasType("land")) { return 0; } - if (player->onlyonecast > 0 && player->castcount >= 1) + if (player->onlyonecast == true && player->castcount >= 1) { return 0; } - if (player->nospellinstant > 0) + if (player->nospellinstant == true) { return 0; } - if (player->onlyoneinstant > 0) + if (player->onlyoneinstant == true) { if (player->castcount >= 1) { return 0; } } - if (player->nocreatureinstant > 0 && card->hasType("creature")) + if (player->nocreatureinstant == true && card->hasType("creature")) { return 0; } - if (player->castrestrictedcreature > 0 && card->hasType("creature")) + if (player->castrestrictedcreature == true && card->hasType("creature")) { return 0; } @@ -341,7 +341,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) spell->resolve(); delete spellCost; delete spell; - player->canPutLandsIntoPlay--; + player->landsPlayerCanStillPlay--; payResult = ManaCost::MANA_PAID_WITH_ALTERNATIVE; spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1); } @@ -355,7 +355,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) game->targetChooser = NULL; player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; } @@ -365,7 +365,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0); player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; } @@ -447,30 +447,30 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) #ifdef WIN32 cost->Dump(); #endif - if (player->castrestrictedspell > 0 && !card->hasType("land")) + if (player->castrestrictedspell == true && !card->hasType("land")) { return 0; } - if (player->onlyonecast > 0 && player->castcount >= 1) + if (player->onlyonecast == true && player->castcount >= 1) { return 0; } - if (player->nospellinstant > 0) + if (player->nospellinstant == true ) { return 0; } - if (player->onlyoneinstant > 0) + if (player->onlyoneinstant == true ) { if (player->castcount >= 1) { return 0; } } - if (player->nocreatureinstant > 0 && card->hasType("creature")) + if (player->nocreatureinstant == true && card->hasType("creature")) { return 0; } - if (player->castrestrictedcreature > 0 && card->hasType("creature")) + if (player->castrestrictedcreature == true && card->hasType("creature")) { return 0; } @@ -532,7 +532,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) spell->resolve(); delete spellCost; delete spell; - player->canPutLandsIntoPlay--; + player->landsPlayerCanStillPlay--; payResult = ManaCost::MANA_PAID_WITH_BUYBACK; spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1); } @@ -548,7 +548,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) game->targetChooser = NULL; player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; } @@ -558,7 +558,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0); player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; @@ -632,30 +632,30 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) #ifdef WIN32 cost->Dump(); #endif - if (player->castrestrictedspell > 0 && !card->hasType("land")) + if (player->castrestrictedspell == true && !card->hasType("land")) { return 0; } - if (player->onlyonecast > 0 && player->castcount >= 1) + if (player->onlyonecast == true && player->castcount >= 1) { return 0; } - if (player->nospellinstant > 0) + if (player->nospellinstant == true ) { return 0; } - if (player->onlyoneinstant > 0) + if (player->onlyoneinstant == true ) { if (player->castcount >= 1) { return 0; } } - if (player->nocreatureinstant > 0 && card->hasType("creature")) + if (player->nocreatureinstant == true && card->hasType("creature")) { return 0; } - if (player->castrestrictedcreature > 0 && card->hasType("creature")) + if (player->castrestrictedcreature == true && card->hasType("creature")) { return 0; } @@ -716,7 +716,7 @@ int MTGFlashBackRule::reactToClick(MTGCardInstance * card) spell->resolve(); delete spellCost; delete spell; - player->canPutLandsIntoPlay--; + player->landsPlayerCanStillPlay--; payResult = ManaCost::MANA_PAID_WITH_FLASHBACK; spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1); } @@ -732,7 +732,7 @@ int MTGFlashBackRule::reactToClick(MTGCardInstance * card) game->targetChooser = NULL; player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true ) { player->castcount += 1; } @@ -742,7 +742,7 @@ int MTGFlashBackRule::reactToClick(MTGCardInstance * card) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0); player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; @@ -816,30 +816,30 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) #ifdef WIN32 cost->Dump(); #endif - if (player->castrestrictedspell > 0 && !card->hasType("land")) + if (player->castrestrictedspell == true && !card->hasType("land")) { return 0; } - if (player->onlyonecast > 0 && player->castcount >= 1) + if (player->onlyonecast == true && player->castcount >= 1) { return 0; } - if (player->nospellinstant > 0) + if (player->nospellinstant == true ) { return 0; } - if (player->onlyoneinstant > 0) + if (player->onlyoneinstant == true ) { if (player->castcount >= 1) { return 0; } } - if (player->nocreatureinstant > 0 && card->hasType("creature")) + if (player->nocreatureinstant == true && card->hasType("creature")) { return 0; } - if (player->castrestrictedcreature > 0 && card->hasType("creature")) + if (player->castrestrictedcreature == true && card->hasType("creature")) { return 0; } @@ -898,7 +898,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) spell->resolve(); delete spellCost; delete spell; - player->canPutLandsIntoPlay--; + player->landsPlayerCanStillPlay--; payResult = ManaCost::MANA_PAID_WITH_RETRACE; spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1); } @@ -912,7 +912,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) game->targetChooser = NULL; player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true ) { player->castcount += 1; } @@ -922,7 +922,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0); player->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1; - if (player->onlyonecast > 0 || player->onlyoneinstant > 0) + if (player->onlyonecast == true || player->onlyoneinstant == true) { player->castcount += 1; @@ -1604,161 +1604,6 @@ MTGPersistRule * MTGPersistRule::clone() const return a; } -//putting cards with restricting effects inplay -MTGCantCasterstart::MTGCantCasterstart(int _id) : - MTGAbility(_id, NULL) -{ -} -; -int MTGCantCasterstart::receiveEvent(WEvent * event) -{ - if (event->type == WEvent::CHANGE_ZONE) - { - WEventZoneChange * e = (WEventZoneChange *) event; - MTGCardInstance * card = e->card->previous; - if (card) - { - if (e->from == e->card->controller()->game->battlefield && e->to == e->card->controller()->game->graveyard) - { - e->card->fresh = 1; - } - if (e->to == e->card->controller()->game->battlefield) - { - e->card->fresh = 1; - } - if (card->basicAbilities[Constants::BOTHCANTCAST] || card->basicAbilities[Constants::BOTHNOCREATURE] - || card->basicAbilities[Constants::CANTCAST] || card->basicAbilities[Constants::CANTCASTCREATURE] - || card->basicAbilities[Constants::CANTCASTTWO] || card->basicAbilities[Constants::ONLYONEBOTH] - || card->basicAbilities[Constants::NOMAXHAND]) - { - int ok = 0; - for (int i = 0; i < 2; i++) - { - Player * p = game->players[i]; - if (e->from == p->game->graveyard || e->from == p->game->hand || e->from == p->game->library || e->from - == p->game->exile || e->to == p->game->inPlay || e->to == p->game->graveyard || e->to - == p->game->hand || e->to == p->game->library || e->to == p->game->exile || e->from - == p->game->inPlay) - { - ok = 1; - //check happens---------- - //reset restrictions if they exist and runs a check if these cards still exist. - p->nomaxhandsize = 0; - p->opponent()->nomaxhandsize = 0; - p->onlyonecast = 0; - p->opponent()->onlyonecast = 0; - p->castrestrictedspell = 0;//0 means no restrictions apply. - p->castrestrictedcreature = 0; - p->opponent()->castrestrictedspell = 0; - p->opponent()->castrestrictedcreature = 0; - /*--------------------------------------------------------------*/ - for (int i = 0; i < 2; i++) - { - Player * p = game->players[i]; - MTGGameZone * z = card->controller()->game->inPlay; - MTGGameZone * y = card->controller()->opponent()->game->inPlay; - int nbcards = z->nb_cards; - int onbcards = y->nb_cards; - //handsize modifier - //check my battlefield and opponents - for (int j = 0; j < nbcards; ++j) - { - MTGCardInstance * c = z->cards[j]; - if (c->has(Constants::NOMAXHAND)) - { - card->controller()->nomaxhandsize = 1; - } - if (c->has(Constants::BOTHCANTCAST)) - { - card->controller()->castrestrictedspell = 1; - card->controller()->opponent()->castrestrictedspell = 1; - } - if (c->has(Constants::CANTCAST)) - { - card->controller()->castrestrictedspell = 1; - } - if (c->has(Constants::BOTHNOCREATURE)) - { - card->controller()->castrestrictedcreature += 1; - card->controller()->opponent()->castrestrictedcreature += 1; - } - if (c->has(Constants::CANTCASTCREATURE)) - { - card->controller()->castrestrictedcreature = 1; - } - if (c->has(Constants::ONLYONEBOTH)) - { - card->controller()->onlyonecast = 1; - card->controller()->opponent()->onlyonecast = 1; - } - if (c->has(Constants::CANTCASTTWO)) - { - card->controller()->onlyonecast = 1; - } - } - //any on other side? - for (int j = 0; j < onbcards; ++j) - { - MTGCardInstance * c = y->cards[j]; - if (c->has(Constants::NOMAXHAND)) - { - card->controller()->opponent()->nomaxhandsize = 1; - } - if (c->has(Constants::BOTHCANTCAST)) - { - card->controller()->castrestrictedspell = 1; - card->controller()->opponent()->castrestrictedspell = 1; - } - if (c->has(Constants::BOTHNOCREATURE)) - { - card->controller()->castrestrictedcreature = 1; - card->controller()->opponent()->castrestrictedcreature = 1; - } - if (c->has(Constants::CANTCASTCREATURE)) - { - card->controller()->opponent()->castrestrictedcreature = 1; - } - if (c->has(Constants::ONLYONEBOTH)) - { - card->controller()->onlyonecast = 1; - card->controller()->opponent()->onlyonecast = 1; - } - if (c->has(Constants::CANTCASTTWO)) - { - card->controller()->opponent()->onlyonecast = 1; - } - if (c->has(Constants::CANTCAST)) - { - card->controller()->opponent()->castrestrictedspell = 1; - } - } - //-----if a card with both*restrict* was found then the players are still restricted, if one player is still restricted he stays restricted. - } - } - } - } - } - } - return 1; -} -ostream& MTGCantCasterstart::toString(ostream& out) const -{ - out << "MTGCantCasterstart ::: ("; - return MTGAbility::toString(out) << ")"; -} -int MTGCantCasterstart::testDestroy() -{ - return 0; -} -MTGCantCasterstart * MTGCantCasterstart::clone() const -{ - MTGCantCasterstart * a = NEW MTGCantCasterstart(*this); - a->isClone = 1; - return a; -} -//the end of this very complex code line. - - //unearth rule---------------------------------- //if the card leaves play, exile it instead. MTGUnearthRule::MTGUnearthRule(int _id) : @@ -1770,14 +1615,23 @@ MTGUnearthRule::MTGUnearthRule(int _id) : int MTGUnearthRule::receiveEvent(WEvent * event) { if (event->type == WEvent::CHANGE_ZONE) - { - WEventZoneChange * e = (WEventZoneChange *) event; - MTGCardInstance * card = e->card->previous; - if (card && card->basicAbilities[Constants::UNEARTH]) - { - int ok = 0; - for (int i = 0; i < 2; i++) - { + { + WEventZoneChange * e = (WEventZoneChange *) event; + MTGCardInstance * card = e->card->previous; + if (e->from == e->card->controller()->game->battlefield && e->to == e->card->controller()->game->graveyard) + { + e->card->fresh = 1; + } + if (e->to == e->card->controller()->game->battlefield) + { + e->card->fresh = 1; + } + + if (card && card->basicAbilities[Constants::UNEARTH]) + { + int ok = 0; + for (int i = 0; i < 2; i++) + { Player * p = game->players[i]; if (e->from == p->game->inPlay) ok = 1; @@ -1814,83 +1668,6 @@ MTGUnearthRule * MTGUnearthRule::clone() const return a; } //---------------------------------------------------------------------- -//sneakattack rule------------------------------------------------------ -//this rule also handles the exile of unearth cards at end of turn. - -MTGSneakAttackRule::MTGSneakAttackRule(int _id) : - MTGAbility(_id, NULL) -{ -} -; - -int MTGSneakAttackRule::receiveEvent(WEvent *e) -{ - if (WEventPhaseChange* event = dynamic_cast(e)) - { - if (Constants::MTG_PHASE_ENDOFTURN == event->from->id) - { - for (int j = 0; j < 2; j++) - { - Player * p = game->players[j]; - MTGGameZone * z = p->game->inPlay; - for (int i = 0; i < z->nb_cards; i++) - { - MTGCardInstance * card = z->cards[i]; - while (card->flanked) - {//undoes the flanking on a card - card->power += 1; - card->addToToughness(1); - card->flanked -= 1; - } - if (card->has(Constants::TREASON)) - { - WEvent * e = NEW WEventCardSacrifice(card); - GameObserver * game = GameObserver::GetInstance(); - game->receiveEvent(e); - p->game->putInGraveyard(card); - i--; - } - if (card->has(Constants::UNEARTH)) - { - p->game->putInExile(card); - i--; - } - if (card->fresh) - card->fresh = 0; - if (card->has(Constants::ONLYONEBOTH)) - { - card->controller()->castcount = 0; - card->controller()->opponent()->castcount = 0; - } - } - MTGGameZone * f = p->game->graveyard; - for (int k = 0; k < f->nb_cards; k++) - { - MTGCardInstance * card = f->cards[k]; - card->fresh = 0; - } - } - } - return 1; - } - return 1; -} - -ostream& MTGSneakAttackRule::toString(ostream& out) const -{ - out << "MTGSneakAttackRule ::: ("; - return MTGAbility::toString(out) << ")"; -} -int MTGSneakAttackRule::testDestroy() -{ - return 0; -} -MTGSneakAttackRule * MTGSneakAttackRule::clone() const -{ - MTGSneakAttackRule * a = NEW MTGSneakAttackRule(*this); - a->isClone = 1; - return a; -} //Affinity rule------------------------------------------------------ //this rule is for Affinity cards. diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 85320330d..3fb8b1d75 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -6,34 +6,38 @@ #include "ManaCost.h" Player::Player(MTGDeck * deck, string file, string fileSmall) : - Damageable(20) +Damageable(20) { - deckFile = file; - deckFileSmall = fileSmall; - manaPool = NEW ManaPool(this); - canPutLandsIntoPlay = 1; - nomaxhandsize = 0; - castedspellsthisturn = 0; - castrestrictedspell = 0; - castrestrictedcreature = 0; - onlyonecast = 0; - castcount = 0; - nocreatureinstant = 0; - nospellinstant = 0; - onlyoneinstant = 0; - poisonCount = 0; - damageCount = 0; - preventable = 0; - mAvatar = NULL; - mAvatarTex = NULL; - type_as_damageable = DAMAGEABLE_PLAYER; - playMode = MODE_HUMAN; - if (deck != NULL) - { - game = NEW MTGPlayerCards(deck); - game->setOwner(this); - deckName = deck->meta_name; - } + deckFile = file; + deckFileSmall = fileSmall; + manaPool = NEW ManaPool(this); + canPutLandsIntoPlay = true; + landsPlayerCanStillPlay = 1; + nomaxhandsize = false; + castedspellsthisturn = 0; + castrestrictedspell = false; + castrestrictedcreature = false; + bothrestrictedspell = false; + bothrestrictedcreature = false; + onlyoneboth = false; + onlyonecast = false; + castcount = 0; + nocreatureinstant = false; + nospellinstant = false; + onlyoneinstant = false; + poisonCount = 0; + damageCount = 0; + preventable = 0; + mAvatar = NULL; + mAvatarTex = NULL; + type_as_damageable = DAMAGEABLE_PLAYER; + playMode = MODE_HUMAN; + if (deck != NULL) + { + game = NEW MTGPlayerCards(deck); + game->setOwner(this); + deckName = deck->meta_name; + } } /*Method to call at the end of a game, before all objects involved in the game are destroyed */