From 78d3828f1e584ec252710d539bcf297a499cb771 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 6 Jul 2016 16:05:29 +0800 Subject: [PATCH 1/6] Zeth Fixes Memleaks and others --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 62 +- projects/mtg/include/AllAbilities.h | 506 +++--- projects/mtg/include/MTGRules.h | 4 + projects/mtg/src/AllAbilities.cpp | 1486 +++++++++--------- projects/mtg/src/Damage.cpp | 2 +- projects/mtg/src/GameObserver.cpp | 297 ++-- projects/mtg/src/MTGCardInstance.cpp | 251 +-- projects/mtg/src/MTGRules.cpp | 556 +++---- projects/mtg/src/ManaCost.cpp | 99 +- 9 files changed, 1646 insertions(+), 1617 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 5a8969ebb..f724167c0 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1043,7 +1043,7 @@ type=Enchantment [/card] [card] name=AEther Burst -target=creature|battlefield +target=creature|battlefield auto=moveto(ownerhand) text=Return up to X target creatures to their owners' hands, where X is one plus the number of cards named AEther Burst in all graveyards as you cast AEther Burst. mana={1}{U} @@ -3677,7 +3677,7 @@ toughness=1+* [/card] [card] name=An-Havva Inn -auto=life:plusonetype:creature[green]|battlefield controller +auto=life:type:creature[green]|battlefieldplus1plusend controller text=You gain X plus 1 life, where X is the number of green creatures on the battlefield. mana={1}{G}{G} type=Sorcery @@ -10126,7 +10126,7 @@ type=Sorcery [card] name=Black Vise auto=name(choose opponent) notatarget(opponent) deplete:0 -auto=@each targetedplayer upkeep:damage:morethanfourcards targetedplayer +auto=@each targetedplayer upkeep:damage:type:*:targetedpersonshandminus4minusend targetedplayer text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={1} type=Artifact @@ -54376,7 +54376,7 @@ type=Artifact [/card] [card] name=Iron Maiden -auto=@each opponent upkeep:damage:morethanfourcards opponent +auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent text=At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={3} type=Artifact @@ -57937,7 +57937,7 @@ type=Instant [card] name=Kindle target=creature,player -auto=damage:plustwotype:kindle:graveyard +auto=damage:type:kindle:graveyardplus2plusend text=Kindle deals X damage to target creature or player, where X is 2 plus the number of cards named Kindle in all graveyards. mana={1}{R} type=Instant @@ -61533,7 +61533,7 @@ toughness=5 [/card] [card] name=Lhurgoyf -anyzone=type:creature:graveyard/plusonetype:creature:graveyard cdaactive +anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. mana={2}{G}{G} type=Creature @@ -68102,7 +68102,7 @@ type=Legendary Land [card] name=Mind Burst target=player -auto=ability$!name(discard) target(*|myhand) reject!$ targetedplayer +auto=ability$!name(discard) target(*|myhandplus1plusend) reject!$ targetedplayer text=Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards. mana={1}{B} type=Sorcery @@ -109311,7 +109311,7 @@ toughness=7 [/card] [card] name=Tarmogoyf -anyzone=gravecardtypes/plusonegravecardtypes cdaactive +anyzone=gravecardtypes/gravecardtypesplus1plusend cdaactive text=Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (The card types are artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal.) mana={1}{G} type=Creature @@ -120125,7 +120125,7 @@ toughness=3 [/card] [card] name=Viseling -auto=@each opponent upkeep:damage:morethanfourcards opponent +auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent text=At the beginning of each opponent's upkeep, Viseling deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={4} type=Artifact Creature @@ -120200,7 +120200,7 @@ type=Instant [/card] [card] name=Vitalizing Cascade -auto=life:Xplusthree +auto=life:Xplus3plusend text=You gain X plus 3 life. mana={X}{G}{W} type=Instant @@ -121951,7 +121951,7 @@ toughness=4 [card] name=Wall of Tombstones abilities=defender -auto=@each my upkeep:transforms((,settoughness=plusonetype:creature:mygraveyard)) forever +auto=@each my upkeep:transforms((,settoughness=type:creature:mygraveyardplus1plusend)) forever text=Defender (This creature can't attack.) -- At the beginning of your upkeep, Wall of Tombstones's toughness becomes 1 plus the number of creature cards in your graveyard. (This effect lasts indefinitely.) mana={1}{B} type=Creature @@ -127555,6 +127555,46 @@ subtype=Orc Warrior power=7 toughness=2 [/card] +###### +######unsorted +[card] +name=Dark Suspicions +auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] +name=Bulwark +auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] +name=Roiling Horror +anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive +autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +suspend(0)={X}{b}{b}{b} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] +name=Dark Deal +auto=count(type:*:myhand) +auto=all(*|myhand) reject +auto=draw:countedamountplus1plusend controller +auto=count(type:*:opponenthand) +auto=all(*|opponenthand) reject +auto=draw:countedamountplus1plusend opponent +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 5a652b823..4e20da195 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -41,111 +41,111 @@ public: class MTGRevealingCards : public MTGAbility, public CardDisplay { public: - vector cards; - Player * playerForZone; - MTGGameZone * RevealZone; - MTGGameZone * RevealFromZone; - string revealCertainTypes; - string revealUntil; + vector cards; + Player * playerForZone; + MTGGameZone * RevealZone; + MTGGameZone * RevealFromZone; + string revealCertainTypes; + string revealUntil; - CardDisplay * revealDisplay; - vectortrashDisplays;//used for repeat - int nbCard; - string abilityString; - string number; - string abilityOne; - string abilityTwo; - string afterReveal; - bool afterEffectActivated; - MTGAbility * abilityToCast; - MTGAbility * abilityFirst; - MTGAbility * abilitySecond; - MTGAbility * abilityAfter; - vectorabilities; - bool repeat;//only the first ability can be repeated, and it must be targeted. - bool initCD; + CardDisplay * revealDisplay; + vectortrashDisplays;//used for repeat + int nbCard; + string abilityString; + string number; + string abilityOne; + string abilityTwo; + string afterReveal; + bool afterEffectActivated; + MTGAbility * abilityToCast; + MTGAbility * abilityFirst; + MTGAbility * abilitySecond; + MTGAbility * abilityAfter; + vectorabilities; + bool repeat;//only the first ability can be repeated, and it must be targeted. + bool initCD; - void Update(float dt); - int testDestroy(); - int toResolve(); - void CardViewBackup(MTGCardInstance * backup); - void Render(); - bool CheckUserInput(JButton key); - MTGAbility * contructAbility(string abilityToMake = ""); - MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); - virtual MTGRevealingCards * clone() const; - ~MTGRevealingCards(); - int receiveEvent(WEvent*); + void Update(float dt); + int testDestroy(); + int toResolve(); + void CardViewBackup(MTGCardInstance * backup); + void Render(); + bool CheckUserInput(JButton key); + MTGAbility * contructAbility(string abilityToMake = ""); + MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); + virtual MTGRevealingCards * clone() const; + ~MTGRevealingCards(); + int receiveEvent(WEvent*); }; class RevealDisplay : public CardDisplay { public: - RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL, - int nb_displayed_items = 7); - void AddCard(MTGCardInstance * _card); - bool CheckUserInput(JButton key); + RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL, + int nb_displayed_items = 7); + void AddCard(MTGCardInstance * _card); + bool CheckUserInput(JButton key); }; class GenericRevealAbility : public ActivatedAbility { public: - string howMany; - MTGRevealingCards * ability; - GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); - int resolve(); - const string getMenuText(); - GenericRevealAbility * clone() const; - ~GenericRevealAbility(); + string howMany; + MTGRevealingCards * ability; + GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); + int resolve(); + const string getMenuText(); + GenericRevealAbility * clone() const; + ~GenericRevealAbility(); }; class MTGScryCards : public MTGAbility, public CardDisplay { public: - vector cards; - MTGGameZone * RevealZone; - MTGGameZone * RevealFromZone; + vector cards; + MTGGameZone * RevealZone; + MTGGameZone * RevealFromZone; - CardDisplay * revealDisplay; - vectortrashDisplays;//used for repeat - int nbCard; - bool delayed; - bool dontRevealAfter; - int revealTopAmount; - string delayedAbilityString; - string abilityString; - string number; - string abilityOne; - string abilityTwo; - MTGAbility * abilityToCast; - MTGAbility * abilityFirst; - MTGAbility * abilitySecond; - vectorabilities; - bool initCD; - void Update(float dt); - int testDestroy(); - void initDisplay(int value = 0); - int toResolve(); - void Render(); - bool CheckUserInput(JButton key); - MTGAbility * contructAbility(string abilityToMake = ""); - MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); - virtual MTGScryCards * clone() const; - ~MTGScryCards(); - int receiveEvent(WEvent*); + CardDisplay * revealDisplay; + vectortrashDisplays;//used for repeat + int nbCard; + bool delayed; + bool dontRevealAfter; + int revealTopAmount; + string delayedAbilityString; + string abilityString; + string number; + string abilityOne; + string abilityTwo; + MTGAbility * abilityToCast; + MTGAbility * abilityFirst; + MTGAbility * abilitySecond; + vectorabilities; + bool initCD; + void Update(float dt); + int testDestroy(); + void initDisplay(int value = 0); + int toResolve(); + void Render(); + bool CheckUserInput(JButton key); + MTGAbility * contructAbility(string abilityToMake = ""); + MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); + virtual MTGScryCards * clone() const; + ~MTGScryCards(); + int receiveEvent(WEvent*); }; class GenericScryAbility : public ActivatedAbility { public: - string howMany; - MTGScryCards * ability; - GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); - int resolve(); - const string getMenuText(); - GenericScryAbility * clone() const; - ~GenericScryAbility(); + string howMany; + MTGScryCards * ability; + GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); + int resolve(); + const string getMenuText(); + GenericScryAbility * clone() const; + ~GenericScryAbility(); }; @@ -166,11 +166,11 @@ private: { if(!s.size()) return; - if (!card) - { - intValue = atoi(s.c_str());//if there is no card, try parsing a number. - return; - } + if (!card) + { + intValue = atoi(s.c_str());//if there is no card, try parsing a number. + return; + } MTGCardInstance * target = card->target; if(!card->storedCard) card->storedCard = card->storedSourceCard; @@ -179,10 +179,8 @@ private: bool halfdown = false; bool twice = false; bool thrice = false; - bool plusone = false; - bool plustwo = false; - bool plusthree = false; bool other = false;//othertype:[subtype] + if (!target) target = card; int multiplier = 1; if (s[0] == '-') @@ -231,24 +229,7 @@ private: size_t tXXX = s.find("thrice"); s.erase(tXXX,tXXX + 6); } - if(s.find("plusone") != string::npos) - { - plusone = true; - size_t pOne = s.find("plusone"); - s.erase(pOne,pOne + 7); - } - if(s.find("plustwo") != string::npos) - { - plustwo = true; - size_t pTwo = s.find("plustwo"); - s.erase(pTwo,pTwo + 7); - } - if(s.find("plusthree") != string::npos) - { - plusthree = true; - size_t pThree = s.find("plusthree"); - s.erase(pThree,pThree + 9); - } + if(s.find("othertype") != string::npos) { other = true; @@ -273,18 +254,58 @@ private: size_t otc = s.find("otherconvertedcost"); s.erase(otc,otc + 5); } - if(s == "prex") + + if (s.find("plusend") != string::npos || s.find("minusend") != string::npos || s.find("math") != string::npos) { - if (card->setX > -1) - { - intValue = card->setX; - } - else - { - ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); - intValue = cX->getCost(Constants::NB_Colors); - delete cX; - } + //plus#plusend and minus#minusend splits the first part and second parts and parses the + //ints for each part, then either adds or subtracts those 2 variables as specified. + vectormathFound = parseBetween(s, "math", "mathend", true); + if (mathFound.size())//maths allows us to get the value before applying multipliers + { + WParsedInt numPar(mathFound[1], NULL, card); + intValue = numPar.getValue(); + + } + else + { + vectorplusSplit = parseBetween(s, "", "plus", true); + if (plusSplit.size()) + { + WParsedInt numPar(plusSplit[1], NULL, card); + intValue = numPar.getValue(); + } + vectorplusFound = parseBetween(s, "plus", "plusend", true); + if (plusFound.size()) + { + WParsedInt numPar(plusFound[1], NULL, card); + intValue += numPar.getValue(); + } + vectorminusSplit = parseBetween(s, "", "minus", true); + if (minusSplit.size()) + { + WParsedInt numPar(minusSplit[1], NULL, card); + intValue = numPar.getValue(); + } + vectorminusFound = parseBetween(s, "minus", "minusend", true); + if (minusFound.size()) + { + WParsedInt numPar(minusFound[1], NULL, card); + intValue -= numPar.getValue(); + } + } + } + else if(s == "prex") + { + if (card->setX > -1) + { + intValue = card->setX; + } + else + { + ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); + intValue = cX->getCost(Constants::NB_Colors); + delete cX; + } } else if (s == "x" || s == "X") { @@ -361,10 +382,10 @@ private: { intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_GREEN); } - else if (s == "Iroas")//devotion to red white - { - intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE); - } + else if (s == "Iroas")//devotion to red white + { + intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE); + } else if (s.find("type:") != string::npos) { size_t begins = s.find("type:"); @@ -681,10 +702,10 @@ private: { intValue = target->getCurrentToughness(); } - else if (s == "countedamount") - { - intValue = target->CountedObjects; - } + else if (s == "countedamount") + { + intValue = target->CountedObjects; + } else if (s == "kicked") { intValue = target->kicked; @@ -806,12 +827,18 @@ private: else if (s == "pbasiclandtypes")//Basic Land types { MTGGameZone * checkZone = card->controller()->inPlay(); - intValue = - cardHasTypeinZone("forest",checkZone) + - cardHasTypeinZone("plains",checkZone) + - cardHasTypeinZone("swamp",checkZone) + - cardHasTypeinZone("island",checkZone) + - cardHasTypeinZone("mountain",checkZone); + intValue = //mtg rules 205.4c + cardHasTypeinZone("waste", checkZone) + + cardHasTypeinZone("forest", checkZone) + + cardHasTypeinZone("plains", checkZone) + + cardHasTypeinZone("swamp", checkZone) + + cardHasTypeinZone("island", checkZone) + + cardHasTypeinZone("mountain", checkZone) + + cardHasTypeinZone("snow-covered forest", checkZone) + + cardHasTypeinZone("snow-covered plains", checkZone) + + cardHasTypeinZone("snow-covered swamp", checkZone) + + cardHasTypeinZone("snow-covered island", checkZone) + + cardHasTypeinZone("snow-covered mountain", checkZone); } else if (s == "myname")//Name of the card you control { @@ -858,13 +885,6 @@ private: cardHasTypeinZone("artifact",checkZone); } } - else if (s == "morethanfourcards") - { - intValue = 0; - int damage = card->playerTarget ? card->playerTarget->game->hand->nb_cards - 4 : card->controller()->opponent()->game->hand->nb_cards - 4; - if ( damage > 0 ) - intValue = damage; - } else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable { intValue = 0; @@ -874,55 +894,47 @@ private: intValue += card->controller()->game->inPlay->cards[j]->power; } } - else if (s == "revealedp") - { - if (card->revealedLast) - intValue = card->revealedLast->power; - } - else if (s == "revealedt") - { - if (card->revealedLast) - intValue = card->revealedLast->toughness; - } - else if (s == "revealedmana") - { - if (card->revealedLast) - intValue = card->revealedLast->getManaCost()->getConvertedCost(); - } - else + else if (s == "revealedp") + { + if (card->revealedLast) + intValue = card->revealedLast->power; + } + else if (s == "revealedt") + { + if (card->revealedLast) + intValue = card->revealedLast->toughness; + } + else if (s == "revealedmana") + { + if (card->revealedLast) + intValue = card->revealedLast->getManaCost()->getConvertedCost(); + } + else if(!intValue)//found nothing, try parsing a atoi { intValue = atoi(s.c_str()); } - if(intValue > 0) + if (intValue > 0)//dont divide by 0 the rest are valid. { - if(halfup) + if (halfup) { - if(intValue%2 == 1) + if (intValue % 2 == 1) intValue++; - intValue = intValue/2; + intValue = intValue / 2; } - if(halfdown) - intValue = intValue/2; - if(twice) - intValue = intValue*2; - if(thrice) - intValue = intValue*3; - if(plusone) - intValue = intValue+1; - if(plustwo) - intValue = intValue+2; - if(plusthree) - intValue = intValue+3; + if (halfdown) + intValue = intValue / 2; } - else + if (twice) + intValue = intValue * 2; + if (thrice) + intValue = intValue * 3; + if (intValue < 0) { - if(plusone) - intValue = intValue+1; - if(plustwo) - intValue = intValue+2; - if(plusthree) - intValue = intValue+3; + //we remove "-" at the start and are parsing for real values. + //if we ended up with a value less than 0, then we return just 0 + intValue = 0; } + intValue *= multiplier; } public: @@ -3477,7 +3489,7 @@ public: list colors; int power, toughness; int tokenId; - string _cardName; + string _cardName; string name; string sabilities; string starfound; @@ -3489,7 +3501,7 @@ public: MTGCardInstance * myToken; vector currentAbilities; Player * tokenReciever; - //by id + //by id ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, int tokenId,string starfound, WParsedInt * multiplier = NULL, int who = 0,bool aLivingWeapon = false) : ActivatedAbility(observer, _id, _source, _cost, 0), tokenId(tokenId), starfound(starfound),multiplier(multiplier), who(who),aLivingWeapon(aLivingWeapon) @@ -3499,18 +3511,18 @@ public: if (card) name = card->data->getName(); battleReady = false; } - //by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)... - ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL, - int who = 0, bool aLivingWeapon = false) : - ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon) - { - if (!multiplier) this->multiplier = NEW WParsedInt(1); - MTGCard * card = MTGCollection()->getCardByName(_cardName); - tokenId = card->getId(); - if (card) name = card->data->getName(); - battleReady = false; - } - //by construction + //by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)... + ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL, + int who = 0, bool aLivingWeapon = false) : + ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon) + { + if (!multiplier) this->multiplier = NEW WParsedInt(1); + MTGCard * card = MTGCollection()->getCardByName(_cardName); + tokenId = card->getId(); + if (card) name = card->data->getName(); + battleReady = false; + } + //by construction ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string sname, string stypes, int _power, int _toughness, string sabilities, string starfound,WParsedInt * multiplier = NULL, int _who = 0,bool aLivingWeapon = false,string spt = "") : ActivatedAbility(observer, _id, _source, _cost, 0),sabilities(sabilities),starfound(starfound), multiplier(multiplier), who(_who),aLivingWeapon(aLivingWeapon),spt(spt) @@ -4033,12 +4045,12 @@ class AThis: public MTGAbility, public NestedAbility public: MTGAbility * a; ThisDescriptor * td; - string restrictionCheck; + string restrictionCheck; AThis(GameObserver* observer, int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability, string restriction = "") : MTGAbility(observer, _id, _source, _target), NestedAbility(ability) { td = _td; - restrictionCheck = restriction; + restrictionCheck = restriction; ability->source = source; ability->target = target; a = NULL; @@ -4062,18 +4074,18 @@ public: int resolve() { - int match = 0; - if (td) - { - match = td->match(source); - } - else - {//restriction check instead of Targetchooser - AbilityFactory abf(target->getObserver()); - int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck); - if (checkCond) - match = 1; - } + int match = 0; + if (td) + { + match = td->match(source); + } + else + {//restriction check instead of Targetchooser + AbilityFactory abf(target->getObserver()); + int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck); + if (checkCond) + match = 1; + } if (match > 0) { addAbilityToGame(); @@ -4120,7 +4132,7 @@ public: { AThis * a = NEW AThis(*this); a->ability = ability->clone(); - if(a->td) + if(a->td) a->td = td->clone(); return a; } @@ -4338,11 +4350,11 @@ public: class ABestow : public ActivatedAbility { public: - MTGCardInstance * _card; - ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); - int resolve(); - const string getMenuText(); - ABestow * clone() const; + MTGCardInstance * _card; + ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); + int resolve(); + const string getMenuText(); + ABestow * clone() const; }; /* Can tap a target for a cost */ @@ -4369,16 +4381,16 @@ public: class AAWhatsX : public ActivatedAbility { public: - int value; - MTGAbility * costRule; - AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); - int resolve(); - const string getMenuText() - { - sprintf(menuText, "%i", value); - return menuText; - }; - AAWhatsX * clone() const; + int value; + MTGAbility * costRule; + AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); + int resolve(); + const string getMenuText() + { + sprintf(menuText, "%i", value); + return menuText; + }; + AAWhatsX * clone() const; }; /* set max level up on a levelup creature this is an Ai hint ability, no effect for players.*/ @@ -4395,17 +4407,17 @@ public: class AACountObject : public ActivatedAbility { public: - string value; + string value; - AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value =""); - int resolve(); - AACountObject * clone() const; + AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value =""); + int resolve(); + AACountObject * clone() const; }; /* Can prevent a card from untapping next untap */ class AAFrozen: public ActivatedAbility { public: - bool freeze; + bool freeze; AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, bool tap, ManaCost * _cost = NULL); int resolve(); const string getMenuText(); @@ -5196,32 +5208,32 @@ public: class AGrant : public MTGAbility { public: - MTGCardInstance * Blessed; - bool resolved; - MTGAbility * Granted; - MTGAbility * toGrant; - AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); - void Update(float dt); - void resolveGrant(); - int resolve(); - const string getMenuText(); - AGrant * clone() const; - ~AGrant(); + MTGCardInstance * Blessed; + bool resolved; + MTGAbility * Granted; + MTGAbility * toGrant; + AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + void Update(float dt); + void resolveGrant(); + int resolve(); + const string getMenuText(); + AGrant * clone() const; + ~AGrant(); private: - void removeGranted(MTGCardInstance *_target); + void removeGranted(MTGCardInstance *_target); }; //GrantWrapper class AGrantWrapper : public InstantAbility { public: - AGrant * ability; - MTGAbility * Granted; - AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); - int resolve(); - const string getMenuText(); - AGrantWrapper * clone() const; - ~AGrantWrapper(); + AGrant * ability; + MTGAbility * Granted; + AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + int resolve(); + const string getMenuText(); + AGrantWrapper * clone() const; + ~AGrantWrapper(); }; //ABlink @@ -6473,7 +6485,7 @@ public: MTGCardInstance * theNamedCard; bool noEvent; bool putinplay; - bool asNormalMadness; + bool asNormalMadness; AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay,bool asNormalMadness = false); int testDestroy(){return 0;}; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 355932ccf..979de37c6 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -58,6 +58,10 @@ public: int Angel[2]; bool dragonbonusgranted[2]; int dragon[2]; + bool eldrazibonusgranted[2]; + int eldrazi[2]; + bool werewolfbonusgranted[2]; + int werewolf[2]; int receiveEvent(WEvent * event); void grantAward(string awardName,int amount); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 2516a18be..eb2d7e5bb 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -45,477 +45,477 @@ MTGEventText * MTGEventText::clone() const //generic activated ability for wrapping reveals. GenericRevealAbility::GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _howMany) : - ActivatedAbility(observer, id, source, NULL), howMany(_howMany) + Targetable * target, string _howMany) : + ActivatedAbility(observer, id, source, NULL), howMany(_howMany) { - this->GetId(); + this->GetId(); } int GenericRevealAbility::resolve() { - MTGAbility * ability = NEW MTGRevealingCards(game, this->GetId(), source, howMany); - ability->addToGame(); - return 1; + MTGAbility * ability = NEW MTGRevealingCards(game, this->GetId(), source, howMany); + ability->addToGame(); + return 1; } const string GenericRevealAbility::getMenuText() { - return "Reveal Cards"; + return "Reveal Cards"; } GenericRevealAbility * GenericRevealAbility::clone() const { - GenericRevealAbility * a = NEW GenericRevealAbility(*this); - return a; + GenericRevealAbility * a = NEW GenericRevealAbility(*this); + return a; } GenericRevealAbility::~GenericRevealAbility() { - //SAFE_DELETE(ability); + //SAFE_DELETE(ability); } //carddisplay created for use in abilities. RevealDisplay::RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener, TargetChooser * tc, - int nb_displayed_items) : - CardDisplay(id, game, x, y, listener, tc, nb_displayed_items) + int nb_displayed_items) : + CardDisplay(id, game, x, y, listener, tc, nb_displayed_items) { } void RevealDisplay::AddCard(MTGCardInstance * _card) { - CardGui * card = NEW CardView(CardView::nullZone, _card, static_cast (x + 20 + (mObjects.size() - start_item) * 30), - static_cast (y + 25)); - Add(card); + CardGui * card = NEW CardView(CardView::nullZone, _card, static_cast (x + 20 + (mObjects.size() - start_item) * 30), + static_cast (y + 25)); + Add(card); } bool RevealDisplay::CheckUserInput(JButton key) { - if (JGE_BTN_SEC == key || JGE_BTN_PRI == key || JGE_BTN_UP == key || JGE_BTN_DOWN == key) - return false; + if (JGE_BTN_SEC == key || JGE_BTN_PRI == key || JGE_BTN_UP == key || JGE_BTN_DOWN == key) + return false; - return CardDisplay::CheckUserInput(key); + return CardDisplay::CheckUserInput(key); } //display card selector box of specified zone. MTGRevealingCards::MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string coreAbility) : - MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) + MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) { - abilityToCast = NULL; - revealDisplay = NULL; - abilityFirst = NULL; + abilityToCast = NULL; + revealDisplay = NULL; + abilityFirst = NULL; abilitySecond = NULL; - abilityString = coreAbility; - initCD = false; + abilityString = coreAbility; + initCD = false; - afterReveal = ""; - afterEffectActivated = false; + afterReveal = ""; + afterEffectActivated = false; - repeat = false; - playerForZone = NULL; - revealCertainTypes = ""; - revealUntil = ""; + repeat = false; + playerForZone = NULL; + revealCertainTypes = ""; + revealUntil = ""; - if (card->playerTarget) - playerForZone = card->playerTarget; - else - playerForZone = source->controller(); + if (card->playerTarget) + playerForZone = card->playerTarget; + else + playerForZone = source->controller(); - RevealZone = playerForZone->game->reveal; - zone = RevealZone; - RevealFromZone = playerForZone->game->library; + RevealZone = playerForZone->game->reveal; + zone = RevealZone; + RevealFromZone = playerForZone->game->library; - vectoramount = parseBetween(coreAbility, "", " "); - if (amount.size()) - { - number = amount[1]; - } + vectoramount = parseBetween(coreAbility, "", " "); + if (amount.size()) + { + number = amount[1]; + } - vectordifferentZone = parseBetween(coreAbility, "revealzone(", ")"); - if (differentZone.size()) - { - RevealFromZone = MTGGameZone::stringToZone(game,differentZone[1],source,NULL); - } + vectordifferentZone = parseBetween(coreAbility, "revealzone(", ")"); + if (differentZone.size()) + { + RevealFromZone = MTGGameZone::stringToZone(game,differentZone[1],source,NULL); + } - vectorcertainTypes = parseBetween(coreAbility, "revealtype(", ")"); - if (certainTypes.size()) - { - revealCertainTypes = certainTypes[1]; - } + vectorcertainTypes = parseBetween(coreAbility, "revealtype(", ")"); + if (certainTypes.size()) + { + revealCertainTypes = certainTypes[1]; + } - vectorRevealCardUntil = parseBetween(coreAbility, "revealuntil(", ")"); - if (RevealCardUntil.size()) - { - revealUntil = RevealCardUntil[1]; - } + vectorRevealCardUntil = parseBetween(coreAbility, "revealuntil(", ")"); + if (RevealCardUntil.size()) + { + revealUntil = RevealCardUntil[1]; + } - vectorfirst = parseBetween(coreAbility, "optionone ", " optiononeend"); - if (first.size()) - { - abilityOne = first[1]; - } - vectorsecond = parseBetween(coreAbility, "optiontwo ", " optiontwoend"); - if (second.size()) - { - abilityTwo = second[1]; - } - vectorafterEffect = parseBetween(coreAbility, "afterrevealed ", " afterrevealedend"); - if (afterEffect.size()) - { - afterReveal = afterEffect[1]; - } + vectorfirst = parseBetween(coreAbility, "optionone ", " optiononeend"); + if (first.size()) + { + abilityOne = first[1]; + } + vectorsecond = parseBetween(coreAbility, "optiontwo ", " optiontwoend"); + if (second.size()) + { + abilityTwo = second[1]; + } + vectorafterEffect = parseBetween(coreAbility, "afterrevealed ", " afterrevealedend"); + if (afterEffect.size()) + { + afterReveal = afterEffect[1]; + } - repeat = coreAbility.find("repeat") != string::npos; + repeat = coreAbility.find("repeat") != string::npos; } void MTGRevealingCards::Update(float dt) { - if (game->OpenedDisplay != this->revealDisplay && !initCD)//wait your turn - { - //if any carddisplays are open, dont do anything until theyre closed, then wait your turn if multiple reveals trigger. - return; - } - if (game->mLayers->actionLayer()->menuObject) - return;//dont do any of this if a menuobject exist. - if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) - { + if (game->OpenedDisplay != this->revealDisplay && !initCD)//wait your turn + { + //if any carddisplays are open, dont do anything until theyre closed, then wait your turn if multiple reveals trigger. + return; + } + if (game->mLayers->actionLayer()->menuObject) + return;//dont do any of this if a menuobject exist. + if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) + { - WParsedInt nbCardP(number, NULL, source); - nbCard = nbCardP.getValue(); - int adjust = 0; - switch (nbCard) - { - //adjust length and location of carddisplay box. - case 1:adjust = 120; break; - case 2:adjust = 145; break; - case 3:adjust = 175; break; - case 4:adjust = 200; break; - case 5:adjust = 225; break; - default:adjust = 225; break; - } - if (revealUntil.size()) - { - adjust = 225; - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL,5); - } - else - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); - revealDisplay->zone = RevealFromZone; - trashDisplays.push_back(revealDisplay); + WParsedInt nbCardP(number, NULL, source); + nbCard = nbCardP.getValue(); + int adjust = 0; + switch (nbCard) + { + //adjust length and location of carddisplay box. + case 1:adjust = 120; break; + case 2:adjust = 145; break; + case 3:adjust = 175; break; + case 4:adjust = 200; break; + case 5:adjust = 225; break; + default:adjust = 225; break; + } + if (revealUntil.size()) + { + adjust = 225; + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL,5); + } + else + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); + revealDisplay->zone = RevealFromZone; + trashDisplays.push_back(revealDisplay); - if (revealCertainTypes.size())//revealing cards of a TARGETCHOOSER type. - { - TargetChooserFactory tcf(game); - TargetChooser * rTc = tcf.createTargetChooser(revealCertainTypes, source); - int startingNumber = RevealFromZone->nb_cards - 1; - if (rTc) - for (int i = startingNumber; i > -1; i--) - { - if (!RevealFromZone->cards.size()) - break; - MTGCardInstance * toMove = RevealFromZone->cards[i]; - if (toMove) - { - if (rTc->canTarget(toMove, true)) - { - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } - } + if (revealCertainTypes.size())//revealing cards of a TARGETCHOOSER type. + { + TargetChooserFactory tcf(game); + TargetChooser * rTc = tcf.createTargetChooser(revealCertainTypes, source); + int startingNumber = RevealFromZone->nb_cards - 1; + if (rTc) + for (int i = startingNumber; i > -1; i--) + { + if (!RevealFromZone->cards.size()) + break; + MTGCardInstance * toMove = RevealFromZone->cards[i]; + if (toMove) + { + if (rTc->canTarget(toMove, true)) + { + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } + } - } - SAFE_DELETE(rTc); - } - else if(revealUntil.size())//reveal cards until you reveal a TARGETCHOOSER. - { - TargetChooserFactory tcf(game); - TargetChooser * rUc = tcf.createTargetChooser(revealUntil, source); - bool foundCard = false; - int howMany = nbCard; - int startingNumber = RevealFromZone->nb_cards; - for (int i = 0; i < startingNumber; i++) - { - if (foundCard && howMany == 0) - break; - if (howMany == 0) - break; //not allowed to reveal until 0 of something is revealed. - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - if (rUc->canTarget(toMove, true)) - { - foundCard = true; - howMany--; - } + } + SAFE_DELETE(rTc); + } + else if(revealUntil.size())//reveal cards until you reveal a TARGETCHOOSER. + { + TargetChooserFactory tcf(game); + TargetChooser * rUc = tcf.createTargetChooser(revealUntil, source); + bool foundCard = false; + int howMany = nbCard; + int startingNumber = RevealFromZone->nb_cards; + for (int i = 0; i < startingNumber; i++) + { + if (foundCard && howMany == 0) + break; + if (howMany == 0) + break; //not allowed to reveal until 0 of something is revealed. + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + if (rUc->canTarget(toMove, true)) + { + foundCard = true; + howMany--; + } - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } - } - SAFE_DELETE(rUc); - } - else - { - for (int i = 0; i < nbCard; i++)//normal reveal - { - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } + } + SAFE_DELETE(rUc); + } + else + { + for (int i = 0; i < nbCard; i++)//normal reveal + { + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } - } + } - } + } - //build the zone, create the first ability. - revealDisplay->init(RevealZone); - revealDisplay->zone = RevealZone; - game->OpenedDisplay = revealDisplay; - toResolve(); - initCD = true; - } + //build the zone, create the first ability. + revealDisplay->init(RevealZone); + revealDisplay->zone = RevealZone; + game->OpenedDisplay = revealDisplay; + toResolve(); + initCD = true; + } - //card display is ready and loaded, abilities have fired at this point. - //critical for testdestroy, a function that determines if a ability can - //exist in condiations such as source not being in play. - - if (!zone->cards.size()) - { - //all possible actions are done, the zone is empty, lets NULL it so it clears it off the screen. - //DO NOT SAFE_DELETE here, it destroys the card->view and backups kept for the second ability. - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; + //card display is ready and loaded, abilities have fired at this point. + //critical for testdestroy, a function that determines if a ability can + //exist in condiations such as source not being in play. + + if (!zone->cards.size()) + { + //all possible actions are done, the zone is empty, lets NULL it so it clears it off the screen. + //DO NOT SAFE_DELETE here, it destroys the card->view and backups kept for the second ability. + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; - if (repeat) - { - initCD = false; - } - else if (afterReveal.size() && !afterEffectActivated) - { - afterEffectActivated = true; - abilityAfter = contructAbility(afterReveal); - game->addObserver(abilityAfter); - } - else - this->removeFromGame(); - } + if (repeat) + { + initCD = false; + } + else if (afterReveal.size() && !afterEffectActivated) + { + afterEffectActivated = true; + abilityAfter = contructAbility(afterReveal); + game->addObserver(abilityAfter); + } + else + this->removeFromGame(); + } - if (revealDisplay) - { - revealDisplay->Update(dt); - Render(); - } + if (revealDisplay) + { + revealDisplay->Update(dt); + Render(); + } - MTGAbility::Update(dt); + MTGAbility::Update(dt); } void MTGRevealingCards::CardViewBackup(MTGCardInstance * backup) { - CardView* t; + CardView* t; - t = NEW CardView(CardView::nullZone, backup, 0, 0); - //we store copies of the card view since the safe_delete of card displays also deletes the guis stored in them. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); - return; + t = NEW CardView(CardView::nullZone, backup, 0, 0); + //we store copies of the card view since the safe_delete of card displays also deletes the guis stored in them. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); + return; } int MTGRevealingCards::testDestroy() { - if (game->mExtraPayment) - return 0; - if (revealDisplay) - return 0; - if (zone->cards.size()) - return 0; - if (!initCD) - return 0; - if (game->mLayers->actionLayer()->menuObject) - return 0; - if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) - return 0; + if (game->mExtraPayment) + return 0; + if (revealDisplay) + return 0; + if (zone->cards.size()) + return 0; + if (!initCD) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) + return 0; - return 1; + return 1; } int MTGRevealingCards::toResolve() { - TargetChooserFactory tcf(game); - vectorsplitTarget = parseBetween(abilityOne, "target(", ")"); - //we build a tc to check if the first ability has any valid targets, if it doesnt, just add the 2nd one. - if (splitTarget.size()) - { - TargetChooser * rTc = tcf.createTargetChooser(splitTarget[1].c_str(), source); + TargetChooserFactory tcf(game); + vectorsplitTarget = parseBetween(abilityOne, "target(", ")"); + //we build a tc to check if the first ability has any valid targets, if it doesnt, just add the 2nd one. + if (splitTarget.size()) + { + TargetChooser * rTc = tcf.createTargetChooser(splitTarget[1].c_str(), source); - if (rTc && rTc->countValidTargets()) - { - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - - } - else - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); + if (rTc && rTc->countValidTargets()) + { + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); - } - SAFE_DELETE(rTc); - } - else//the first ability is not targeted - { - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - } - return 1; + } + else + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + + } + SAFE_DELETE(rTc); + } + else//the first ability is not targeted + { + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + } + return 1; } MTGAbility * MTGRevealingCards::contructAbility(string abilityToMake) { - AbilityFactory af(game); - abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); - if (!abilityToCast) - return NULL; - abilityToCast->canBeInterrupted = false; - abilityToCast->forceDestroy = 1; - return abilityToCast; + AbilityFactory af(game); + abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); + if (!abilityToCast) + return NULL; + abilityToCast->canBeInterrupted = false; + abilityToCast->forceDestroy = 1; + return abilityToCast; } void MTGRevealingCards::Render() { - if (!revealDisplay) - return; - CheckUserInput(mEngine->ReadButton()); - revealDisplay->CheckUserInput(mEngine->ReadButton()); - revealDisplay->Render(); - return; + if (!revealDisplay) + return; + CheckUserInput(mEngine->ReadButton()); + revealDisplay->CheckUserInput(mEngine->ReadButton()); + revealDisplay->Render(); + return; } bool MTGRevealingCards::CheckUserInput(JButton key) { - //DO NOT REFACTOR BELOW, IT KEPT SPLIT UP TO MAINTAIN READABILITY. + //DO NOT REFACTOR BELOW, IT KEPT SPLIT UP TO MAINTAIN READABILITY. //we override check inputs, we MUST complete reveal and its effects before being allowed to do anything else. - TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); - if (this->source->controller()->isAI()) - { - if (this->source->controller() != game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); - } - if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key)//android back button - { - if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) - { - tc->done = true; - tc->forceTargetListReadyByPlayer = 1; - //this is for when we have targets but only want to move Y targets, it allows us to - //tell the targetchooser we are done. - if (!abilitySecond && !tc->getNbTargets() && tc->source) - {//we selected nothing for the first ability. - tc->source->getObserver()->cardClick(tc->source, 0, false); - if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(0); - //remove it from the game, update, and remove it from stack if needed. - //before adding next ability, otherwise we end up with a menu reactToClick. - if (zone->cards.size() && abilityFirst->testDestroy())//generally only want to add ability 2 if anything is left in the zone. - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } - } - else if (tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - } - } - else if (!tc && !abilitySecond)//the actions of the first card have finished and we're done looking at the cards. - { //or the first ability was an "all(" which was not a mover ability. - CheckUserInput(JGE_BTN_OK); - } - return false; - } - if (JGE_BTN_OK == key)//for ease if we're sitting there looking at the card display and click a card after first ability. - { //looks redundent and can be added above as another condiational, however we would end up with a massive - //if statement that becomes very very hard to follow. - if (!tc && !abilitySecond) - { - if (abilityFirst) - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(1); + TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); + if (this->source->controller()->isAI()) + { + if (this->source->controller() != game->isInterrupting) + game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); + } + if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key)//android back button + { + if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) + { + tc->done = true; + tc->forceTargetListReadyByPlayer = 1; + //this is for when we have targets but only want to move Y targets, it allows us to + //tell the targetchooser we are done. + if (!abilitySecond && !tc->getNbTargets() && tc->source) + {//we selected nothing for the first ability. + tc->source->getObserver()->cardClick(tc->source, 0, false); + if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(0); + //remove it from the game, update, and remove it from stack if needed. + //before adding next ability, otherwise we end up with a menu reactToClick. + if (zone->cards.size() && abilityFirst->testDestroy())//generally only want to add ability 2 if anything is left in the zone. + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } + } + else if (tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + } + } + else if (!tc && !abilitySecond)//the actions of the first card have finished and we're done looking at the cards. + { //or the first ability was an "all(" which was not a mover ability. + CheckUserInput(JGE_BTN_OK); + } + return false; + } + if (JGE_BTN_OK == key)//for ease if we're sitting there looking at the card display and click a card after first ability. + { //looks redundent and can be added above as another condiational, however we would end up with a massive + //if statement that becomes very very hard to follow. + if (!tc && !abilitySecond) + { + if (abilityFirst) + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(1); - if (zone->cards.size()) - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } + if (zone->cards.size()) + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } - } - } - if(revealDisplay) + } + } + if(revealDisplay) return revealDisplay->CheckUserInput(key); - return false; + return false; } MTGRevealingCards * MTGRevealingCards::clone() const { - return NEW MTGRevealingCards(*this); + return NEW MTGRevealingCards(*this); } MTGRevealingCards::~MTGRevealingCards() { - for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) - SAFE_DELETE(*it); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - SAFE_DELETE(*it); + for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) + SAFE_DELETE(*it); + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + SAFE_DELETE(*it); } int MTGRevealingCards::receiveEvent(WEvent* e) { - if (WEventZoneChange* event = dynamic_cast(e)) - { - if (event->from == zone) - { - CardView* t; - if (event->card->view) - t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + if (WEventZoneChange* event = dynamic_cast(e)) + { + if (event->from == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); else t = NEW CardView(CardView::nullZone, event->card, (float)x, (float)y); - //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. - //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than - //they should be, possibly someone being to over cautious. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); + //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. + //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than + //they should be, possibly someone being to over cautious. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); return 1; - } - } - return 0; + } + } + return 0; } @@ -532,353 +532,353 @@ int MTGRevealingCards::receiveEvent(WEvent* e) ///delayed changes the order, makes the ability fire after the 2nd reveal is finished. /// MTGScryCards::MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string coreAbility) : - MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) + MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) { - abilityToCast = NULL; - revealDisplay = NULL; - abilityFirst = NULL; - abilitySecond = NULL; - abilityString = coreAbility; - delayedAbilityString = ""; - revealTopAmount = 1;//scry, then reveal the top card and do effect. + abilityToCast = NULL; + revealDisplay = NULL; + abilityFirst = NULL; + abilitySecond = NULL; + abilityString = coreAbility; + delayedAbilityString = ""; + revealTopAmount = 1;//scry, then reveal the top card and do effect. - initCD = false; - RevealZone = source->controller()->game->reveal; - zone =RevealZone; - RevealFromZone = source->controller()->game->library; + initCD = false; + RevealZone = source->controller()->game->reveal; + zone =RevealZone; + RevealFromZone = source->controller()->game->library; - vectoramount = parseBetween(coreAbility, "", " "); - if (amount.size()) - { - number = amount[1]; - } + vectoramount = parseBetween(coreAbility, "", " "); + if (amount.size()) + { + number = amount[1]; + } - vectordifferentZone = parseBetween(coreAbility, "scryzone(", ")"); - if (differentZone.size()) - { - RevealFromZone = MTGGameZone::stringToZone(game, differentZone[1], source, NULL); - } + vectordifferentZone = parseBetween(coreAbility, "scryzone(", ")"); + if (differentZone.size()) + { + RevealFromZone = MTGGameZone::stringToZone(game, differentZone[1], source, NULL); + } - abilityOne = "name(Place on top) target(*|myreveal) moveto(mylibrary)"; + abilityOne = "name(Place on top) target(*|myreveal) moveto(mylibrary)"; delayed = coreAbility.find("delayed") != string::npos; - dontRevealAfter = coreAbility.find("dontshow") != string::npos; - if(dontRevealAfter) - revealTopAmount = 0; - vectorsecond = parseBetween(coreAbility, "scrycore ", " scrycoreend"); - if (second.size()) - { - if (delayed) - { - abilityTwo = "target(*|reveal) name(Reveal the top card) donothing"; - delayedAbilityString = second[1]; - } - else - abilityTwo = second[1]; - } + dontRevealAfter = coreAbility.find("dontshow") != string::npos; + if(dontRevealAfter) + revealTopAmount = 0; + vectorsecond = parseBetween(coreAbility, "scrycore ", " scrycoreend"); + if (second.size()) + { + if (delayed) + { + abilityTwo = "target(*|reveal) name(Reveal the top card) donothing"; + delayedAbilityString = second[1]; + } + else + abilityTwo = second[1]; + } - + } void MTGScryCards::Update(float dt) { - if (game->OpenedDisplay != this->revealDisplay && !initCD) - return; - if (game->mLayers->actionLayer()->menuObject) - return; - if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) - { - WParsedInt nbCardP(number, NULL, source); - nbCard = nbCardP.getValue(); - initDisplay(nbCard); - toResolve(); - } - initCD = true; - if (!zone->cards.size() && abilitySecond) - { - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; - this->removeFromGame(); - } - if (revealDisplay) - { - revealDisplay->Update(dt); - Render(); - } - MTGAbility::Update(dt); + if (game->OpenedDisplay != this->revealDisplay && !initCD) + return; + if (game->mLayers->actionLayer()->menuObject) + return; + if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) + { + WParsedInt nbCardP(number, NULL, source); + nbCard = nbCardP.getValue(); + initDisplay(nbCard); + toResolve(); + } + initCD = true; + if (!zone->cards.size() && abilitySecond) + { + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; + this->removeFromGame(); + } + if (revealDisplay) + { + revealDisplay->Update(dt); + Render(); + } + MTGAbility::Update(dt); } void MTGScryCards::initDisplay(int value) { - if (RevealZone->cards.size()) - { - do - { - MTGCardInstance * toMove = RevealZone->cards[0]; - if (toMove) - { - MTGAbility * a = NEW AALibraryBottom(game, getMaxId(), source, toMove); - a->oneShot = 1; - a->resolve(); - SAFE_DELETE(a); - } - } while (RevealZone->cards.size()); + if (RevealZone->cards.size()) + { + do + { + MTGCardInstance * toMove = RevealZone->cards[0]; + if (toMove) + { + MTGAbility * a = NEW AALibraryBottom(game, getMaxId(), source, toMove); + a->oneShot = 1; + a->resolve(); + SAFE_DELETE(a); + } + } while (RevealZone->cards.size()); - game->Update(0); - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; - } - int adjust = 0; - switch (value) - { - case 1:adjust = 120; break; - case 2:adjust = 145; break; - case 3:adjust = 175; break; - case 4:adjust = 200; break; - case 5:adjust = 225; break; - default:adjust = 225; break; - } - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); - revealDisplay->zone = RevealFromZone; - trashDisplays.push_back(revealDisplay); - for (int i = 0; i < value; i++) - { - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - CardView* t; - t = NEW CardView(CardView::nullZone, toMove, 0, 0); - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - cards.push_back(t); - source->controller()->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } - } - revealDisplay->init(RevealZone); - revealDisplay->zone = RevealZone; - game->OpenedDisplay = revealDisplay; + game->Update(0); + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; + } + int adjust = 0; + switch (value) + { + case 1:adjust = 120; break; + case 2:adjust = 145; break; + case 3:adjust = 175; break; + case 4:adjust = 200; break; + case 5:adjust = 225; break; + default:adjust = 225; break; + } + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); + revealDisplay->zone = RevealFromZone; + trashDisplays.push_back(revealDisplay); + for (int i = 0; i < value; i++) + { + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + CardView* t; + t = NEW CardView(CardView::nullZone, toMove, 0, 0); + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + cards.push_back(t); + source->controller()->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } + } + revealDisplay->init(RevealZone); + revealDisplay->zone = RevealZone; + game->OpenedDisplay = revealDisplay; } int MTGScryCards::testDestroy() { - if (game->mExtraPayment) - return 0; - if (revealDisplay) - return 0; - if (zone->cards.size()) - return 0; - if (!initCD) - return 0; - if (game->mLayers->actionLayer()->menuObject) - return 0; - if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) - return 0; + if (game->mExtraPayment) + return 0; + if (revealDisplay) + return 0; + if (zone->cards.size()) + return 0; + if (!initCD) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) + return 0; - return 1; + return 1; } int MTGScryCards::toResolve() { - //scry will always have valid targets. - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - return 1; + //scry will always have valid targets. + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + return 1; } MTGAbility * MTGScryCards::contructAbility(string abilityToMake) { - AbilityFactory af(game); - abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); - if (!abilityToCast) - return NULL; - abilityToCast->canBeInterrupted = false; - abilityToCast->forceDestroy = 1; - return abilityToCast; + AbilityFactory af(game); + abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); + if (!abilityToCast) + return NULL; + abilityToCast->canBeInterrupted = false; + abilityToCast->forceDestroy = 1; + return abilityToCast; } void MTGScryCards::Render() { - if (!revealDisplay) - return; - CheckUserInput(mEngine->ReadButton()); - if (revealDisplay) - { - revealDisplay->CheckUserInput(mEngine->ReadButton()); - revealDisplay->Render(); - } - return; + if (!revealDisplay) + return; + CheckUserInput(mEngine->ReadButton()); + if (revealDisplay) + { + revealDisplay->CheckUserInput(mEngine->ReadButton()); + revealDisplay->Render(); + } + return; } bool MTGScryCards::CheckUserInput(JButton key) { - //DO NOT REFACTOR BELOW - TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); - if (this->source->controller()->isAI()) - {//ai doesnt click button, and the engine has no way of knowing whos clicking button - //for now we will cancel interrupts made when ai is making choice - //in the future we will need a way to find out if the human is pressing the keys and which player. - if (this->source->controller() != game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); - } - if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key) - { - if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) - { - tc->done = true; - tc->forceTargetListReadyByPlayer = 1; - if (!abilitySecond && !tc->getNbTargets() && tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(0); - if (zone->cards.size() && abilityFirst->testDestroy()) - { - initDisplay(revealTopAmount); - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } - } - else if (tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - } - } - else if (!tc && !abilitySecond) - { - CheckUserInput(JGE_BTN_OK); - } - return false; - } - if (JGE_BTN_OK == key) - { - if (!tc && !abilitySecond) - { - if (abilityFirst) - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(1); + //DO NOT REFACTOR BELOW + TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); + if (this->source->controller()->isAI()) + {//ai doesnt click button, and the engine has no way of knowing whos clicking button + //for now we will cancel interrupts made when ai is making choice + //in the future we will need a way to find out if the human is pressing the keys and which player. + if (this->source->controller() != game->isInterrupting) + game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); + } + if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key) + { + if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) + { + tc->done = true; + tc->forceTargetListReadyByPlayer = 1; + if (!abilitySecond && !tc->getNbTargets() && tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(0); + if (zone->cards.size() && abilityFirst->testDestroy()) + { + initDisplay(revealTopAmount); + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } + } + else if (tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + } + } + else if (!tc && !abilitySecond) + { + CheckUserInput(JGE_BTN_OK); + } + return false; + } + if (JGE_BTN_OK == key) + { + if (!tc && !abilitySecond) + { + if (abilityFirst) + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(1); - if (zone->cards.size() || (revealDisplay && !zone->cards.size())) - { - initDisplay(revealTopAmount); - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } + if (zone->cards.size() || (revealDisplay && !zone->cards.size())) + { + initDisplay(revealTopAmount); + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } - } - if (!tc && abilitySecond && abilitySecond->testDestroy()) - { - do - { - if (!RevealZone->cards.size()) - break; - MTGCardInstance * toMove = RevealZone->cards[0]; - if (toMove) - { - source->revealedLast = toMove; - MTGAbility * a = NEW AAMover(game, getMaxId(), source, toMove,"library", "Place on top"); - a->oneShot = true; - a->resolve(); - SAFE_DELETE(a); - } - } while (RevealZone->cards.size()); + } + if (!tc && abilitySecond && abilitySecond->testDestroy()) + { + do + { + if (!RevealZone->cards.size()) + break; + MTGCardInstance * toMove = RevealZone->cards[0]; + if (toMove) + { + source->revealedLast = toMove; + MTGAbility * a = NEW AAMover(game, getMaxId(), source, toMove,"library", "Place on top"); + a->oneShot = true; + a->resolve(); + SAFE_DELETE(a); + } + } while (RevealZone->cards.size()); - if (delayed) - { - MTGAbility * delayedA = contructAbility(delayedAbilityString); - if (delayedA->oneShot) - { - delayedA->resolve(); - SAFE_DELETE(delayedA); - } - else - delayedA->addToGame(); - - } - } - } - if (revealDisplay) - return revealDisplay->CheckUserInput(key); - return false; + if (delayed) + { + MTGAbility * delayedA = contructAbility(delayedAbilityString); + if (delayedA->oneShot) + { + delayedA->resolve(); + SAFE_DELETE(delayedA); + } + else + delayedA->addToGame(); + + } + } + } + if (revealDisplay) + return revealDisplay->CheckUserInput(key); + return false; } MTGScryCards * MTGScryCards::clone() const { - return NEW MTGScryCards(*this); + return NEW MTGScryCards(*this); } MTGScryCards::~MTGScryCards() { - for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) - SAFE_DELETE(*it); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - SAFE_DELETE(*it); + for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) + SAFE_DELETE(*it); + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + SAFE_DELETE(*it); } int MTGScryCards::receiveEvent(WEvent* e) { - if (WEventZoneChange* event = dynamic_cast(e)) - { - if (event->from == zone) - { - CardView* t; - if (event->card->view) - t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + if (WEventZoneChange* event = dynamic_cast(e)) + { + if (event->from == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); else t = NEW CardView(CardView::nullZone, event->card, (float)x, (float)y); - //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. - //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than - //they should be, possibly someone being to over cautious. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); + //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. + //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than + //they should be, possibly someone being to over cautious. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); return 1; - } - } - return 0; + } + } + return 0; } //scry wrapper GenericScryAbility::GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _howMany) : - ActivatedAbility(observer, id, source, NULL), howMany(_howMany) + Targetable * target, string _howMany) : + ActivatedAbility(observer, id, source, NULL), howMany(_howMany) { - this->GetId(); + this->GetId(); } int GenericScryAbility::resolve() { - MTGAbility * ability = NEW MTGScryCards(game, this->GetId(), source, howMany); - ability->addToGame(); - return 1; + MTGAbility * ability = NEW MTGScryCards(game, this->GetId(), source, howMany); + ability->addToGame(); + return 1; } const string GenericScryAbility::getMenuText() { - return "Scry Cards"; + return "Scry Cards"; } GenericScryAbility * GenericScryAbility::clone() const { - GenericScryAbility * a = NEW GenericScryAbility(*this); - return a; + GenericScryAbility * a = NEW GenericScryAbility(*this); + return a; } GenericScryAbility::~GenericScryAbility() { - //SAFE_DELETE(ability); + //SAFE_DELETE(ability); } //////////////////////// @@ -1319,6 +1319,7 @@ int AACopier::resolve() MTGCard* clone = MTGCollection()->getCardById(_target->copiedID); MTGCardInstance * myClone = NEW MTGCardInstance(clone, source->controller()->game); source->copy(myClone); + SAFE_DELETE(myClone); source->isACopier = true; source->copiedID = _target->getMTGId(); source->modifiedbAbi = _target->modifiedbAbi; @@ -2183,9 +2184,9 @@ int GenericPaidAbility::resolve() } else { - //dangerous code below, parse a string line that might not exist. baseAbilityStrSplit[0] - //you either have a string and do stuff, or dont and leave the ability - //not fixing this since its been heavily modified from the orginal implementation. + //dangerous code below, parse a string line that might not exist. baseAbilityStrSplit[0] + //you either have a string and do stuff, or dont and leave the ability + //not fixing this since its been heavily modified from the orginal implementation. nomenu = true; baseAbility = Af.parseMagicLine(baseAbilityStrSplit[0], this->GetId(), NULL, source); baseAbility->target = target; @@ -2380,7 +2381,7 @@ int AAEPIC::resolve() MTGCardInstance * _target = (MTGCardInstance *)target; if(FField) _target->controller()->forcefield = 1; - else + else _target->controller()->epic = 1; return 1; } @@ -2732,7 +2733,7 @@ AAFrozen::AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCa ActivatedAbility(observer, id, card, _cost, 0) { target = _target; - freeze = tap; + freeze = tap; } int AAFrozen::resolve() @@ -2742,10 +2743,10 @@ int AAFrozen::resolve() { while (_target->next) _target = _target->next; //This is for cards such as rampant growth - if (freeze) - { - _target->tap();//easier to manage for cards that allow you to tap and also freeze. - } + if (freeze) + { + _target->tap();//easier to manage for cards that allow you to tap and also freeze. + } _target->frozen += 1; } return 1; @@ -3886,13 +3887,13 @@ int AAMover::resolve() delete spell; return 1; } - if (destZone == game->players[i]->game->graveyard && fromZone == game->players[i]->game->hand) - { - //movers that take a card from hand and place them in graveyard are always discards. we send an event for it here. + if (destZone == game->players[i]->game->graveyard && fromZone == game->players[i]->game->hand) + { + //movers that take a card from hand and place them in graveyard are always discards. we send an event for it here. - WEvent * e = NEW WEventCardDiscard(_target); - game->receiveEvent(e); - } + WEvent * e = NEW WEventCardDiscard(_target); + game->receiveEvent(e); + } } @@ -4300,36 +4301,36 @@ AARemoveMana::~AARemoveMana() //Bestow ABestow::ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) : - ActivatedAbility(observer, id, card, _cost, 0) + ActivatedAbility(observer, id, card, _cost, 0) { - target = _target; - aType = MTGAbility::TAPPER; - _card = card; + target = _target; + aType = MTGAbility::TAPPER; + _card = card; } int ABestow::resolve() { - if (target) - { - if (_card->hasType("creature")) - { - _card->removeType("creature"); - _card->addType("aura"); - } - _card->target = (MTGCardInstance*)target; - _card->isBestowed = true; - } - return 1; + if (target) + { + if (_card->hasType("creature")) + { + _card->removeType("creature"); + _card->addType("aura"); + } + _card->target = (MTGCardInstance*)target; + _card->isBestowed = true; + } + return 1; } const string ABestow::getMenuText() { - return "Bestow"; + return "Bestow"; } ABestow * ABestow::clone() const { - return NEW ABestow(*this); + return NEW ABestow(*this); } //Tapper @@ -4414,48 +4415,48 @@ AAWhatsMax * AAWhatsMax::clone() const } //set X value AAWhatsX::AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, int value, MTGAbility * _costRule) : - ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) + ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) { } int AAWhatsX::resolve() { - if (source) - { - source->setX = value; - - } - costRule->reactToClick(source); - return 1; + if (source) + { + source->setX = value; + + } + costRule->reactToClick(source); + return 1; } AAWhatsX * AAWhatsX::clone() const { - return NEW AAWhatsX(*this); + return NEW AAWhatsX(*this); } //count objects on field before doing an effect AACountObject::AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, ManaCost * _cost, string value) : - ActivatedAbility(observer, id, card, _cost, 0), value(value) + ActivatedAbility(observer, id, card, _cost, 0), value(value) { } int AACountObject::resolve() { - if (source) - { - int amount = 0; - WParsedInt * use = NEW WParsedInt(value, NULL, source); - amount = use->getValue(); - source->CountedObjects = amount; - SAFE_DELETE(use); - } - return 1; + if (source) + { + int amount = 0; + WParsedInt * use = NEW WParsedInt(value, NULL, source); + amount = use->getValue(); + source->CountedObjects = amount; + SAFE_DELETE(use); + } + return 1; } AACountObject * AACountObject::clone() const { - return NEW AACountObject(*this); + return NEW AACountObject(*this); } // Win Game @@ -4749,16 +4750,16 @@ void MenuAbility::Update(float dt) { if(game->mExtraPayment->isPaymentSet() && game->mExtraPayment->canPay() ) { - if (game->mExtraPayment->costs.size()) - { - if (game->mExtraPayment->costs[0]->costToPay) - { - ManaCost * diff = game->mExtraPayment->costs[0]->costToPay; - ManaCost * c = source->controller()->getManaPool()->Diff(diff); - source->X = c->getCost(Constants::NB_Colors); - delete c; - } - } + if (game->mExtraPayment->costs.size()) + { + if (game->mExtraPayment->costs[0]->costToPay) + { + ManaCost * diff = game->mExtraPayment->costs[0]->costToPay; + ManaCost * c = source->controller()->getManaPool()->Diff(diff); + source->X = c->getCost(Constants::NB_Colors); + delete c; + } + } game->mExtraPayment->doPay(); game->mLayers->actionLayer()->reactToClick(game->mExtraPayment->action, game->mExtraPayment->source); @@ -5012,7 +5013,7 @@ MultiAbility * MultiAbility::clone() const a->abilities.clear(); for (size_t i = 0; i < abilities.size(); ++i) { - if(abilities[i]) + if(abilities[i]) a->abilities.push_back(abilities[i]->clone()); } return a; @@ -6133,6 +6134,7 @@ int AProduceMana::produce() { AManaProducer *amp = NEW AManaProducer(game, game->mLayers->actionLayer()->getMaxId(), source, source->controller(), ManaCost::parseManaCost(ManaDescription,NULL,source), NULL, 0,"",false); amp->resolve(); + SAFE_DELETE(amp);//once you call resolve() on a ability, you can safely delete it. } return 1; } @@ -6611,108 +6613,108 @@ AShackleWrapper::~AShackleWrapper() //grant AGrant::AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : - MTGAbility(observer, _id, card) + MTGAbility(observer, _id, card) { - Granted = _Grant; - target = _target; - Blessed = NULL; - resolved = false; - toGrant = NULL; + Granted = _Grant; + target = _target; + Blessed = NULL; + resolved = false; + toGrant = NULL; } void AGrant::Update(float dt) { - if (resolved == false) - { - resolved = true; - resolveGrant(); - } + if (resolved == false) + { + resolved = true; + resolveGrant(); + } - if (!source->isTapped() || !source->isInPlay(game)) - { - if (Blessed == NULL || !Blessed->isInPlay(game)) - MTGAbility::Update(dt); - MTGCardInstance * _target = Blessed; - removeGranted(_target); - } - else - resolveGrant(); - MTGAbility::Update(dt); + if (!source->isTapped() || !source->isInPlay(game)) + { + if (Blessed == NULL || !Blessed->isInPlay(game)) + MTGAbility::Update(dt); + MTGCardInstance * _target = Blessed; + removeGranted(_target); + } + else + resolveGrant(); + MTGAbility::Update(dt); } void AGrant::resolveGrant() { - if (toGrant) return; - MTGCardInstance * _target = (MTGCardInstance *)target; - if (_target) - { - toGrant = Granted->clone(); - toGrant->target = _target; - toGrant->addToGame(); - Blessed = _target; - } + if (toGrant) return; + MTGCardInstance * _target = (MTGCardInstance *)target; + if (_target) + { + toGrant = Granted->clone(); + toGrant->target = _target; + toGrant->addToGame(); + Blessed = _target; + } } void AGrant::removeGranted(MTGCardInstance* _target) { - if (!toGrant) return; - game->removeObserver(toGrant); - game->removeObserver(this); - Blessed = NULL; - return; + if (!toGrant) return; + game->removeObserver(toGrant); + game->removeObserver(this); + Blessed = NULL; + return; } int AGrant::resolve() { - return 0; + return 0; } const string AGrant::getMenuText() { - return Granted->getMenuText(); + return Granted->getMenuText(); } AGrant * AGrant::clone() const { - AGrant * a = NEW AGrant(*this); - a->forceDestroy = -1; - a->Granted = Granted->clone(); - return a; + AGrant * a = NEW AGrant(*this); + a->forceDestroy = -1; + a->Granted = Granted->clone(); + return a; }; AGrant::~AGrant() { - SAFE_DELETE(Granted); + SAFE_DELETE(Granted); } AGrantWrapper::AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : - InstantAbility(observer, _id, source, _target), Granted(_Grant) + InstantAbility(observer, _id, source, _target), Granted(_Grant) { - ability = NEW AGrant(observer, _id, card, _target,_Grant); + ability = NEW AGrant(observer, _id, card, _target,_Grant); } int AGrantWrapper::resolve() { - AGrant * a = ability->clone(); - a->target = target; - a->addToGame(); - return 1; + AGrant * a = ability->clone(); + a->target = target; + a->addToGame(); + return 1; } const string AGrantWrapper::getMenuText() { - return "Grant"; + return "Grant"; } AGrantWrapper * AGrantWrapper::clone() const { - AGrantWrapper * a = NEW AGrantWrapper(*this); - a->ability = this->ability->clone(); - a->oneShot = 1; - return a; + AGrantWrapper * a = NEW AGrantWrapper(*this); + a->ability = this->ability->clone(); + a->oneShot = 1; + return a; } AGrantWrapper::~AGrantWrapper() { - SAFE_DELETE(ability); + SAFE_DELETE(ability); } //a blink @@ -7322,8 +7324,8 @@ int AACastCard::resolveSpell() else copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack,noEvent); copy->changeController(source->controller(),true); - if(asNormalMadness) - copy->MadnessPlay = true; + if(asNormalMadness) + copy->MadnessPlay = true; } else { diff --git a/projects/mtg/src/Damage.cpp b/projects/mtg/src/Damage.cpp index 9177b442d..b5a94633c 100644 --- a/projects/mtg/src/Damage.cpp +++ b/projects/mtg/src/Damage.cpp @@ -251,7 +251,7 @@ int Damage::resolve() target->lifeLostThisTurn += damage; if ( typeOfDamage == 1 && target == source->controller()->opponent() )//add vector prowledtypes. { - vector values = MTGAllCards::getCreatureValuesById(); + vector values = MTGAllCards::getCreatureValuesById();//getting a weird crash here. rarely. for (size_t i = 0; i < values.size(); ++i) { if ( source->hasSubtype( values[i] ) && find(source->controller()->prowledTypes.begin(), source->controller()->prowledTypes.end(), values[i])==source->controller()->prowledTypes.end() ) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 693b232c2..2464aa980 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1057,208 +1057,115 @@ void GameObserver::Affinity() if (!card) continue; - /////////////////////////// - //reset extracost shadows// - /////////////////////////// - card->isExtraCostTarget = false; - if (mExtraPayment != NULL) - { - for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) - { - - if (mExtraPayment->costs[ec]->tc) - { - vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - Targetable * cardMasked = *it; - dynamic_cast(cardMasked)->isExtraCostTarget = true; - } - - } - } - } - //////////////////////////// - bool NewAffinityFound = false; - for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) - { - if (!card->cardsAbilities[na]) - break; - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if (newAff) - { - NewAffinityFound = true; - } - } - bool DoReduceIncrease = false; - if (card->has(Constants::AFFINITYARTIFACTS) || - card->has(Constants::AFFINITYFOREST) || - card->has(Constants::AFFINITYGREENCREATURES) || - card->has(Constants::AFFINITYISLAND) || - card->has(Constants::AFFINITYMOUNTAIN) || - card->has(Constants::AFFINITYPLAINS) || - card->has(Constants::AFFINITYSWAMP) || - card->has(Constants::TRINISPHERE) || - card->getIncreasedManaCost()->getConvertedCost() || - card->getReducedManaCost()->getConvertedCost() || - NewAffinityFound) - DoReduceIncrease = true; - if (!DoReduceIncrease) - continue; - //above we check if there are even any cards that effect cards manacost - //if there are none, leave this function. manacost->copy( is a very expensive funtion - //1mb a sec to run at all time even when no known reducers or increasers are in play. - //memory snapshot shots pointed to this as such a heavy load that games with many cards inplay - //would slow to a crawl. - //only do any of the following if a card with the stated ability is in your hand. - int color = 0; - string type = ""; - - ManaCost * original = NEW ManaCost(); - original->copy(card->model->data->getManaCost()); - if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost()) - {//start1 - if(card->getIncreasedManaCost()->getConvertedCost()) - original->add(card->getIncreasedManaCost()); - if(card->getReducedManaCost()->getConvertedCost()) - original->remove(card->getReducedManaCost()); - if(card->getManaCost()) - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) + /////////////////////////// + //reset extracost shadows// + /////////////////////////// + card->isExtraCostTarget = false; + if (mExtraPayment != NULL) + { + for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + + if (mExtraPayment->costs[ec]->tc) { - card->getManaCost()->extraCosts->costs[i]->setSource(card); + vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + Targetable * cardMasked = *it; + dynamic_cast(cardMasked)->isExtraCostTarget = true; + } + } } - }//end1 - int reducem = 0; - bool resetCost = false; - for(unsigned int na = 0; na < card->cardsAbilities.size();na++) - {//start2 - if (!card->cardsAbilities[na]) - break; + } + //////////////////////////// + bool NewAffinityFound = false; + for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) + { + if (!card->cardsAbilities[na]) + break; ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if(newAff) + if (newAff) { - if(!resetCost) - { - resetCost = true; - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) - { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) - { - card->getManaCost()->extraCosts->costs[i]->setSource(card); - } - } - } - TargetChooserFactory tf(this); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); + NewAffinityFound = true; + } + } + bool DoReduceIncrease = false; + if (card->has(Constants::AFFINITYARTIFACTS) || + card->has(Constants::AFFINITYFOREST) || + card->has(Constants::AFFINITYGREENCREATURES) || + card->has(Constants::AFFINITYISLAND) || + card->has(Constants::AFFINITYMOUNTAIN) || + card->has(Constants::AFFINITYPLAINS) || + card->has(Constants::AFFINITYSWAMP) || + card->has(Constants::TRINISPHERE) || + card->getIncreasedManaCost()->getConvertedCost() || + card->getReducedManaCost()->getConvertedCost() || + NewAffinityFound) + DoReduceIncrease = true; + if (!DoReduceIncrease) + continue; + //above we check if there are even any cards that effect cards manacost + //if there are none, leave this function. manacost->copy( is a very expensive funtion + //1mb a sec to run at all time even when no known reducers or increasers are in play. + //memory snapshot shots pointed to this as such a heavy load that games with many cards inplay + //would slow to a crawl. + //only do any of the following if a card with the stated ability is in your hand. + //kicker is an addon to normal cost, suspend is not casting. add cost as needed EXACTLY as seen below. + card->getManaCost()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost())); + card->getManaCost()->copy(newCost); + SAFE_DELETE(newCost); + if (card->getManaCost()->getAlternative()) + { + card->getManaCost()->getAlternative()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative())); + card->getManaCost()->getAlternative()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getBestow()) + { + card->getManaCost()->getBestow()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow())); + card->getManaCost()->getBestow()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getRetrace()) + { + card->getManaCost()->getRetrace()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace())); + card->getManaCost()->getRetrace()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getBuyback()) + { + card->getManaCost()->getBuyback()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback())); + card->getManaCost()->getBuyback()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getFlashback()) + { + card->getManaCost()->getFlashback()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback())); + card->getManaCost()->getFlashback()->copy(newCost); + SAFE_DELETE(newCost); + } + if (card->getManaCost()->getMorph()) + { + card->getManaCost()->getMorph()->resetCosts(); + ManaCost * newCost = NEW ManaCost(); + newCost->copy(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph())); + card->getManaCost()->getMorph()->copy(newCost); + SAFE_DELETE(newCost); + } - for (int w = 0; w < 2; ++w) - { - Player *p = this->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) - { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - { - reducem += z->countByCanTarget(tcn); - } - } - } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for(int j = 0; j < reducem; j++) - card->getManaCost()->remove(removingCost); - SAFE_DELETE(removingCost); - } - }//end2 - if(card->has(Constants::AFFINITYARTIFACTS)|| - card->has(Constants::AFFINITYFOREST)|| - card->has(Constants::AFFINITYGREENCREATURES)|| - card->has(Constants::AFFINITYISLAND)|| - card->has(Constants::AFFINITYMOUNTAIN)|| - card->has(Constants::AFFINITYPLAINS)|| - card->has(Constants::AFFINITYSWAMP)) - {//start3 - if (card->has(Constants::AFFINITYARTIFACTS)) - { - type = "artifact"; - } - else if (card->has(Constants::AFFINITYSWAMP)) - { - type = "swamp"; - } - else if (card->has(Constants::AFFINITYMOUNTAIN)) - { - type = "mountain"; - } - else if (card->has(Constants::AFFINITYPLAINS)) - { - type = "plains"; - } - else if (card->has(Constants::AFFINITYISLAND)) - { - type = "island"; - } - else if (card->has(Constants::AFFINITYFOREST)) - { - type = "forest"; - } - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - card->getManaCost()->copy(original); - if(card->getManaCost()->extraCosts) - { - for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) - { - card->getManaCost()->extraCosts->costs[i]->setSource(card); - } - } - int reduce = 0; - if(card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(this); - TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); - reduce = card->controller()->game->battlefield->countByCanTarget(tc); - SAFE_DELETE(tc); - } - else - { - reduce = card->controller()->game->battlefield->countByType(type); - } - for(int i = 0; i < reduce;i++) - { - if(card->getManaCost()->getCost(color) > 0) - card->getManaCost()->remove(color,1); - } - }//end3 - //trinisphere... now how to implement kicker recomputation - - if(card->has(Constants::TRINISPHERE)) - { - for(int jj = card->getManaCost()->getConvertedCost(); jj < 3; jj++) - { - card->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1); - card->countTrini++; - } - } - else - { - if(card->countTrini) - { - card->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); - card->countTrini=0; - } - } - - SAFE_DELETE(original); }//end } } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index c8d800eec..3cea0730c 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -69,8 +69,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to cardistargetted = 0; cardistargetter = 0; myconvertedcost = getManaCost()->getConvertedCost(); - revealedLast = NULL; - MadnessPlay = false; + revealedLast = NULL; + MadnessPlay = false; } MTGCardInstance * MTGCardInstance::createSnapShot() @@ -153,14 +153,14 @@ int MTGCardInstance::init() data = this; X = 0; castX = 0; - setX = -1; + setX = -1; return 1; } void MTGCardInstance::initMTGCI() { X = 0; - setX = -1; + setX = -1; sample = ""; model = NULL; isToken = false; @@ -198,7 +198,7 @@ void MTGCardInstance::initMTGCI() wasDealtDamage = false; isDualWielding = false; suspended = false; - isBestowed = false; + isBestowed = false; castMethod = Constants::NOT_CAST; mPropertiesChangedSinceLastUpdate = false; stillNeeded = true; @@ -228,7 +228,7 @@ void MTGCardInstance::initMTGCI() imprintW = 0; currentimprintName = ""; imprintedNames.clear(); - CountedObjects = 0; + CountedObjects = 0; for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++) alternateCostPaid[i] = 0; @@ -782,8 +782,8 @@ int MTGCardInstance::getCurrentToughness() //check stack bool MTGCardInstance::StackIsEmptyandSorcerySpeed() { - Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. - Player * whoCurrent = getObserver()->currentPlayer; + Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. + Player * whoCurrent = getObserver()->currentPlayer; if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) && (getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) && @@ -961,121 +961,156 @@ JQuadPtr MTGCardInstance::getIcon() return WResourceManager::Instance()->RetrieveCard(this, CACHE_THUMB); } -ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * newCost, ManaCost * refCost, bool noTrinisphere) +ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cost, ManaCost * Data, bool noTrinisphere) { - if(!card) - return NULL; - - if(card->getIncreasedManaCost()->getConvertedCost()) - newCost->add(card->getIncreasedManaCost()); - if(card->getReducedManaCost()->getConvertedCost()) - newCost->remove(card->getReducedManaCost()); - if(refCost->extraCosts) - newCost->extraCosts = refCost->extraCosts; - //affinity - int color = 0; - string type = ""; - ManaCost * original = NEW ManaCost(); - original->copy(newCost); - - int reducem = 0; - bool resetCost = false; - for(unsigned int na = 0; na < card->cardsAbilities.size();na++) - {//start2 - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if(newAff) - { - if(!resetCost) - { - resetCost = true; - newCost->copy(original); - } - TargetChooserFactory tf(observer); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); + int color = 0; + string type = ""; + ManaCost * original = NEW ManaCost(); + original->copy(Data); + if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost()) + {//start1 + if (card->getIncreasedManaCost()->getConvertedCost()) + original->add(card->getIncreasedManaCost()); + if (card->getReducedManaCost()->getConvertedCost()) + original->remove(card->getReducedManaCost()); - for (int w = 0; w < 2; ++w) + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + }//end1 + int reducem = 0; + bool resetCost = false; + for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) + {//start2 + if (!card->cardsAbilities[na]) + break; + ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); + if (newAff) + { + if (!resetCost) + { + resetCost = true; + Cost->copy(original); + if (Cost->extraCosts) { - Player *p = observer->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - reducem += z->countByCanTarget(tcn); + Cost->extraCosts->costs[i]->setSource(card); } } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for(int j = 0; j < reducem; j++) - newCost->remove(removingCost); - SAFE_DELETE(removingCost); } - }//end2 - if(card->has(Constants::AFFINITYARTIFACTS)|| - card->has(Constants::AFFINITYFOREST)|| - card->has(Constants::AFFINITYGREENCREATURES)|| - card->has(Constants::AFFINITYISLAND)|| - card->has(Constants::AFFINITYMOUNTAIN)|| - card->has(Constants::AFFINITYPLAINS)|| - card->has(Constants::AFFINITYSWAMP)) - {//start3 - if (card->has(Constants::AFFINITYARTIFACTS)) - type = "artifact"; - else if (card->has(Constants::AFFINITYSWAMP)) - type = "swamp"; - else if (card->has(Constants::AFFINITYMOUNTAIN)) - type = "mountain"; - else if (card->has(Constants::AFFINITYPLAINS)) - type = "plains"; - else if (card->has(Constants::AFFINITYISLAND)) - type = "island"; - else if (card->has(Constants::AFFINITYFOREST)) - type = "forest"; - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - newCost->copy(original); - int reduce = 0; - if(card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(observer); - TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); - reduce = card->controller()->game->battlefield->countByCanTarget(tc); - SAFE_DELETE(tc); - } - else - reduce = card->controller()->game->battlefield->countByType(type); - for(int i = 0; i < reduce;i++) - if(newCost->getCost(color) > 0) - newCost->remove(color,1); - }//end3 - - if(!noTrinisphere) - { - //trinisphere... now how to implement kicker recomputation - if(card->has(Constants::TRINISPHERE)) - { - for(int jj = newCost->getConvertedCost(); jj < 3; jj++) + TargetChooserFactory tf(getObserver()); + TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL); + + for (int w = 0; w < 2; ++w) { - newCost->add(Constants::MTG_COLOR_ARTIFACT, 1); - card->countTrini++; + Player *p = getObserver()->players[w]; + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) + { + MTGGameZone * z = zones[k]; + if (tcn->targetsZone(z)) + { + reducem += z->countByCanTarget(tcn); + } + } } + SAFE_DELETE(tcn); + ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); + for (int j = 0; j < reducem; j++) + original->remove(removingCost); + SAFE_DELETE(removingCost); + } + }//end2 + if (card->has(Constants::AFFINITYARTIFACTS) || + card->has(Constants::AFFINITYFOREST) || + card->has(Constants::AFFINITYGREENCREATURES) || + card->has(Constants::AFFINITYISLAND) || + card->has(Constants::AFFINITYMOUNTAIN) || + card->has(Constants::AFFINITYPLAINS) || + card->has(Constants::AFFINITYSWAMP)) + {//start3 + if (card->has(Constants::AFFINITYARTIFACTS)) + { + type = "artifact"; + } + else if (card->has(Constants::AFFINITYSWAMP)) + { + type = "swamp"; + } + else if (card->has(Constants::AFFINITYMOUNTAIN)) + { + type = "mountain"; + } + else if (card->has(Constants::AFFINITYPLAINS)) + { + type = "plains"; + } + else if (card->has(Constants::AFFINITYISLAND)) + { + type = "island"; + } + else if (card->has(Constants::AFFINITYFOREST)) + { + type = "forest"; + } + else if (card->has(Constants::AFFINITYGREENCREATURES)) + { + color = 1; + type = "creature"; + } + + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + int reduce = 0; + if (card->has(Constants::AFFINITYGREENCREATURES)) + { + TargetChooserFactory tf(getObserver()); + TargetChooser * tc = tf.createTargetChooser("creature[green]", NULL); + reduce = card->controller()->game->battlefield->countByCanTarget(tc); + SAFE_DELETE(tc); } else { - if(card->countTrini) - { - newCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); - card->countTrini=0; - } + reduce = card->controller()->game->battlefield->countByType(type); + } + for (int i = 0; i < reduce; i++) + { + if (Cost->getCost(color) > 0) + Cost->remove(color, 1); + } + }//end3 + //trinisphere... now how to implement kicker recomputation + + if (card->has(Constants::TRINISPHERE)) + { + for (int jj = Cost->getConvertedCost(); jj < 3; jj++) + { + Cost->add(Constants::MTG_COLOR_ARTIFACT, 1); + card->countTrini++; + } + } + else + { + if (card->countTrini) + { + Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); + card->countTrini = 0; } } - SAFE_DELETE(original); - - return newCost; + return Cost; } MTGCardInstance * MTGCardInstance::getNextPartner() diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index d9f77b0e6..fbb74087c 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -49,6 +49,10 @@ PermanentAbility(observer, _id) Angel[i] = 0; dragonbonusgranted[i] = false; dragon[i] = 0; + eldrazibonusgranted[i] = false; + eldrazi[i] = 0; + werewolfbonusgranted[i] = false; + werewolf[i] = 0; } } @@ -171,6 +175,10 @@ int MTGEventBonus::receiveEvent(WEvent * event) Angel[currentPlayer->getId()]++; if(e->card->hasType("dragon")||e->card->hasType("wurm")||e->card->hasType("drake")||e->card->hasType("snake")||e->card->hasType("hydra")) dragon[currentPlayer->getId()]++; + if (e->card->hasType("eldrazi")) + eldrazi[currentPlayer->getId()]++; + if (e->card->hasType("werewolf") || e->card->hasType("wolf")) + werewolf[currentPlayer->getId()]++; } if(toys[currentPlayer->getId()] > 30 && !toybonusgranted[currentPlayer->getId()]) { @@ -228,6 +236,16 @@ int MTGEventBonus::receiveEvent(WEvent * event) grantAward("Teeth And Scales!",300); dragonbonusgranted[currentPlayer->getId()] = true; } + if (eldrazi[currentPlayer->getId()] > 30 && !eldrazibonusgranted[currentPlayer->getId()]) + { + grantAward("Colorblind!", 300); + eldrazibonusgranted[currentPlayer->getId()] = true; + } + if (werewolf[currentPlayer->getId()] > 30 && !werewolfbonusgranted[currentPlayer->getId()]) + { + grantAward("Full Moon!", 300); + werewolfbonusgranted[currentPlayer->getId()] = true; + } } } //bonus for dealing 100+ damage from a single source @@ -365,65 +383,65 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) return 0; Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); - ManaCost * playerMana = player->getManaPool(); - ///////announce X cost/////// - if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) - { - vectorselection; - int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; - //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would - //give me the correct amount sorry. - for (int i = 0; i < options; ++i) - { + ManaCost * playerMana = player->getManaPool(); + ///////announce X cost/////// + if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { - MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); - MTGAbility * setCardX = setX->clone(); - setCardX->oneShot = true; - selection.push_back(setCardX); - SAFE_DELETE(setX); - } - if (selection.size()) - { - MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); - game->mLayers->actionLayer()->currentActionCard = card; - a1->resolve(); - } - return 0; - } - /////////////////////////////////////////////////////////////////////////////////////// - //////X is set, below we set sunburst for X if needed and cast or reset the card.////// - //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// - //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// - //////and the value of X isn’t defined by the text of that spell or ability, the ////// - //////controller of that spell or ability chooses and announces the value of X as////// - //////part of casting the spell or activating the ability. ////// - //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// - //////its mana cost or in any alternative cost or additional cost it has equals ////// - //////the announced value.While an activated ability is on the stack, any X in ////// - //////its activation cost equals the announced value. ////// - /////////////////////////////////////////////////////////////////////////////////////// - if (card->setX > -1) - { - ManaCost * Xcost = NEW ManaCost(); - Xcost->copy(cost); - Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); - Xcost->remove(7, 1); - if (playerMana->canAfford(Xcost)) - { - cost->copy(Xcost); - SAFE_DELETE(Xcost); - } - else - { - if (card->setX > -1) - card->setX = -1; - SAFE_DELETE(Xcost); - return 0; - } - } - ////////////////////////////////////////// - ////cards without X contenue from here//// - ////////////////////////////////////////// + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(cost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1); + if (playerMana->canAfford(Xcost)) + { + cost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } + ////////////////////////////////////////// + ////cards without X contenue from here//// + ////////////////////////////////////////// //this handles extra cost payments at the moment a card is played. if (cost->isExtraPaymentSet()) { @@ -438,7 +456,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) game->mExtraPayment = cost->extraCosts; return 0; } - + ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); int payResult = player->getManaPool()->pay(card->getManaCost()); if (card->getManaCost()->getKicker() && (OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number || card->controller()->isAI())) @@ -552,9 +570,9 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *) ManaCost * withKickerCost= NEW ManaCost(card->getManaCost()); withKickerCost->add(card->getManaCost()->getKicker()); //cost reduction/recalculation must be here or outside somehow... - //no recalculations beyound this point, reactToClick is the function that - //happens only with the assumption that you could actually pay for it, any calculations after will - //have negitive effects. this function is basically "can i play this card?" + //no recalculations beyound this point, reactToClick is the function that + //happens only with the assumption that you could actually pay for it, any calculations after will + //have negitive effects. this function is basically "can i play this card?" #ifdef WIN32 withKickerCost->Dump(); #endif @@ -691,7 +709,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * return 0;//overload has its own rule if(!card->getManaCost()->getAlternative()) return 0; - ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative()); + ManaCost * alternateCost = card->getManaCost()->getAlternative(); if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) { @@ -755,7 +773,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) if ( !isReactingToClick(card)) return 0; - ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative()); + ManaCost * alternateCost = card->getManaCost()->getAlternative(); card->paymenttype = MTGAbility::ALTERNATIVE_COST; if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) @@ -769,61 +787,61 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter Player * player = game->currentlyActing(); ManaPool * playerMana = player->getManaPool(); - ///////announce X cost/////// - if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) - { - vectorselection; - int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; - //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would - //give me the correct amount sorry. - for (int i = 0; i < options; ++i) - { + ///////announce X cost/////// + if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { - MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); - MTGAbility * setCardX = setX->clone(); - setCardX->oneShot = true; - selection.push_back(setCardX); - SAFE_DELETE(setX); - } - if (selection.size()) - { - MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); - game->mLayers->actionLayer()->currentActionCard = card; - a1->resolve(); - } - return 0; - } - /////////////////////////////////////////////////////////////////////////////////////// - //////X is set, below we set sunburst for X if needed and cast or reset the card.////// - //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// - //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// - //////and the value of X isn’t defined by the text of that spell or ability, the ////// - //////controller of that spell or ability chooses and announces the value of X as////// - //////part of casting the spell or activating the ability. ////// - //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// - //////its mana cost or in any alternative cost or additional cost it has equals ////// - //////the announced value.While an activated ability is on the stack, any X in ////// - //////its activation cost equals the announced value. ////// - /////////////////////////////////////////////////////////////////////////////////////// - if (card->setX > -1) - { - ManaCost * Xcost = NEW ManaCost(); - Xcost->copy(alternateCost); - Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); - Xcost->remove(7, 1);//remove the X - if (playerMana->canAfford(Xcost)) - { - alternateCost->copy(Xcost); - SAFE_DELETE(Xcost); - } - else - { - if (card->setX > -1) - card->setX = -1; - SAFE_DELETE(Xcost); - return 0; - } - } + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(alternateCost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1);//remove the X + if (playerMana->canAfford(Xcost)) + { + alternateCost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } //this handles extra cost payments at the moment a card is played. @@ -880,7 +898,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter { ManaCost * c = spellCost->Diff(alternateCost); - copy->X = card->setX; + copy->X = card->setX; copy->castX = copy->X; delete c; } @@ -924,7 +942,7 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getBuyback()) return 0; - ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback()); + ManaCost * buybackCost = card->getManaCost()->getBuyback(); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -938,7 +956,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback()); + ManaCost * buybackCost = card->getManaCost()->getBuyback(); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -978,7 +996,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getFlashback()) return 0; - ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback()); + ManaCost * flashbackCost = card->getManaCost()->getFlashback(); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -989,7 +1007,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGFlashBackRule::reactToClick(MTGCardInstance * card) { - ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback()); + ManaCost * flashbackCost = card->getManaCost()->getFlashback(); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1031,17 +1049,17 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) Player * player = game->currentlyActing(); if(!card->getManaCost()->getRetrace()) return 0; - ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace()); + if (!player->game->graveyard->hasCard(card)) + { + return 0; + } + auto retraceCost = card->getManaCost()->getRetrace(); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { retraceCost->extraCosts->costs[i]->setSource(card); - } - - if (!player->game->graveyard->hasCard(card)) - return 0; - - return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost ); + } + return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost); } @@ -1050,7 +1068,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace()); + ManaCost * retraceCost = card->getManaCost()->getRetrace(); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1227,7 +1245,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY) return 0; ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph()); + ManaCost * morph = card->getManaCost()->getMorph(); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1256,7 +1274,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card) Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph()); + ManaCost * morph = card->getManaCost()->getMorph(); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1346,23 +1364,26 @@ MTGAlternativeCostRule(observer, _id) int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if(!card->has(Constants::PAYZERO)) + if (!card->has(Constants::PAYZERO)) return 0; Player * player = game->currentlyActing(); - ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL)); - ManaCost * newCost = card->computeNewCost(card,cost,cost); - if(newCost->extraCosts) - for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) + if (card->isLand() || (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))) + { + //only allowed to pay zero for cards in library??? above is "if you dont have it in hand, grave, or exile" + return 0; + } + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + { + return 0; + } + ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + ManaCost * newCost = card->computeNewCost(card, cost, cost); + SAFE_DELETE(cost); + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) { newCost->extraCosts->costs[i]->setSource(card); } - - if(card->isLand()) - return 0; - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) - return 0; - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - return 0; if(card->has(Constants::CANPLAYFROMGRAVEYARD)) CustomName = "Zero Cast From Graveyard"; else if(card->has(Constants::CANPLAYFROMEXILE)) @@ -1412,22 +1433,26 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { if (!card->has(Constants::OVERLOAD)) return 0; - Player * player = game->currentlyActing(); - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); - ManaCost * newCost = card->computeNewCost(card,cost,cost); + if (card->isLand()) + { + return 0; + } + Player * player = card->controller(); + if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) + { + return 0; + } + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + { + return 0; + } + ManaCost * newCost = card->getManaCost()->getAlternative(); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { newCost->extraCosts->costs[i]->setSource(card); } - if (card->isLand()) - return 0; - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) - return 0; - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - return 0; - return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } @@ -1437,7 +1462,7 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card) return 0; ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); - ManaCost * newCost = card->computeNewCost(card,cost,cost); + ManaCost * newCost = card->getManaCost()->getAlternative(); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { @@ -1462,64 +1487,64 @@ MTGOverloadRule * MTGOverloadRule::clone() const /////////////////////////////////////////////////////////////////////////////////////////////////// //bestow MTGBestowRule::MTGBestowRule(GameObserver* observer, int _id) : - MTGAlternativeCostRule(observer, _id) + MTGAlternativeCostRule(observer, _id) { - aType = MTGAbility::BESTOW_COST; + aType = MTGAbility::BESTOW_COST; } int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if (!card->model) - return 0; - //Player * player = game->currentlyActing(); - if (!card->model->data->getManaCost()->getBestow()) - return 0; - if (card->isInPlay(game)) - return 0; - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow()); - ManaCost * newCost = card->computeNewCost(card, cost, cost); - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } - SAFE_DELETE(cost); - if (card->isLand()) - return 0; - if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) - return 0; - return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); + if (!card->model) + return 0; + if (!card->model->data->getManaCost()->getBestow()) + return 0; + if (card->isInPlay(game)) + return 0; + if (card->isLand()) + { + return 0; + } + if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) + { + return 0; + } + ManaCost * newCost = card->getManaCost()->getBestow(); + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } + return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } int MTGBestowRule::reactToClick(MTGCardInstance * card) { - if (!isReactingToClick(card)) - return 0; - //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash - //TODO::::we need to get to the source of this leak and fix it. - ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow()); - ManaCost * newCost = card->computeNewCost(card, cost, cost); - - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } + if (!isReactingToClick(card)) + return 0; + //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash + //TODO::::we need to get to the source of this leak and fix it. + ManaCost * newCost = card->getManaCost()->getBestow(); + + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } - card->paymenttype = MTGAbility::BESTOW_COST; - card->spellTargetType = "creature|battlefield"; - return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false); + card->paymenttype = MTGAbility::BESTOW_COST; + card->spellTargetType = "creature|battlefield"; + return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false); } ostream& MTGBestowRule::toString(ostream& out) const { - out << "MTGBestowRule ::: ("; - return MTGAbility::toString(out) << ")"; + out << "MTGBestowRule ::: ("; + return MTGAbility::toString(out) << ")"; } MTGBestowRule * MTGBestowRule::clone() const { - return NEW MTGBestowRule(*this); + return NEW MTGBestowRule(*this); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1710,19 +1735,19 @@ int MTGAttackRule::receiveEvent(WEvent *e) for (int i = 0; i < z->nb_cards; i++) { MTGCardInstance * card = z->cards[i]; - if (card->isAttacker() && card->has(Constants::NOSOLO)) - { - TargetChooserFactory tf(game); - TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL); - int Check = card->controller()->game->battlefield->countByCanTarget(tc); - if (Check <2) - card->initAttackersDefensers(); - } - if (card->isAttacker() && card->has(Constants::DETHRONE)) - { - if (p->opponent()->life >= p->life) - card->counters->addCounter(1, 1); - } + if (card->isAttacker() && card->has(Constants::NOSOLO)) + { + TargetChooserFactory tf(game); + TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL); + int Check = card->controller()->game->battlefield->countByCanTarget(tc); + if (Check <2) + card->initAttackersDefensers(); + } + if (card->isAttacker() && card->has(Constants::DETHRONE)) + { + if (p->opponent()->life >= p->life) + card->counters->addCounter(1, 1); + } if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn. reactToClick(card); if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI()) @@ -2036,49 +2061,49 @@ PermanentAbility(observer, _id) int MTGBlockRule::receiveEvent(WEvent *e) { - if (dynamic_cast(e)) - {//do not refactor, these are keep seperate for readability. - Player * p = game->currentPlayer; + if (dynamic_cast(e)) + {//do not refactor, these are keep seperate for readability. + Player * p = game->currentPlayer; - vector Attacker; - MTGGameZone * k = p->game->inPlay; - for (int i = 0; i < k->nb_cards; i++) - { - MTGCardInstance * card = k->cards[i]; - if (card->isAttacker()) - { - Attacker.push_back(card); - } - } - //force cards that must block, to block whatever is first found. players have a chance to set thier own - //but if ignored we do it for them. - if (Attacker.size()) - { - MTGGameZone * tf = p->opponent()->game->inPlay; - for (size_t i = 0; i < tf->cards.size(); i++) - { - MTGCardInstance * card = tf->cards[i]; - if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock()) - {//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them - //unassigned as a block. - for (size_t i = 0; i < Attacker.size(); i++) - { - if (card->canBlock(Attacker[i]) && !card->defenser) - { - blocker = NEW AABlock(card->getObserver(), -1, card, NULL); - blocker->oneShot = true; - blocker->forceDestroy = 1; - blocker->canBeInterrupted = false; - blocker->target = Attacker[i]; - blocker->resolve(); - SAFE_DELETE(blocker); - } - } + vector Attacker; + MTGGameZone * k = p->game->inPlay; + for (int i = 0; i < k->nb_cards; i++) + { + MTGCardInstance * card = k->cards[i]; + if (card->isAttacker()) + { + Attacker.push_back(card); + } + } + //force cards that must block, to block whatever is first found. players have a chance to set thier own + //but if ignored we do it for them. + if (Attacker.size()) + { + MTGGameZone * tf = p->opponent()->game->inPlay; + for (size_t i = 0; i < tf->cards.size(); i++) + { + MTGCardInstance * card = tf->cards[i]; + if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock()) + {//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them + //unassigned as a block. + for (size_t i = 0; i < Attacker.size(); i++) + { + if (card->canBlock(Attacker[i]) && !card->defenser) + { + blocker = NEW AABlock(card->getObserver(), -1, card, NULL); + blocker->oneShot = true; + blocker->forceDestroy = 1; + blocker->canBeInterrupted = false; + blocker->target = Attacker[i]; + blocker->resolve(); + SAFE_DELETE(blocker); + } + } - } - } + } + } - } + } if (dynamic_cast(e)) { @@ -2098,23 +2123,23 @@ int MTGBlockRule::receiveEvent(WEvent *e) } } - //if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal. - MTGGameZone * z = p->game->inPlay; - for (int i = 0; i < z->nb_cards; i++) - { - MTGCardInstance * card = z->cards[i]; - if (card->has(Constants::MENACE) && card->blockers.size() < 2) - { - while (card->blockers.size()) - { - MTGCardInstance * blockingCard = card->blockers.front(); - blockingCard->toggleDefenser(NULL); - - } - } - } + //if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal. + MTGGameZone * z = p->game->inPlay; + for (int i = 0; i < z->nb_cards; i++) + { + MTGCardInstance * card = z->cards[i]; + if (card->has(Constants::MENACE) && card->blockers.size() < 2) + { + while (card->blockers.size()) + { + MTGCardInstance * blockingCard = card->blockers.front(); + blockingCard->toggleDefenser(NULL); + + } + } + } - } + } return 1; @@ -2877,6 +2902,7 @@ int MTGPersistRule::receiveEvent(WEvent * event) } AAMover *putinplay = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), copy, copy,"ownerbattlefield",code,NULL,undying,persist); putinplay->oneShot = true; + game->mLayers->actionLayer()->garbage.push_back(putinplay); putinplay->fireAbility(); return 1; } diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index de9991d65..cfb5a4caf 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -153,7 +153,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'e': - //Exile + //Exile manaCost->addExtraCost(NEW ExileTargetCost(tc)); break; case 'h': //bounce (move to Hand) @@ -179,12 +179,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'd': //DiscardRandom cost - if (value.find("delve") != string::npos) - { - if(!tc) - tc = tcf.createTargetChooser("*|mygraveyard", c); - manaCost->addExtraCost(NEW Delve(tc)); - } + if (value.find("delve") != string::npos) + { + if(!tc) + tc = tcf.createTargetChooser("*|mygraveyard", c); + manaCost->addExtraCost(NEW Delve(tc)); + } else if (value == "d") { manaCost->addExtraCost(NEW DiscardRandomCost(tc)); @@ -259,12 +259,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan break; case 'c': //Counters or cycle { - if (value.find("convoke") != string::npos) - { - if (!tc) - tc = tcf.createTargetChooser("creature|mybattlefield", c); - manaCost->addExtraCost(NEW Convoke(tc)); - } + if (value.find("convoke") != string::npos) + { + if (!tc) + tc = tcf.createTargetChooser("creature|mybattlefield", c); + manaCost->addExtraCost(NEW Convoke(tc)); + } else if(value == "chosencolor") { if(c) @@ -390,19 +390,21 @@ ManaCost::ManaCost(ManaCost * manaCost) cost[i] = manaCost->getCost(i); } hybrids = manaCost->hybrids; - - kicker = NEW ManaCost( manaCost->kicker ); - if(kicker) - kicker->isMulti = manaCost->isMulti; + kicker = NEW ManaCost(manaCost->kicker); + if (kicker) + kicker->isMulti = manaCost->isMulti; Retrace = NEW ManaCost( manaCost->Retrace ); BuyBack = NEW ManaCost( manaCost->BuyBack ); alternative = NEW ManaCost( manaCost->alternative ); FlashBack = NEW ManaCost( manaCost->FlashBack ); morph = NEW ManaCost( manaCost->morph ); suspend = NEW ManaCost( manaCost->suspend ); - Bestow = NEW ManaCost(manaCost->Bestow); - - extraCosts = manaCost->extraCosts ? manaCost->extraCosts->clone() : NULL; + Bestow = NEW ManaCost(manaCost->Bestow); + extraCosts = NULL; + if (manaCost->extraCosts) + { + extraCosts = manaCost->extraCosts->clone(); + } manaUsedToCast = NULL; xColor = manaCost->xColor; } @@ -429,9 +431,13 @@ ManaCost::ManaCost(const ManaCost& manaCost) FlashBack = NEW ManaCost( manaCost.FlashBack ); morph = NEW ManaCost( manaCost.morph ); suspend = NEW ManaCost( manaCost.suspend ); - Bestow = NEW ManaCost(manaCost.Bestow); + Bestow = NEW ManaCost(manaCost.Bestow); + extraCosts = NULL; + if (manaCost.extraCosts) + { + extraCosts = manaCost.extraCosts->clone(); + } - extraCosts = manaCost.extraCosts ? manaCost.extraCosts->clone() : NULL; manaUsedToCast = NULL; xColor = manaCost.xColor; } @@ -453,7 +459,7 @@ ManaCost & ManaCost::operator= (const ManaCost & manaCost) FlashBack = manaCost.FlashBack; morph = manaCost.morph; suspend = manaCost.suspend; - Bestow = manaCost.Bestow; + Bestow = manaCost.Bestow; manaUsedToCast = manaCost.manaUsedToCast; xColor = manaCost.xColor; } @@ -470,7 +476,7 @@ ManaCost::~ManaCost() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); SAFE_DELETE(manaUsedToCast); cost.erase(cost.begin() ,cost.end()); @@ -480,7 +486,6 @@ void ManaCost::x() { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return; } @@ -491,7 +496,6 @@ int ManaCost::hasX() { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return 0; } if (xColor > 0) @@ -504,7 +508,6 @@ void ManaCost::specificX(int color) { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return; } xColor = color; @@ -515,7 +518,6 @@ int ManaCost::hasSpecificX() { if (cost.size() <= (size_t)Constants::NB_Colors) { - DebugTrace("Seems ManaCost was not properly initialized"); return 0; } if(xColor > 0) @@ -556,7 +558,7 @@ void ManaCost::init() Retrace = NULL; morph = NULL; suspend = NULL; - Bestow = NULL; + Bestow = NULL; manaUsedToCast = NULL; isMulti = false; xColor = -1; @@ -581,7 +583,7 @@ void ManaCost::resetCosts() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); } void ManaCost::copy(ManaCost * _manaCost) @@ -599,6 +601,7 @@ void ManaCost::copy(ManaCost * _manaCost) hybrids = _manaCost->hybrids; SAFE_DELETE(extraCosts); + if (_manaCost->extraCosts) { extraCosts = _manaCost->extraCosts->clone(); @@ -647,12 +650,12 @@ void ManaCost::copy(ManaCost * _manaCost) suspend = NEW ManaCost(); suspend->copy(_manaCost->suspend); } - SAFE_DELETE(Bestow); - if (_manaCost->Bestow) - { - Bestow = NEW ManaCost(); - Bestow->copy(_manaCost->Bestow); - } + SAFE_DELETE(Bestow); + if (_manaCost->Bestow) + { + Bestow = NEW ManaCost(); + Bestow->copy(_manaCost->Bestow); + } xColor = _manaCost->xColor; } @@ -1117,7 +1120,7 @@ void ManaPool::Empty() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); SAFE_DELETE(manaUsedToCast); init(); WEvent * e = NEW WEventEmptyManaPool(this); @@ -1147,8 +1150,8 @@ int ManaPool::remove(int color, int value) int ManaPool::add(int color, int value, MTGCardInstance * source, bool extra) { - if (color == Constants::MTG_COLOR_ARTIFACT) - color = Constants::MTG_COLOR_WASTE; + if (color == Constants::MTG_COLOR_ARTIFACT) + color = Constants::MTG_COLOR_WASTE; int result = ManaCost::add(color, value); for (int i = 0; i < value; ++i) { @@ -1168,15 +1171,15 @@ int ManaPool::add(ManaCost * _cost, MTGCardInstance * source) { if (!_cost) return 0; - //while colorless is still exactly the same, there are now cards that require - //true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the - //new type. keeping the old type intact for payment methods {1}{c} .... - int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT); - if (replaceArtifact) - { - _cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact); - _cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact); - } + //while colorless is still exactly the same, there are now cards that require + //true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the + //new type. keeping the old type intact for payment methods {1}{c} .... + int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT); + if (replaceArtifact) + { + _cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact); + _cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact); + } int result = ManaCost::add(_cost); for (int i = 0; i < Constants::NB_Colors; i++) { From 2f4c00c602a7aeb076a32fa9bb813db3f199bfa5 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 6 Jul 2016 16:09:54 +0800 Subject: [PATCH 2/6] Sorted Primitives --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 80 +++++++++---------- .../bin/Res/sets/primitives/unsupported.txt | 27 ------- 2 files changed, 39 insertions(+), 68 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index f724167c0..eea5024a4 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1,6 +1,6 @@ #Primitives Pack for Wagic the Homebrew. #Please keep these card alphabetized, and try to have the "name=" line at the top of each card -#I sorted this programatically so the other comments are removed except for AUTO_DEFINE - kevlahnota 7-4-2016 +#I sorted this programatically so the other comments are removed except for AUTO_DEFINE - kevlahnota 7-6-2016 [card] name=Abandoned Outpost auto=tap @@ -14420,6 +14420,13 @@ mana={4} type=Artifact [/card] [card] +name=Bulwark +auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] name=Bump in the Night auto=life:-3 opponent flashback={5}{R} @@ -23720,6 +23727,18 @@ mana={2}{B} type=Instant [/card] [card] +name=Dark Deal +auto=count(type:*:myhand) +auto=all(*|myhand) reject +auto=draw:countedamountplus1plusend controller +auto=count(type:*:opponenthand) +auto=all(*|opponenthand) reject +auto=draw:countedamountplus1plusend opponent +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] +[card] name=Dark Depths auto=counter(0/0,10,Ice) auto={3}:counter(0/0,-1,Ice) all(this) @@ -23829,6 +23848,13 @@ power=1 toughness=1 [/card] [card] +name=Dark Suspicions +auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] name=Dark Temper target=creature auto=aslongas(*[black]|myBattlefield) destroy @@ -89005,6 +89031,18 @@ mana={1}{W}{U} type=Sorcery [/card] [card] +name=Roiling Horror +anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive +autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +suspend(0)={X}{b}{b}{b} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] name=Roiling Terrain target=land auto=destroy @@ -127555,46 +127593,6 @@ subtype=Orc Warrior power=7 toughness=2 [/card] -###### -######unsorted -[card] -name=Dark Suspicions -auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] -name=Bulwark -auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] -name=Roiling Horror -anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive -autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -suspend(0)={X}{b}{b}{b} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] -name=Dark Deal -auto=count(type:*:myhand) -auto=all(*|myhand) reject -auto=draw:countedamountplus1plusend controller -auto=count(type:*:opponenthand) -auto=all(*|opponenthand) reject -auto=draw:countedamountplus1plusend opponent -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 853855c96..8cb3ca733 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -1927,12 +1927,6 @@ mana={B} type=Sorcery [/card] [card] -name=Bulwark -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] name=Burn at the Stake text=As an additional cost to cast Burn at the Stake, tap any number of untapped creatures you control. -- Burn at the Stake deals damage to target creature or player equal to three times the number of creatures tapped this way. mana={2}{R}{R}{R} @@ -3698,12 +3692,6 @@ power=2 toughness=3 [/card] [card] -name=Dark Deal -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] -[card] name=Dark Impostor text={4}{B}{B}: Exile target creature and put a +1/+1 counter on Dark Impostor. -- Dark Impostor has all activated abilities of all creature cards exiled with it. mana={2}{B} @@ -3719,12 +3707,6 @@ mana={0} type=Artifact [/card] [card] -name=Dark Suspicions -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] name=Darkpact text=Remove Darkpact from your deck before playing if you're not playing for ante. -- You own target card in the ante. Exchange that card with the top card of your library. mana={B}{B}{B} @@ -14687,15 +14669,6 @@ power=3 toughness=2 [/card] [card] -name=Roiling Horror -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] name=Roiling Waters text=Return up to two target creatures your opponents control to their owners' hands. Target player draws two cards. mana={5}{U}{U} From cf71f84e49a71b562d9427b9a14d1485a22be222 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 7 Jul 2016 09:15:57 +0800 Subject: [PATCH 3/6] Revert "Sorted Primitives" This reverts commit 2f4c00c602a7aeb076a32fa9bb813db3f199bfa5. --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 80 ++++++++++--------- .../bin/Res/sets/primitives/unsupported.txt | 27 +++++++ 2 files changed, 68 insertions(+), 39 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index eea5024a4..f724167c0 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1,6 +1,6 @@ #Primitives Pack for Wagic the Homebrew. #Please keep these card alphabetized, and try to have the "name=" line at the top of each card -#I sorted this programatically so the other comments are removed except for AUTO_DEFINE - kevlahnota 7-6-2016 +#I sorted this programatically so the other comments are removed except for AUTO_DEFINE - kevlahnota 7-4-2016 [card] name=Abandoned Outpost auto=tap @@ -14420,13 +14420,6 @@ mana={4} type=Artifact [/card] [card] -name=Bulwark -auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] name=Bump in the Night auto=life:-3 opponent flashback={5}{R} @@ -23727,18 +23720,6 @@ mana={2}{B} type=Instant [/card] [card] -name=Dark Deal -auto=count(type:*:myhand) -auto=all(*|myhand) reject -auto=draw:countedamountplus1plusend controller -auto=count(type:*:opponenthand) -auto=all(*|opponenthand) reject -auto=draw:countedamountplus1plusend opponent -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] -[card] name=Dark Depths auto=counter(0/0,10,Ice) auto={3}:counter(0/0,-1,Ice) all(this) @@ -23848,13 +23829,6 @@ power=1 toughness=1 [/card] [card] -name=Dark Suspicions -auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] name=Dark Temper target=creature auto=aslongas(*[black]|myBattlefield) destroy @@ -89031,18 +89005,6 @@ mana={1}{W}{U} type=Sorcery [/card] [card] -name=Roiling Horror -anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive -autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -suspend(0)={X}{b}{b}{b} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] name=Roiling Terrain target=land auto=destroy @@ -127593,6 +127555,46 @@ subtype=Orc Warrior power=7 toughness=2 [/card] +###### +######unsorted +[card] +name=Dark Suspicions +auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] +name=Bulwark +auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] +name=Roiling Horror +anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive +autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +suspend(0)={X}{b}{b}{b} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] +name=Dark Deal +auto=count(type:*:myhand) +auto=all(*|myhand) reject +auto=draw:countedamountplus1plusend controller +auto=count(type:*:opponenthand) +auto=all(*|opponenthand) reject +auto=draw:countedamountplus1plusend opponent +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 8cb3ca733..853855c96 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -1927,6 +1927,12 @@ mana={B} type=Sorcery [/card] [card] +name=Bulwark +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] name=Burn at the Stake text=As an additional cost to cast Burn at the Stake, tap any number of untapped creatures you control. -- Burn at the Stake deals damage to target creature or player equal to three times the number of creatures tapped this way. mana={2}{R}{R}{R} @@ -3692,6 +3698,12 @@ power=2 toughness=3 [/card] [card] +name=Dark Deal +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] +[card] name=Dark Impostor text={4}{B}{B}: Exile target creature and put a +1/+1 counter on Dark Impostor. -- Dark Impostor has all activated abilities of all creature cards exiled with it. mana={2}{B} @@ -3707,6 +3719,12 @@ mana={0} type=Artifact [/card] [card] +name=Dark Suspicions +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] name=Darkpact text=Remove Darkpact from your deck before playing if you're not playing for ante. -- You own target card in the ante. Exchange that card with the top card of your library. mana={B}{B}{B} @@ -14669,6 +14687,15 @@ power=3 toughness=2 [/card] [card] +name=Roiling Horror +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] name=Roiling Waters text=Return up to two target creatures your opponents control to their owners' hands. Target player draws two cards. mana={5}{U}{U} From e39dee6e1d64c471cf79a6f370fdb8588cebccc3 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 7 Jul 2016 09:16:03 +0800 Subject: [PATCH 4/6] Revert "Zeth Fixes" This reverts commit 78d3828f1e584ec252710d539bcf297a499cb771. --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 62 +- projects/mtg/include/AllAbilities.h | 506 +++--- projects/mtg/include/MTGRules.h | 4 - projects/mtg/src/AllAbilities.cpp | 1486 +++++++++--------- projects/mtg/src/Damage.cpp | 2 +- projects/mtg/src/GameObserver.cpp | 291 ++-- projects/mtg/src/MTGCardInstance.cpp | 245 ++- projects/mtg/src/MTGRules.cpp | 556 ++++--- projects/mtg/src/ManaCost.cpp | 99 +- 9 files changed, 1611 insertions(+), 1640 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index f724167c0..5a8969ebb 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1043,7 +1043,7 @@ type=Enchantment [/card] [card] name=AEther Burst -target=creature|battlefield +target=creature|battlefield auto=moveto(ownerhand) text=Return up to X target creatures to their owners' hands, where X is one plus the number of cards named AEther Burst in all graveyards as you cast AEther Burst. mana={1}{U} @@ -3677,7 +3677,7 @@ toughness=1+* [/card] [card] name=An-Havva Inn -auto=life:type:creature[green]|battlefieldplus1plusend controller +auto=life:plusonetype:creature[green]|battlefield controller text=You gain X plus 1 life, where X is the number of green creatures on the battlefield. mana={1}{G}{G} type=Sorcery @@ -10126,7 +10126,7 @@ type=Sorcery [card] name=Black Vise auto=name(choose opponent) notatarget(opponent) deplete:0 -auto=@each targetedplayer upkeep:damage:type:*:targetedpersonshandminus4minusend targetedplayer +auto=@each targetedplayer upkeep:damage:morethanfourcards targetedplayer text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={1} type=Artifact @@ -54376,7 +54376,7 @@ type=Artifact [/card] [card] name=Iron Maiden -auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent +auto=@each opponent upkeep:damage:morethanfourcards opponent text=At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={3} type=Artifact @@ -57937,7 +57937,7 @@ type=Instant [card] name=Kindle target=creature,player -auto=damage:type:kindle:graveyardplus2plusend +auto=damage:plustwotype:kindle:graveyard text=Kindle deals X damage to target creature or player, where X is 2 plus the number of cards named Kindle in all graveyards. mana={1}{R} type=Instant @@ -61533,7 +61533,7 @@ toughness=5 [/card] [card] name=Lhurgoyf -anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive +anyzone=type:creature:graveyard/plusonetype:creature:graveyard cdaactive text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1. mana={2}{G}{G} type=Creature @@ -68102,7 +68102,7 @@ type=Legendary Land [card] name=Mind Burst target=player -auto=ability$!name(discard) target(*|myhandplus1plusend) reject!$ targetedplayer +auto=ability$!name(discard) target(*|myhand) reject!$ targetedplayer text=Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards. mana={1}{B} type=Sorcery @@ -109311,7 +109311,7 @@ toughness=7 [/card] [card] name=Tarmogoyf -anyzone=gravecardtypes/gravecardtypesplus1plusend cdaactive +anyzone=gravecardtypes/plusonegravecardtypes cdaactive text=Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (The card types are artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal.) mana={1}{G} type=Creature @@ -120125,7 +120125,7 @@ toughness=3 [/card] [card] name=Viseling -auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent +auto=@each opponent upkeep:damage:morethanfourcards opponent text=At the beginning of each opponent's upkeep, Viseling deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={4} type=Artifact Creature @@ -120200,7 +120200,7 @@ type=Instant [/card] [card] name=Vitalizing Cascade -auto=life:Xplus3plusend +auto=life:Xplusthree text=You gain X plus 3 life. mana={X}{G}{W} type=Instant @@ -121951,7 +121951,7 @@ toughness=4 [card] name=Wall of Tombstones abilities=defender -auto=@each my upkeep:transforms((,settoughness=type:creature:mygraveyardplus1plusend)) forever +auto=@each my upkeep:transforms((,settoughness=plusonetype:creature:mygraveyard)) forever text=Defender (This creature can't attack.) -- At the beginning of your upkeep, Wall of Tombstones's toughness becomes 1 plus the number of creature cards in your graveyard. (This effect lasts indefinitely.) mana={1}{B} type=Creature @@ -127555,46 +127555,6 @@ subtype=Orc Warrior power=7 toughness=2 [/card] -###### -######unsorted -[card] -name=Dark Suspicions -auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] -name=Bulwark -auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] -name=Roiling Horror -anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive -autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -suspend(0)={X}{b}{b}{b} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] -name=Dark Deal -auto=count(type:*:myhand) -auto=all(*|myhand) reject -auto=draw:countedamountplus1plusend controller -auto=count(type:*:opponenthand) -auto=all(*|opponenthand) reject -auto=draw:countedamountplus1plusend opponent -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 4e20da195..5a652b823 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -41,111 +41,111 @@ public: class MTGRevealingCards : public MTGAbility, public CardDisplay { public: - vector cards; - Player * playerForZone; - MTGGameZone * RevealZone; - MTGGameZone * RevealFromZone; - string revealCertainTypes; - string revealUntil; + vector cards; + Player * playerForZone; + MTGGameZone * RevealZone; + MTGGameZone * RevealFromZone; + string revealCertainTypes; + string revealUntil; - CardDisplay * revealDisplay; - vectortrashDisplays;//used for repeat - int nbCard; - string abilityString; - string number; - string abilityOne; - string abilityTwo; - string afterReveal; - bool afterEffectActivated; - MTGAbility * abilityToCast; - MTGAbility * abilityFirst; - MTGAbility * abilitySecond; - MTGAbility * abilityAfter; - vectorabilities; - bool repeat;//only the first ability can be repeated, and it must be targeted. - bool initCD; + CardDisplay * revealDisplay; + vectortrashDisplays;//used for repeat + int nbCard; + string abilityString; + string number; + string abilityOne; + string abilityTwo; + string afterReveal; + bool afterEffectActivated; + MTGAbility * abilityToCast; + MTGAbility * abilityFirst; + MTGAbility * abilitySecond; + MTGAbility * abilityAfter; + vectorabilities; + bool repeat;//only the first ability can be repeated, and it must be targeted. + bool initCD; - void Update(float dt); - int testDestroy(); - int toResolve(); - void CardViewBackup(MTGCardInstance * backup); - void Render(); - bool CheckUserInput(JButton key); - MTGAbility * contructAbility(string abilityToMake = ""); - MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); - virtual MTGRevealingCards * clone() const; - ~MTGRevealingCards(); - int receiveEvent(WEvent*); + void Update(float dt); + int testDestroy(); + int toResolve(); + void CardViewBackup(MTGCardInstance * backup); + void Render(); + bool CheckUserInput(JButton key); + MTGAbility * contructAbility(string abilityToMake = ""); + MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); + virtual MTGRevealingCards * clone() const; + ~MTGRevealingCards(); + int receiveEvent(WEvent*); }; class RevealDisplay : public CardDisplay { public: - RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL, - int nb_displayed_items = 7); - void AddCard(MTGCardInstance * _card); - bool CheckUserInput(JButton key); + RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL, + int nb_displayed_items = 7); + void AddCard(MTGCardInstance * _card); + bool CheckUserInput(JButton key); }; class GenericRevealAbility : public ActivatedAbility { public: - string howMany; - MTGRevealingCards * ability; - GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); - int resolve(); - const string getMenuText(); - GenericRevealAbility * clone() const; - ~GenericRevealAbility(); + string howMany; + MTGRevealingCards * ability; + GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); + int resolve(); + const string getMenuText(); + GenericRevealAbility * clone() const; + ~GenericRevealAbility(); }; class MTGScryCards : public MTGAbility, public CardDisplay { public: - vector cards; - MTGGameZone * RevealZone; - MTGGameZone * RevealFromZone; + vector cards; + MTGGameZone * RevealZone; + MTGGameZone * RevealFromZone; - CardDisplay * revealDisplay; - vectortrashDisplays;//used for repeat - int nbCard; - bool delayed; - bool dontRevealAfter; - int revealTopAmount; - string delayedAbilityString; - string abilityString; - string number; - string abilityOne; - string abilityTwo; - MTGAbility * abilityToCast; - MTGAbility * abilityFirst; - MTGAbility * abilitySecond; - vectorabilities; - bool initCD; - void Update(float dt); - int testDestroy(); - void initDisplay(int value = 0); - int toResolve(); - void Render(); - bool CheckUserInput(JButton key); - MTGAbility * contructAbility(string abilityToMake = ""); - MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); - virtual MTGScryCards * clone() const; - ~MTGScryCards(); - int receiveEvent(WEvent*); + CardDisplay * revealDisplay; + vectortrashDisplays;//used for repeat + int nbCard; + bool delayed; + bool dontRevealAfter; + int revealTopAmount; + string delayedAbilityString; + string abilityString; + string number; + string abilityOne; + string abilityTwo; + MTGAbility * abilityToCast; + MTGAbility * abilityFirst; + MTGAbility * abilitySecond; + vectorabilities; + bool initCD; + void Update(float dt); + int testDestroy(); + void initDisplay(int value = 0); + int toResolve(); + void Render(); + bool CheckUserInput(JButton key); + MTGAbility * contructAbility(string abilityToMake = ""); + MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); + virtual MTGScryCards * clone() const; + ~MTGScryCards(); + int receiveEvent(WEvent*); }; class GenericScryAbility : public ActivatedAbility { public: - string howMany; - MTGScryCards * ability; - GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); - int resolve(); - const string getMenuText(); - GenericScryAbility * clone() const; - ~GenericScryAbility(); + string howMany; + MTGScryCards * ability; + GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); + int resolve(); + const string getMenuText(); + GenericScryAbility * clone() const; + ~GenericScryAbility(); }; @@ -166,11 +166,11 @@ private: { if(!s.size()) return; - if (!card) - { - intValue = atoi(s.c_str());//if there is no card, try parsing a number. - return; - } + if (!card) + { + intValue = atoi(s.c_str());//if there is no card, try parsing a number. + return; + } MTGCardInstance * target = card->target; if(!card->storedCard) card->storedCard = card->storedSourceCard; @@ -179,8 +179,10 @@ private: bool halfdown = false; bool twice = false; bool thrice = false; + bool plusone = false; + bool plustwo = false; + bool plusthree = false; bool other = false;//othertype:[subtype] - if (!target) target = card; int multiplier = 1; if (s[0] == '-') @@ -229,7 +231,24 @@ private: size_t tXXX = s.find("thrice"); s.erase(tXXX,tXXX + 6); } - + if(s.find("plusone") != string::npos) + { + plusone = true; + size_t pOne = s.find("plusone"); + s.erase(pOne,pOne + 7); + } + if(s.find("plustwo") != string::npos) + { + plustwo = true; + size_t pTwo = s.find("plustwo"); + s.erase(pTwo,pTwo + 7); + } + if(s.find("plusthree") != string::npos) + { + plusthree = true; + size_t pThree = s.find("plusthree"); + s.erase(pThree,pThree + 9); + } if(s.find("othertype") != string::npos) { other = true; @@ -254,58 +273,18 @@ private: size_t otc = s.find("otherconvertedcost"); s.erase(otc,otc + 5); } - - if (s.find("plusend") != string::npos || s.find("minusend") != string::npos || s.find("math") != string::npos) + if(s == "prex") { - //plus#plusend and minus#minusend splits the first part and second parts and parses the - //ints for each part, then either adds or subtracts those 2 variables as specified. - vectormathFound = parseBetween(s, "math", "mathend", true); - if (mathFound.size())//maths allows us to get the value before applying multipliers - { - WParsedInt numPar(mathFound[1], NULL, card); - intValue = numPar.getValue(); - - } - else - { - vectorplusSplit = parseBetween(s, "", "plus", true); - if (plusSplit.size()) - { - WParsedInt numPar(plusSplit[1], NULL, card); - intValue = numPar.getValue(); - } - vectorplusFound = parseBetween(s, "plus", "plusend", true); - if (plusFound.size()) - { - WParsedInt numPar(plusFound[1], NULL, card); - intValue += numPar.getValue(); - } - vectorminusSplit = parseBetween(s, "", "minus", true); - if (minusSplit.size()) - { - WParsedInt numPar(minusSplit[1], NULL, card); - intValue = numPar.getValue(); - } - vectorminusFound = parseBetween(s, "minus", "minusend", true); - if (minusFound.size()) - { - WParsedInt numPar(minusFound[1], NULL, card); - intValue -= numPar.getValue(); - } - } - } - else if(s == "prex") - { - if (card->setX > -1) - { - intValue = card->setX; - } - else - { - ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); - intValue = cX->getCost(Constants::NB_Colors); - delete cX; - } + if (card->setX > -1) + { + intValue = card->setX; + } + else + { + ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); + intValue = cX->getCost(Constants::NB_Colors); + delete cX; + } } else if (s == "x" || s == "X") { @@ -382,10 +361,10 @@ private: { intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_GREEN); } - else if (s == "Iroas")//devotion to red white - { - intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE); - } + else if (s == "Iroas")//devotion to red white + { + intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE); + } else if (s.find("type:") != string::npos) { size_t begins = s.find("type:"); @@ -702,10 +681,10 @@ private: { intValue = target->getCurrentToughness(); } - else if (s == "countedamount") - { - intValue = target->CountedObjects; - } + else if (s == "countedamount") + { + intValue = target->CountedObjects; + } else if (s == "kicked") { intValue = target->kicked; @@ -827,18 +806,12 @@ private: else if (s == "pbasiclandtypes")//Basic Land types { MTGGameZone * checkZone = card->controller()->inPlay(); - intValue = //mtg rules 205.4c - cardHasTypeinZone("waste", checkZone) + - cardHasTypeinZone("forest", checkZone) + - cardHasTypeinZone("plains", checkZone) + - cardHasTypeinZone("swamp", checkZone) + - cardHasTypeinZone("island", checkZone) + - cardHasTypeinZone("mountain", checkZone) + - cardHasTypeinZone("snow-covered forest", checkZone) + - cardHasTypeinZone("snow-covered plains", checkZone) + - cardHasTypeinZone("snow-covered swamp", checkZone) + - cardHasTypeinZone("snow-covered island", checkZone) + - cardHasTypeinZone("snow-covered mountain", checkZone); + intValue = + cardHasTypeinZone("forest",checkZone) + + cardHasTypeinZone("plains",checkZone) + + cardHasTypeinZone("swamp",checkZone) + + cardHasTypeinZone("island",checkZone) + + cardHasTypeinZone("mountain",checkZone); } else if (s == "myname")//Name of the card you control { @@ -885,6 +858,13 @@ private: cardHasTypeinZone("artifact",checkZone); } } + else if (s == "morethanfourcards") + { + intValue = 0; + int damage = card->playerTarget ? card->playerTarget->game->hand->nb_cards - 4 : card->controller()->opponent()->game->hand->nb_cards - 4; + if ( damage > 0 ) + intValue = damage; + } else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable { intValue = 0; @@ -894,47 +874,55 @@ private: intValue += card->controller()->game->inPlay->cards[j]->power; } } - else if (s == "revealedp") - { - if (card->revealedLast) - intValue = card->revealedLast->power; - } - else if (s == "revealedt") - { - if (card->revealedLast) - intValue = card->revealedLast->toughness; - } - else if (s == "revealedmana") - { - if (card->revealedLast) - intValue = card->revealedLast->getManaCost()->getConvertedCost(); - } - else if(!intValue)//found nothing, try parsing a atoi + else if (s == "revealedp") + { + if (card->revealedLast) + intValue = card->revealedLast->power; + } + else if (s == "revealedt") + { + if (card->revealedLast) + intValue = card->revealedLast->toughness; + } + else if (s == "revealedmana") + { + if (card->revealedLast) + intValue = card->revealedLast->getManaCost()->getConvertedCost(); + } + else { intValue = atoi(s.c_str()); } - if (intValue > 0)//dont divide by 0 the rest are valid. + if(intValue > 0) { - if (halfup) + if(halfup) { - if (intValue % 2 == 1) + if(intValue%2 == 1) intValue++; - intValue = intValue / 2; + intValue = intValue/2; } - if (halfdown) - intValue = intValue / 2; + if(halfdown) + intValue = intValue/2; + if(twice) + intValue = intValue*2; + if(thrice) + intValue = intValue*3; + if(plusone) + intValue = intValue+1; + if(plustwo) + intValue = intValue+2; + if(plusthree) + intValue = intValue+3; } - if (twice) - intValue = intValue * 2; - if (thrice) - intValue = intValue * 3; - if (intValue < 0) + else { - //we remove "-" at the start and are parsing for real values. - //if we ended up with a value less than 0, then we return just 0 - intValue = 0; + if(plusone) + intValue = intValue+1; + if(plustwo) + intValue = intValue+2; + if(plusthree) + intValue = intValue+3; } - intValue *= multiplier; } public: @@ -3489,7 +3477,7 @@ public: list colors; int power, toughness; int tokenId; - string _cardName; + string _cardName; string name; string sabilities; string starfound; @@ -3501,7 +3489,7 @@ public: MTGCardInstance * myToken; vector currentAbilities; Player * tokenReciever; - //by id + //by id ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, int tokenId,string starfound, WParsedInt * multiplier = NULL, int who = 0,bool aLivingWeapon = false) : ActivatedAbility(observer, _id, _source, _cost, 0), tokenId(tokenId), starfound(starfound),multiplier(multiplier), who(who),aLivingWeapon(aLivingWeapon) @@ -3511,18 +3499,18 @@ public: if (card) name = card->data->getName(); battleReady = false; } - //by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)... - ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL, - int who = 0, bool aLivingWeapon = false) : - ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon) - { - if (!multiplier) this->multiplier = NEW WParsedInt(1); - MTGCard * card = MTGCollection()->getCardByName(_cardName); - tokenId = card->getId(); - if (card) name = card->data->getName(); - battleReady = false; - } - //by construction + //by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)... + ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL, + int who = 0, bool aLivingWeapon = false) : + ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon) + { + if (!multiplier) this->multiplier = NEW WParsedInt(1); + MTGCard * card = MTGCollection()->getCardByName(_cardName); + tokenId = card->getId(); + if (card) name = card->data->getName(); + battleReady = false; + } + //by construction ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string sname, string stypes, int _power, int _toughness, string sabilities, string starfound,WParsedInt * multiplier = NULL, int _who = 0,bool aLivingWeapon = false,string spt = "") : ActivatedAbility(observer, _id, _source, _cost, 0),sabilities(sabilities),starfound(starfound), multiplier(multiplier), who(_who),aLivingWeapon(aLivingWeapon),spt(spt) @@ -4045,12 +4033,12 @@ class AThis: public MTGAbility, public NestedAbility public: MTGAbility * a; ThisDescriptor * td; - string restrictionCheck; + string restrictionCheck; AThis(GameObserver* observer, int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability, string restriction = "") : MTGAbility(observer, _id, _source, _target), NestedAbility(ability) { td = _td; - restrictionCheck = restriction; + restrictionCheck = restriction; ability->source = source; ability->target = target; a = NULL; @@ -4074,18 +4062,18 @@ public: int resolve() { - int match = 0; - if (td) - { - match = td->match(source); - } - else - {//restriction check instead of Targetchooser - AbilityFactory abf(target->getObserver()); - int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck); - if (checkCond) - match = 1; - } + int match = 0; + if (td) + { + match = td->match(source); + } + else + {//restriction check instead of Targetchooser + AbilityFactory abf(target->getObserver()); + int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck); + if (checkCond) + match = 1; + } if (match > 0) { addAbilityToGame(); @@ -4132,7 +4120,7 @@ public: { AThis * a = NEW AThis(*this); a->ability = ability->clone(); - if(a->td) + if(a->td) a->td = td->clone(); return a; } @@ -4350,11 +4338,11 @@ public: class ABestow : public ActivatedAbility { public: - MTGCardInstance * _card; - ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); - int resolve(); - const string getMenuText(); - ABestow * clone() const; + MTGCardInstance * _card; + ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); + int resolve(); + const string getMenuText(); + ABestow * clone() const; }; /* Can tap a target for a cost */ @@ -4381,16 +4369,16 @@ public: class AAWhatsX : public ActivatedAbility { public: - int value; - MTGAbility * costRule; - AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); - int resolve(); - const string getMenuText() - { - sprintf(menuText, "%i", value); - return menuText; - }; - AAWhatsX * clone() const; + int value; + MTGAbility * costRule; + AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); + int resolve(); + const string getMenuText() + { + sprintf(menuText, "%i", value); + return menuText; + }; + AAWhatsX * clone() const; }; /* set max level up on a levelup creature this is an Ai hint ability, no effect for players.*/ @@ -4407,17 +4395,17 @@ public: class AACountObject : public ActivatedAbility { public: - string value; + string value; - AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value =""); - int resolve(); - AACountObject * clone() const; + AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value =""); + int resolve(); + AACountObject * clone() const; }; /* Can prevent a card from untapping next untap */ class AAFrozen: public ActivatedAbility { public: - bool freeze; + bool freeze; AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, bool tap, ManaCost * _cost = NULL); int resolve(); const string getMenuText(); @@ -5208,32 +5196,32 @@ public: class AGrant : public MTGAbility { public: - MTGCardInstance * Blessed; - bool resolved; - MTGAbility * Granted; - MTGAbility * toGrant; - AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); - void Update(float dt); - void resolveGrant(); - int resolve(); - const string getMenuText(); - AGrant * clone() const; - ~AGrant(); + MTGCardInstance * Blessed; + bool resolved; + MTGAbility * Granted; + MTGAbility * toGrant; + AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + void Update(float dt); + void resolveGrant(); + int resolve(); + const string getMenuText(); + AGrant * clone() const; + ~AGrant(); private: - void removeGranted(MTGCardInstance *_target); + void removeGranted(MTGCardInstance *_target); }; //GrantWrapper class AGrantWrapper : public InstantAbility { public: - AGrant * ability; - MTGAbility * Granted; - AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); - int resolve(); - const string getMenuText(); - AGrantWrapper * clone() const; - ~AGrantWrapper(); + AGrant * ability; + MTGAbility * Granted; + AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + int resolve(); + const string getMenuText(); + AGrantWrapper * clone() const; + ~AGrantWrapper(); }; //ABlink @@ -6485,7 +6473,7 @@ public: MTGCardInstance * theNamedCard; bool noEvent; bool putinplay; - bool asNormalMadness; + bool asNormalMadness; AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay,bool asNormalMadness = false); int testDestroy(){return 0;}; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 979de37c6..355932ccf 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -58,10 +58,6 @@ public: int Angel[2]; bool dragonbonusgranted[2]; int dragon[2]; - bool eldrazibonusgranted[2]; - int eldrazi[2]; - bool werewolfbonusgranted[2]; - int werewolf[2]; int receiveEvent(WEvent * event); void grantAward(string awardName,int amount); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index eb2d7e5bb..2516a18be 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -45,477 +45,477 @@ MTGEventText * MTGEventText::clone() const //generic activated ability for wrapping reveals. GenericRevealAbility::GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _howMany) : - ActivatedAbility(observer, id, source, NULL), howMany(_howMany) + Targetable * target, string _howMany) : + ActivatedAbility(observer, id, source, NULL), howMany(_howMany) { - this->GetId(); + this->GetId(); } int GenericRevealAbility::resolve() { - MTGAbility * ability = NEW MTGRevealingCards(game, this->GetId(), source, howMany); - ability->addToGame(); - return 1; + MTGAbility * ability = NEW MTGRevealingCards(game, this->GetId(), source, howMany); + ability->addToGame(); + return 1; } const string GenericRevealAbility::getMenuText() { - return "Reveal Cards"; + return "Reveal Cards"; } GenericRevealAbility * GenericRevealAbility::clone() const { - GenericRevealAbility * a = NEW GenericRevealAbility(*this); - return a; + GenericRevealAbility * a = NEW GenericRevealAbility(*this); + return a; } GenericRevealAbility::~GenericRevealAbility() { - //SAFE_DELETE(ability); + //SAFE_DELETE(ability); } //carddisplay created for use in abilities. RevealDisplay::RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener, TargetChooser * tc, - int nb_displayed_items) : - CardDisplay(id, game, x, y, listener, tc, nb_displayed_items) + int nb_displayed_items) : + CardDisplay(id, game, x, y, listener, tc, nb_displayed_items) { } void RevealDisplay::AddCard(MTGCardInstance * _card) { - CardGui * card = NEW CardView(CardView::nullZone, _card, static_cast (x + 20 + (mObjects.size() - start_item) * 30), - static_cast (y + 25)); - Add(card); + CardGui * card = NEW CardView(CardView::nullZone, _card, static_cast (x + 20 + (mObjects.size() - start_item) * 30), + static_cast (y + 25)); + Add(card); } bool RevealDisplay::CheckUserInput(JButton key) { - if (JGE_BTN_SEC == key || JGE_BTN_PRI == key || JGE_BTN_UP == key || JGE_BTN_DOWN == key) - return false; + if (JGE_BTN_SEC == key || JGE_BTN_PRI == key || JGE_BTN_UP == key || JGE_BTN_DOWN == key) + return false; - return CardDisplay::CheckUserInput(key); + return CardDisplay::CheckUserInput(key); } //display card selector box of specified zone. MTGRevealingCards::MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string coreAbility) : - MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) + MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) { - abilityToCast = NULL; - revealDisplay = NULL; - abilityFirst = NULL; + abilityToCast = NULL; + revealDisplay = NULL; + abilityFirst = NULL; abilitySecond = NULL; - abilityString = coreAbility; - initCD = false; + abilityString = coreAbility; + initCD = false; - afterReveal = ""; - afterEffectActivated = false; + afterReveal = ""; + afterEffectActivated = false; - repeat = false; - playerForZone = NULL; - revealCertainTypes = ""; - revealUntil = ""; + repeat = false; + playerForZone = NULL; + revealCertainTypes = ""; + revealUntil = ""; - if (card->playerTarget) - playerForZone = card->playerTarget; - else - playerForZone = source->controller(); + if (card->playerTarget) + playerForZone = card->playerTarget; + else + playerForZone = source->controller(); - RevealZone = playerForZone->game->reveal; - zone = RevealZone; - RevealFromZone = playerForZone->game->library; + RevealZone = playerForZone->game->reveal; + zone = RevealZone; + RevealFromZone = playerForZone->game->library; - vectoramount = parseBetween(coreAbility, "", " "); - if (amount.size()) - { - number = amount[1]; - } + vectoramount = parseBetween(coreAbility, "", " "); + if (amount.size()) + { + number = amount[1]; + } - vectordifferentZone = parseBetween(coreAbility, "revealzone(", ")"); - if (differentZone.size()) - { - RevealFromZone = MTGGameZone::stringToZone(game,differentZone[1],source,NULL); - } + vectordifferentZone = parseBetween(coreAbility, "revealzone(", ")"); + if (differentZone.size()) + { + RevealFromZone = MTGGameZone::stringToZone(game,differentZone[1],source,NULL); + } - vectorcertainTypes = parseBetween(coreAbility, "revealtype(", ")"); - if (certainTypes.size()) - { - revealCertainTypes = certainTypes[1]; - } + vectorcertainTypes = parseBetween(coreAbility, "revealtype(", ")"); + if (certainTypes.size()) + { + revealCertainTypes = certainTypes[1]; + } - vectorRevealCardUntil = parseBetween(coreAbility, "revealuntil(", ")"); - if (RevealCardUntil.size()) - { - revealUntil = RevealCardUntil[1]; - } + vectorRevealCardUntil = parseBetween(coreAbility, "revealuntil(", ")"); + if (RevealCardUntil.size()) + { + revealUntil = RevealCardUntil[1]; + } - vectorfirst = parseBetween(coreAbility, "optionone ", " optiononeend"); - if (first.size()) - { - abilityOne = first[1]; - } - vectorsecond = parseBetween(coreAbility, "optiontwo ", " optiontwoend"); - if (second.size()) - { - abilityTwo = second[1]; - } - vectorafterEffect = parseBetween(coreAbility, "afterrevealed ", " afterrevealedend"); - if (afterEffect.size()) - { - afterReveal = afterEffect[1]; - } + vectorfirst = parseBetween(coreAbility, "optionone ", " optiononeend"); + if (first.size()) + { + abilityOne = first[1]; + } + vectorsecond = parseBetween(coreAbility, "optiontwo ", " optiontwoend"); + if (second.size()) + { + abilityTwo = second[1]; + } + vectorafterEffect = parseBetween(coreAbility, "afterrevealed ", " afterrevealedend"); + if (afterEffect.size()) + { + afterReveal = afterEffect[1]; + } - repeat = coreAbility.find("repeat") != string::npos; + repeat = coreAbility.find("repeat") != string::npos; } void MTGRevealingCards::Update(float dt) { - if (game->OpenedDisplay != this->revealDisplay && !initCD)//wait your turn - { - //if any carddisplays are open, dont do anything until theyre closed, then wait your turn if multiple reveals trigger. - return; - } - if (game->mLayers->actionLayer()->menuObject) - return;//dont do any of this if a menuobject exist. - if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) - { + if (game->OpenedDisplay != this->revealDisplay && !initCD)//wait your turn + { + //if any carddisplays are open, dont do anything until theyre closed, then wait your turn if multiple reveals trigger. + return; + } + if (game->mLayers->actionLayer()->menuObject) + return;//dont do any of this if a menuobject exist. + if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) + { - WParsedInt nbCardP(number, NULL, source); - nbCard = nbCardP.getValue(); - int adjust = 0; - switch (nbCard) - { - //adjust length and location of carddisplay box. - case 1:adjust = 120; break; - case 2:adjust = 145; break; - case 3:adjust = 175; break; - case 4:adjust = 200; break; - case 5:adjust = 225; break; - default:adjust = 225; break; - } - if (revealUntil.size()) - { - adjust = 225; - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL,5); - } - else - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); - revealDisplay->zone = RevealFromZone; - trashDisplays.push_back(revealDisplay); + WParsedInt nbCardP(number, NULL, source); + nbCard = nbCardP.getValue(); + int adjust = 0; + switch (nbCard) + { + //adjust length and location of carddisplay box. + case 1:adjust = 120; break; + case 2:adjust = 145; break; + case 3:adjust = 175; break; + case 4:adjust = 200; break; + case 5:adjust = 225; break; + default:adjust = 225; break; + } + if (revealUntil.size()) + { + adjust = 225; + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL,5); + } + else + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); + revealDisplay->zone = RevealFromZone; + trashDisplays.push_back(revealDisplay); - if (revealCertainTypes.size())//revealing cards of a TARGETCHOOSER type. - { - TargetChooserFactory tcf(game); - TargetChooser * rTc = tcf.createTargetChooser(revealCertainTypes, source); - int startingNumber = RevealFromZone->nb_cards - 1; - if (rTc) - for (int i = startingNumber; i > -1; i--) - { - if (!RevealFromZone->cards.size()) - break; - MTGCardInstance * toMove = RevealFromZone->cards[i]; - if (toMove) - { - if (rTc->canTarget(toMove, true)) - { - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } - } + if (revealCertainTypes.size())//revealing cards of a TARGETCHOOSER type. + { + TargetChooserFactory tcf(game); + TargetChooser * rTc = tcf.createTargetChooser(revealCertainTypes, source); + int startingNumber = RevealFromZone->nb_cards - 1; + if (rTc) + for (int i = startingNumber; i > -1; i--) + { + if (!RevealFromZone->cards.size()) + break; + MTGCardInstance * toMove = RevealFromZone->cards[i]; + if (toMove) + { + if (rTc->canTarget(toMove, true)) + { + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } + } - } - SAFE_DELETE(rTc); - } - else if(revealUntil.size())//reveal cards until you reveal a TARGETCHOOSER. - { - TargetChooserFactory tcf(game); - TargetChooser * rUc = tcf.createTargetChooser(revealUntil, source); - bool foundCard = false; - int howMany = nbCard; - int startingNumber = RevealFromZone->nb_cards; - for (int i = 0; i < startingNumber; i++) - { - if (foundCard && howMany == 0) - break; - if (howMany == 0) - break; //not allowed to reveal until 0 of something is revealed. - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - if (rUc->canTarget(toMove, true)) - { - foundCard = true; - howMany--; - } + } + SAFE_DELETE(rTc); + } + else if(revealUntil.size())//reveal cards until you reveal a TARGETCHOOSER. + { + TargetChooserFactory tcf(game); + TargetChooser * rUc = tcf.createTargetChooser(revealUntil, source); + bool foundCard = false; + int howMany = nbCard; + int startingNumber = RevealFromZone->nb_cards; + for (int i = 0; i < startingNumber; i++) + { + if (foundCard && howMany == 0) + break; + if (howMany == 0) + break; //not allowed to reveal until 0 of something is revealed. + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + if (rUc->canTarget(toMove, true)) + { + foundCard = true; + howMany--; + } - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } - } - SAFE_DELETE(rUc); - } - else - { - for (int i = 0; i < nbCard; i++)//normal reveal - { - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } + } + SAFE_DELETE(rUc); + } + else + { + for (int i = 0; i < nbCard; i++)//normal reveal + { + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } - } + } - } + } - //build the zone, create the first ability. - revealDisplay->init(RevealZone); - revealDisplay->zone = RevealZone; - game->OpenedDisplay = revealDisplay; - toResolve(); - initCD = true; - } + //build the zone, create the first ability. + revealDisplay->init(RevealZone); + revealDisplay->zone = RevealZone; + game->OpenedDisplay = revealDisplay; + toResolve(); + initCD = true; + } - //card display is ready and loaded, abilities have fired at this point. - //critical for testdestroy, a function that determines if a ability can - //exist in condiations such as source not being in play. - - if (!zone->cards.size()) - { - //all possible actions are done, the zone is empty, lets NULL it so it clears it off the screen. - //DO NOT SAFE_DELETE here, it destroys the card->view and backups kept for the second ability. - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; + //card display is ready and loaded, abilities have fired at this point. + //critical for testdestroy, a function that determines if a ability can + //exist in condiations such as source not being in play. + + if (!zone->cards.size()) + { + //all possible actions are done, the zone is empty, lets NULL it so it clears it off the screen. + //DO NOT SAFE_DELETE here, it destroys the card->view and backups kept for the second ability. + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; - if (repeat) - { - initCD = false; - } - else if (afterReveal.size() && !afterEffectActivated) - { - afterEffectActivated = true; - abilityAfter = contructAbility(afterReveal); - game->addObserver(abilityAfter); - } - else - this->removeFromGame(); - } + if (repeat) + { + initCD = false; + } + else if (afterReveal.size() && !afterEffectActivated) + { + afterEffectActivated = true; + abilityAfter = contructAbility(afterReveal); + game->addObserver(abilityAfter); + } + else + this->removeFromGame(); + } - if (revealDisplay) - { - revealDisplay->Update(dt); - Render(); - } + if (revealDisplay) + { + revealDisplay->Update(dt); + Render(); + } - MTGAbility::Update(dt); + MTGAbility::Update(dt); } void MTGRevealingCards::CardViewBackup(MTGCardInstance * backup) { - CardView* t; + CardView* t; - t = NEW CardView(CardView::nullZone, backup, 0, 0); - //we store copies of the card view since the safe_delete of card displays also deletes the guis stored in them. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); - return; + t = NEW CardView(CardView::nullZone, backup, 0, 0); + //we store copies of the card view since the safe_delete of card displays also deletes the guis stored in them. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); + return; } int MTGRevealingCards::testDestroy() { - if (game->mExtraPayment) - return 0; - if (revealDisplay) - return 0; - if (zone->cards.size()) - return 0; - if (!initCD) - return 0; - if (game->mLayers->actionLayer()->menuObject) - return 0; - if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) - return 0; + if (game->mExtraPayment) + return 0; + if (revealDisplay) + return 0; + if (zone->cards.size()) + return 0; + if (!initCD) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) + return 0; - return 1; + return 1; } int MTGRevealingCards::toResolve() { - TargetChooserFactory tcf(game); - vectorsplitTarget = parseBetween(abilityOne, "target(", ")"); - //we build a tc to check if the first ability has any valid targets, if it doesnt, just add the 2nd one. - if (splitTarget.size()) - { - TargetChooser * rTc = tcf.createTargetChooser(splitTarget[1].c_str(), source); + TargetChooserFactory tcf(game); + vectorsplitTarget = parseBetween(abilityOne, "target(", ")"); + //we build a tc to check if the first ability has any valid targets, if it doesnt, just add the 2nd one. + if (splitTarget.size()) + { + TargetChooser * rTc = tcf.createTargetChooser(splitTarget[1].c_str(), source); - if (rTc && rTc->countValidTargets()) - { - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); + if (rTc && rTc->countValidTargets()) + { + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + + } + else + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); - } - else - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - - } - SAFE_DELETE(rTc); - } - else//the first ability is not targeted - { - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - } - return 1; + } + SAFE_DELETE(rTc); + } + else//the first ability is not targeted + { + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + } + return 1; } MTGAbility * MTGRevealingCards::contructAbility(string abilityToMake) { - AbilityFactory af(game); - abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); - if (!abilityToCast) - return NULL; - abilityToCast->canBeInterrupted = false; - abilityToCast->forceDestroy = 1; - return abilityToCast; + AbilityFactory af(game); + abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); + if (!abilityToCast) + return NULL; + abilityToCast->canBeInterrupted = false; + abilityToCast->forceDestroy = 1; + return abilityToCast; } void MTGRevealingCards::Render() { - if (!revealDisplay) - return; - CheckUserInput(mEngine->ReadButton()); - revealDisplay->CheckUserInput(mEngine->ReadButton()); - revealDisplay->Render(); - return; + if (!revealDisplay) + return; + CheckUserInput(mEngine->ReadButton()); + revealDisplay->CheckUserInput(mEngine->ReadButton()); + revealDisplay->Render(); + return; } bool MTGRevealingCards::CheckUserInput(JButton key) { - //DO NOT REFACTOR BELOW, IT KEPT SPLIT UP TO MAINTAIN READABILITY. + //DO NOT REFACTOR BELOW, IT KEPT SPLIT UP TO MAINTAIN READABILITY. //we override check inputs, we MUST complete reveal and its effects before being allowed to do anything else. - TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); - if (this->source->controller()->isAI()) - { - if (this->source->controller() != game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); - } - if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key)//android back button - { - if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) - { - tc->done = true; - tc->forceTargetListReadyByPlayer = 1; - //this is for when we have targets but only want to move Y targets, it allows us to - //tell the targetchooser we are done. - if (!abilitySecond && !tc->getNbTargets() && tc->source) - {//we selected nothing for the first ability. - tc->source->getObserver()->cardClick(tc->source, 0, false); - if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(0); - //remove it from the game, update, and remove it from stack if needed. - //before adding next ability, otherwise we end up with a menu reactToClick. - if (zone->cards.size() && abilityFirst->testDestroy())//generally only want to add ability 2 if anything is left in the zone. - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } - } - else if (tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - } - } - else if (!tc && !abilitySecond)//the actions of the first card have finished and we're done looking at the cards. - { //or the first ability was an "all(" which was not a mover ability. - CheckUserInput(JGE_BTN_OK); - } - return false; - } - if (JGE_BTN_OK == key)//for ease if we're sitting there looking at the card display and click a card after first ability. - { //looks redundent and can be added above as another condiational, however we would end up with a massive - //if statement that becomes very very hard to follow. - if (!tc && !abilitySecond) - { - if (abilityFirst) - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(1); + TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); + if (this->source->controller()->isAI()) + { + if (this->source->controller() != game->isInterrupting) + game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); + } + if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key)//android back button + { + if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) + { + tc->done = true; + tc->forceTargetListReadyByPlayer = 1; + //this is for when we have targets but only want to move Y targets, it allows us to + //tell the targetchooser we are done. + if (!abilitySecond && !tc->getNbTargets() && tc->source) + {//we selected nothing for the first ability. + tc->source->getObserver()->cardClick(tc->source, 0, false); + if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(0); + //remove it from the game, update, and remove it from stack if needed. + //before adding next ability, otherwise we end up with a menu reactToClick. + if (zone->cards.size() && abilityFirst->testDestroy())//generally only want to add ability 2 if anything is left in the zone. + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } + } + else if (tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + } + } + else if (!tc && !abilitySecond)//the actions of the first card have finished and we're done looking at the cards. + { //or the first ability was an "all(" which was not a mover ability. + CheckUserInput(JGE_BTN_OK); + } + return false; + } + if (JGE_BTN_OK == key)//for ease if we're sitting there looking at the card display and click a card after first ability. + { //looks redundent and can be added above as another condiational, however we would end up with a massive + //if statement that becomes very very hard to follow. + if (!tc && !abilitySecond) + { + if (abilityFirst) + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(1); - if (zone->cards.size()) - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } + if (zone->cards.size()) + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } - } - } - if(revealDisplay) + } + } + if(revealDisplay) return revealDisplay->CheckUserInput(key); - return false; + return false; } MTGRevealingCards * MTGRevealingCards::clone() const { - return NEW MTGRevealingCards(*this); + return NEW MTGRevealingCards(*this); } MTGRevealingCards::~MTGRevealingCards() { - for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) - SAFE_DELETE(*it); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - SAFE_DELETE(*it); + for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) + SAFE_DELETE(*it); + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + SAFE_DELETE(*it); } int MTGRevealingCards::receiveEvent(WEvent* e) { - if (WEventZoneChange* event = dynamic_cast(e)) - { - if (event->from == zone) - { - CardView* t; - if (event->card->view) - t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + if (WEventZoneChange* event = dynamic_cast(e)) + { + if (event->from == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); else t = NEW CardView(CardView::nullZone, event->card, (float)x, (float)y); - //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. - //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than - //they should be, possibly someone being to over cautious. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); + //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. + //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than + //they should be, possibly someone being to over cautious. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); return 1; - } - } - return 0; + } + } + return 0; } @@ -532,353 +532,353 @@ int MTGRevealingCards::receiveEvent(WEvent* e) ///delayed changes the order, makes the ability fire after the 2nd reveal is finished. /// MTGScryCards::MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string coreAbility) : - MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) + MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) { - abilityToCast = NULL; - revealDisplay = NULL; - abilityFirst = NULL; - abilitySecond = NULL; - abilityString = coreAbility; - delayedAbilityString = ""; - revealTopAmount = 1;//scry, then reveal the top card and do effect. + abilityToCast = NULL; + revealDisplay = NULL; + abilityFirst = NULL; + abilitySecond = NULL; + abilityString = coreAbility; + delayedAbilityString = ""; + revealTopAmount = 1;//scry, then reveal the top card and do effect. - initCD = false; - RevealZone = source->controller()->game->reveal; - zone =RevealZone; - RevealFromZone = source->controller()->game->library; + initCD = false; + RevealZone = source->controller()->game->reveal; + zone =RevealZone; + RevealFromZone = source->controller()->game->library; - vectoramount = parseBetween(coreAbility, "", " "); - if (amount.size()) - { - number = amount[1]; - } + vectoramount = parseBetween(coreAbility, "", " "); + if (amount.size()) + { + number = amount[1]; + } - vectordifferentZone = parseBetween(coreAbility, "scryzone(", ")"); - if (differentZone.size()) - { - RevealFromZone = MTGGameZone::stringToZone(game, differentZone[1], source, NULL); - } + vectordifferentZone = parseBetween(coreAbility, "scryzone(", ")"); + if (differentZone.size()) + { + RevealFromZone = MTGGameZone::stringToZone(game, differentZone[1], source, NULL); + } - abilityOne = "name(Place on top) target(*|myreveal) moveto(mylibrary)"; + abilityOne = "name(Place on top) target(*|myreveal) moveto(mylibrary)"; delayed = coreAbility.find("delayed") != string::npos; - dontRevealAfter = coreAbility.find("dontshow") != string::npos; - if(dontRevealAfter) - revealTopAmount = 0; - vectorsecond = parseBetween(coreAbility, "scrycore ", " scrycoreend"); - if (second.size()) - { - if (delayed) - { - abilityTwo = "target(*|reveal) name(Reveal the top card) donothing"; - delayedAbilityString = second[1]; - } - else - abilityTwo = second[1]; - } + dontRevealAfter = coreAbility.find("dontshow") != string::npos; + if(dontRevealAfter) + revealTopAmount = 0; + vectorsecond = parseBetween(coreAbility, "scrycore ", " scrycoreend"); + if (second.size()) + { + if (delayed) + { + abilityTwo = "target(*|reveal) name(Reveal the top card) donothing"; + delayedAbilityString = second[1]; + } + else + abilityTwo = second[1]; + } - + } void MTGScryCards::Update(float dt) { - if (game->OpenedDisplay != this->revealDisplay && !initCD) - return; - if (game->mLayers->actionLayer()->menuObject) - return; - if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) - { - WParsedInt nbCardP(number, NULL, source); - nbCard = nbCardP.getValue(); - initDisplay(nbCard); - toResolve(); - } - initCD = true; - if (!zone->cards.size() && abilitySecond) - { - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; - this->removeFromGame(); - } - if (revealDisplay) - { - revealDisplay->Update(dt); - Render(); - } - MTGAbility::Update(dt); + if (game->OpenedDisplay != this->revealDisplay && !initCD) + return; + if (game->mLayers->actionLayer()->menuObject) + return; + if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) + { + WParsedInt nbCardP(number, NULL, source); + nbCard = nbCardP.getValue(); + initDisplay(nbCard); + toResolve(); + } + initCD = true; + if (!zone->cards.size() && abilitySecond) + { + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; + this->removeFromGame(); + } + if (revealDisplay) + { + revealDisplay->Update(dt); + Render(); + } + MTGAbility::Update(dt); } void MTGScryCards::initDisplay(int value) { - if (RevealZone->cards.size()) - { - do - { - MTGCardInstance * toMove = RevealZone->cards[0]; - if (toMove) - { - MTGAbility * a = NEW AALibraryBottom(game, getMaxId(), source, toMove); - a->oneShot = 1; - a->resolve(); - SAFE_DELETE(a); - } - } while (RevealZone->cards.size()); + if (RevealZone->cards.size()) + { + do + { + MTGCardInstance * toMove = RevealZone->cards[0]; + if (toMove) + { + MTGAbility * a = NEW AALibraryBottom(game, getMaxId(), source, toMove); + a->oneShot = 1; + a->resolve(); + SAFE_DELETE(a); + } + } while (RevealZone->cards.size()); - game->Update(0); - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; - } - int adjust = 0; - switch (value) - { - case 1:adjust = 120; break; - case 2:adjust = 145; break; - case 3:adjust = 175; break; - case 4:adjust = 200; break; - case 5:adjust = 225; break; - default:adjust = 225; break; - } - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); - revealDisplay->zone = RevealFromZone; - trashDisplays.push_back(revealDisplay); - for (int i = 0; i < value; i++) - { - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - CardView* t; - t = NEW CardView(CardView::nullZone, toMove, 0, 0); - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - cards.push_back(t); - source->controller()->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } - } - revealDisplay->init(RevealZone); - revealDisplay->zone = RevealZone; - game->OpenedDisplay = revealDisplay; + game->Update(0); + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; + } + int adjust = 0; + switch (value) + { + case 1:adjust = 120; break; + case 2:adjust = 145; break; + case 3:adjust = 175; break; + case 4:adjust = 200; break; + case 5:adjust = 225; break; + default:adjust = 225; break; + } + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); + revealDisplay->zone = RevealFromZone; + trashDisplays.push_back(revealDisplay); + for (int i = 0; i < value; i++) + { + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + CardView* t; + t = NEW CardView(CardView::nullZone, toMove, 0, 0); + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + cards.push_back(t); + source->controller()->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } + } + revealDisplay->init(RevealZone); + revealDisplay->zone = RevealZone; + game->OpenedDisplay = revealDisplay; } int MTGScryCards::testDestroy() { - if (game->mExtraPayment) - return 0; - if (revealDisplay) - return 0; - if (zone->cards.size()) - return 0; - if (!initCD) - return 0; - if (game->mLayers->actionLayer()->menuObject) - return 0; - if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) - return 0; + if (game->mExtraPayment) + return 0; + if (revealDisplay) + return 0; + if (zone->cards.size()) + return 0; + if (!initCD) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) + return 0; - return 1; + return 1; } int MTGScryCards::toResolve() { - //scry will always have valid targets. - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - return 1; + //scry will always have valid targets. + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + return 1; } MTGAbility * MTGScryCards::contructAbility(string abilityToMake) { - AbilityFactory af(game); - abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); - if (!abilityToCast) - return NULL; - abilityToCast->canBeInterrupted = false; - abilityToCast->forceDestroy = 1; - return abilityToCast; + AbilityFactory af(game); + abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); + if (!abilityToCast) + return NULL; + abilityToCast->canBeInterrupted = false; + abilityToCast->forceDestroy = 1; + return abilityToCast; } void MTGScryCards::Render() { - if (!revealDisplay) - return; - CheckUserInput(mEngine->ReadButton()); - if (revealDisplay) - { - revealDisplay->CheckUserInput(mEngine->ReadButton()); - revealDisplay->Render(); - } - return; + if (!revealDisplay) + return; + CheckUserInput(mEngine->ReadButton()); + if (revealDisplay) + { + revealDisplay->CheckUserInput(mEngine->ReadButton()); + revealDisplay->Render(); + } + return; } bool MTGScryCards::CheckUserInput(JButton key) { - //DO NOT REFACTOR BELOW - TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); - if (this->source->controller()->isAI()) - {//ai doesnt click button, and the engine has no way of knowing whos clicking button - //for now we will cancel interrupts made when ai is making choice - //in the future we will need a way to find out if the human is pressing the keys and which player. - if (this->source->controller() != game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); - } - if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key) - { - if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) - { - tc->done = true; - tc->forceTargetListReadyByPlayer = 1; - if (!abilitySecond && !tc->getNbTargets() && tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(0); - if (zone->cards.size() && abilityFirst->testDestroy()) - { - initDisplay(revealTopAmount); - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } - } - else if (tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - } - } - else if (!tc && !abilitySecond) - { - CheckUserInput(JGE_BTN_OK); - } - return false; - } - if (JGE_BTN_OK == key) - { - if (!tc && !abilitySecond) - { - if (abilityFirst) - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(1); + //DO NOT REFACTOR BELOW + TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); + if (this->source->controller()->isAI()) + {//ai doesnt click button, and the engine has no way of knowing whos clicking button + //for now we will cancel interrupts made when ai is making choice + //in the future we will need a way to find out if the human is pressing the keys and which player. + if (this->source->controller() != game->isInterrupting) + game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); + } + if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key) + { + if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) + { + tc->done = true; + tc->forceTargetListReadyByPlayer = 1; + if (!abilitySecond && !tc->getNbTargets() && tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(0); + if (zone->cards.size() && abilityFirst->testDestroy()) + { + initDisplay(revealTopAmount); + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } + } + else if (tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + } + } + else if (!tc && !abilitySecond) + { + CheckUserInput(JGE_BTN_OK); + } + return false; + } + if (JGE_BTN_OK == key) + { + if (!tc && !abilitySecond) + { + if (abilityFirst) + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(1); - if (zone->cards.size() || (revealDisplay && !zone->cards.size())) - { - initDisplay(revealTopAmount); - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } + if (zone->cards.size() || (revealDisplay && !zone->cards.size())) + { + initDisplay(revealTopAmount); + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } - } - if (!tc && abilitySecond && abilitySecond->testDestroy()) - { - do - { - if (!RevealZone->cards.size()) - break; - MTGCardInstance * toMove = RevealZone->cards[0]; - if (toMove) - { - source->revealedLast = toMove; - MTGAbility * a = NEW AAMover(game, getMaxId(), source, toMove,"library", "Place on top"); - a->oneShot = true; - a->resolve(); - SAFE_DELETE(a); - } - } while (RevealZone->cards.size()); + } + if (!tc && abilitySecond && abilitySecond->testDestroy()) + { + do + { + if (!RevealZone->cards.size()) + break; + MTGCardInstance * toMove = RevealZone->cards[0]; + if (toMove) + { + source->revealedLast = toMove; + MTGAbility * a = NEW AAMover(game, getMaxId(), source, toMove,"library", "Place on top"); + a->oneShot = true; + a->resolve(); + SAFE_DELETE(a); + } + } while (RevealZone->cards.size()); - if (delayed) - { - MTGAbility * delayedA = contructAbility(delayedAbilityString); - if (delayedA->oneShot) - { - delayedA->resolve(); - SAFE_DELETE(delayedA); - } - else - delayedA->addToGame(); - - } - } - } - if (revealDisplay) - return revealDisplay->CheckUserInput(key); - return false; + if (delayed) + { + MTGAbility * delayedA = contructAbility(delayedAbilityString); + if (delayedA->oneShot) + { + delayedA->resolve(); + SAFE_DELETE(delayedA); + } + else + delayedA->addToGame(); + + } + } + } + if (revealDisplay) + return revealDisplay->CheckUserInput(key); + return false; } MTGScryCards * MTGScryCards::clone() const { - return NEW MTGScryCards(*this); + return NEW MTGScryCards(*this); } MTGScryCards::~MTGScryCards() { - for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) - SAFE_DELETE(*it); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - SAFE_DELETE(*it); + for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) + SAFE_DELETE(*it); + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + SAFE_DELETE(*it); } int MTGScryCards::receiveEvent(WEvent* e) { - if (WEventZoneChange* event = dynamic_cast(e)) - { - if (event->from == zone) - { - CardView* t; - if (event->card->view) - t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + if (WEventZoneChange* event = dynamic_cast(e)) + { + if (event->from == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); else t = NEW CardView(CardView::nullZone, event->card, (float)x, (float)y); - //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. - //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than - //they should be, possibly someone being to over cautious. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); + //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. + //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than + //they should be, possibly someone being to over cautious. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); return 1; - } - } - return 0; + } + } + return 0; } //scry wrapper GenericScryAbility::GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _howMany) : - ActivatedAbility(observer, id, source, NULL), howMany(_howMany) + Targetable * target, string _howMany) : + ActivatedAbility(observer, id, source, NULL), howMany(_howMany) { - this->GetId(); + this->GetId(); } int GenericScryAbility::resolve() { - MTGAbility * ability = NEW MTGScryCards(game, this->GetId(), source, howMany); - ability->addToGame(); - return 1; + MTGAbility * ability = NEW MTGScryCards(game, this->GetId(), source, howMany); + ability->addToGame(); + return 1; } const string GenericScryAbility::getMenuText() { - return "Scry Cards"; + return "Scry Cards"; } GenericScryAbility * GenericScryAbility::clone() const { - GenericScryAbility * a = NEW GenericScryAbility(*this); - return a; + GenericScryAbility * a = NEW GenericScryAbility(*this); + return a; } GenericScryAbility::~GenericScryAbility() { - //SAFE_DELETE(ability); + //SAFE_DELETE(ability); } //////////////////////// @@ -1319,7 +1319,6 @@ int AACopier::resolve() MTGCard* clone = MTGCollection()->getCardById(_target->copiedID); MTGCardInstance * myClone = NEW MTGCardInstance(clone, source->controller()->game); source->copy(myClone); - SAFE_DELETE(myClone); source->isACopier = true; source->copiedID = _target->getMTGId(); source->modifiedbAbi = _target->modifiedbAbi; @@ -2184,9 +2183,9 @@ int GenericPaidAbility::resolve() } else { - //dangerous code below, parse a string line that might not exist. baseAbilityStrSplit[0] - //you either have a string and do stuff, or dont and leave the ability - //not fixing this since its been heavily modified from the orginal implementation. + //dangerous code below, parse a string line that might not exist. baseAbilityStrSplit[0] + //you either have a string and do stuff, or dont and leave the ability + //not fixing this since its been heavily modified from the orginal implementation. nomenu = true; baseAbility = Af.parseMagicLine(baseAbilityStrSplit[0], this->GetId(), NULL, source); baseAbility->target = target; @@ -2381,7 +2380,7 @@ int AAEPIC::resolve() MTGCardInstance * _target = (MTGCardInstance *)target; if(FField) _target->controller()->forcefield = 1; - else + else _target->controller()->epic = 1; return 1; } @@ -2733,7 +2732,7 @@ AAFrozen::AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCa ActivatedAbility(observer, id, card, _cost, 0) { target = _target; - freeze = tap; + freeze = tap; } int AAFrozen::resolve() @@ -2743,10 +2742,10 @@ int AAFrozen::resolve() { while (_target->next) _target = _target->next; //This is for cards such as rampant growth - if (freeze) - { - _target->tap();//easier to manage for cards that allow you to tap and also freeze. - } + if (freeze) + { + _target->tap();//easier to manage for cards that allow you to tap and also freeze. + } _target->frozen += 1; } return 1; @@ -3887,13 +3886,13 @@ int AAMover::resolve() delete spell; return 1; } - if (destZone == game->players[i]->game->graveyard && fromZone == game->players[i]->game->hand) - { - //movers that take a card from hand and place them in graveyard are always discards. we send an event for it here. + if (destZone == game->players[i]->game->graveyard && fromZone == game->players[i]->game->hand) + { + //movers that take a card from hand and place them in graveyard are always discards. we send an event for it here. - WEvent * e = NEW WEventCardDiscard(_target); - game->receiveEvent(e); - } + WEvent * e = NEW WEventCardDiscard(_target); + game->receiveEvent(e); + } } @@ -4301,36 +4300,36 @@ AARemoveMana::~AARemoveMana() //Bestow ABestow::ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) : - ActivatedAbility(observer, id, card, _cost, 0) + ActivatedAbility(observer, id, card, _cost, 0) { - target = _target; - aType = MTGAbility::TAPPER; - _card = card; + target = _target; + aType = MTGAbility::TAPPER; + _card = card; } int ABestow::resolve() { - if (target) - { - if (_card->hasType("creature")) - { - _card->removeType("creature"); - _card->addType("aura"); - } - _card->target = (MTGCardInstance*)target; - _card->isBestowed = true; - } - return 1; + if (target) + { + if (_card->hasType("creature")) + { + _card->removeType("creature"); + _card->addType("aura"); + } + _card->target = (MTGCardInstance*)target; + _card->isBestowed = true; + } + return 1; } const string ABestow::getMenuText() { - return "Bestow"; + return "Bestow"; } ABestow * ABestow::clone() const { - return NEW ABestow(*this); + return NEW ABestow(*this); } //Tapper @@ -4415,48 +4414,48 @@ AAWhatsMax * AAWhatsMax::clone() const } //set X value AAWhatsX::AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, int value, MTGAbility * _costRule) : - ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) + ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) { } int AAWhatsX::resolve() { - if (source) - { - source->setX = value; - - } - costRule->reactToClick(source); - return 1; + if (source) + { + source->setX = value; + + } + costRule->reactToClick(source); + return 1; } AAWhatsX * AAWhatsX::clone() const { - return NEW AAWhatsX(*this); + return NEW AAWhatsX(*this); } //count objects on field before doing an effect AACountObject::AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, ManaCost * _cost, string value) : - ActivatedAbility(observer, id, card, _cost, 0), value(value) + ActivatedAbility(observer, id, card, _cost, 0), value(value) { } int AACountObject::resolve() { - if (source) - { - int amount = 0; - WParsedInt * use = NEW WParsedInt(value, NULL, source); - amount = use->getValue(); - source->CountedObjects = amount; - SAFE_DELETE(use); - } - return 1; + if (source) + { + int amount = 0; + WParsedInt * use = NEW WParsedInt(value, NULL, source); + amount = use->getValue(); + source->CountedObjects = amount; + SAFE_DELETE(use); + } + return 1; } AACountObject * AACountObject::clone() const { - return NEW AACountObject(*this); + return NEW AACountObject(*this); } // Win Game @@ -4750,16 +4749,16 @@ void MenuAbility::Update(float dt) { if(game->mExtraPayment->isPaymentSet() && game->mExtraPayment->canPay() ) { - if (game->mExtraPayment->costs.size()) - { - if (game->mExtraPayment->costs[0]->costToPay) - { - ManaCost * diff = game->mExtraPayment->costs[0]->costToPay; - ManaCost * c = source->controller()->getManaPool()->Diff(diff); - source->X = c->getCost(Constants::NB_Colors); - delete c; - } - } + if (game->mExtraPayment->costs.size()) + { + if (game->mExtraPayment->costs[0]->costToPay) + { + ManaCost * diff = game->mExtraPayment->costs[0]->costToPay; + ManaCost * c = source->controller()->getManaPool()->Diff(diff); + source->X = c->getCost(Constants::NB_Colors); + delete c; + } + } game->mExtraPayment->doPay(); game->mLayers->actionLayer()->reactToClick(game->mExtraPayment->action, game->mExtraPayment->source); @@ -5013,7 +5012,7 @@ MultiAbility * MultiAbility::clone() const a->abilities.clear(); for (size_t i = 0; i < abilities.size(); ++i) { - if(abilities[i]) + if(abilities[i]) a->abilities.push_back(abilities[i]->clone()); } return a; @@ -6134,7 +6133,6 @@ int AProduceMana::produce() { AManaProducer *amp = NEW AManaProducer(game, game->mLayers->actionLayer()->getMaxId(), source, source->controller(), ManaCost::parseManaCost(ManaDescription,NULL,source), NULL, 0,"",false); amp->resolve(); - SAFE_DELETE(amp);//once you call resolve() on a ability, you can safely delete it. } return 1; } @@ -6613,108 +6611,108 @@ AShackleWrapper::~AShackleWrapper() //grant AGrant::AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : - MTGAbility(observer, _id, card) + MTGAbility(observer, _id, card) { - Granted = _Grant; - target = _target; - Blessed = NULL; - resolved = false; - toGrant = NULL; + Granted = _Grant; + target = _target; + Blessed = NULL; + resolved = false; + toGrant = NULL; } void AGrant::Update(float dt) { - if (resolved == false) - { - resolved = true; - resolveGrant(); - } + if (resolved == false) + { + resolved = true; + resolveGrant(); + } - if (!source->isTapped() || !source->isInPlay(game)) - { - if (Blessed == NULL || !Blessed->isInPlay(game)) - MTGAbility::Update(dt); - MTGCardInstance * _target = Blessed; - removeGranted(_target); - } - else - resolveGrant(); - MTGAbility::Update(dt); + if (!source->isTapped() || !source->isInPlay(game)) + { + if (Blessed == NULL || !Blessed->isInPlay(game)) + MTGAbility::Update(dt); + MTGCardInstance * _target = Blessed; + removeGranted(_target); + } + else + resolveGrant(); + MTGAbility::Update(dt); } void AGrant::resolveGrant() { - if (toGrant) return; - MTGCardInstance * _target = (MTGCardInstance *)target; - if (_target) - { - toGrant = Granted->clone(); - toGrant->target = _target; - toGrant->addToGame(); - Blessed = _target; - } + if (toGrant) return; + MTGCardInstance * _target = (MTGCardInstance *)target; + if (_target) + { + toGrant = Granted->clone(); + toGrant->target = _target; + toGrant->addToGame(); + Blessed = _target; + } } void AGrant::removeGranted(MTGCardInstance* _target) { - if (!toGrant) return; - game->removeObserver(toGrant); - game->removeObserver(this); - Blessed = NULL; - return; + if (!toGrant) return; + game->removeObserver(toGrant); + game->removeObserver(this); + Blessed = NULL; + return; } int AGrant::resolve() { - return 0; + return 0; } const string AGrant::getMenuText() { - return Granted->getMenuText(); + return Granted->getMenuText(); } AGrant * AGrant::clone() const { - AGrant * a = NEW AGrant(*this); - a->forceDestroy = -1; - a->Granted = Granted->clone(); - return a; + AGrant * a = NEW AGrant(*this); + a->forceDestroy = -1; + a->Granted = Granted->clone(); + return a; }; AGrant::~AGrant() { - SAFE_DELETE(Granted); + SAFE_DELETE(Granted); } AGrantWrapper::AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : - InstantAbility(observer, _id, source, _target), Granted(_Grant) + InstantAbility(observer, _id, source, _target), Granted(_Grant) { - ability = NEW AGrant(observer, _id, card, _target,_Grant); + ability = NEW AGrant(observer, _id, card, _target,_Grant); } int AGrantWrapper::resolve() { - AGrant * a = ability->clone(); - a->target = target; - a->addToGame(); - return 1; + AGrant * a = ability->clone(); + a->target = target; + a->addToGame(); + return 1; } const string AGrantWrapper::getMenuText() { - return "Grant"; + return "Grant"; } AGrantWrapper * AGrantWrapper::clone() const { - AGrantWrapper * a = NEW AGrantWrapper(*this); - a->ability = this->ability->clone(); - a->oneShot = 1; - return a; + AGrantWrapper * a = NEW AGrantWrapper(*this); + a->ability = this->ability->clone(); + a->oneShot = 1; + return a; } AGrantWrapper::~AGrantWrapper() { - SAFE_DELETE(ability); + SAFE_DELETE(ability); } //a blink @@ -7324,8 +7322,8 @@ int AACastCard::resolveSpell() else copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack,noEvent); copy->changeController(source->controller(),true); - if(asNormalMadness) - copy->MadnessPlay = true; + if(asNormalMadness) + copy->MadnessPlay = true; } else { diff --git a/projects/mtg/src/Damage.cpp b/projects/mtg/src/Damage.cpp index b5a94633c..9177b442d 100644 --- a/projects/mtg/src/Damage.cpp +++ b/projects/mtg/src/Damage.cpp @@ -251,7 +251,7 @@ int Damage::resolve() target->lifeLostThisTurn += damage; if ( typeOfDamage == 1 && target == source->controller()->opponent() )//add vector prowledtypes. { - vector values = MTGAllCards::getCreatureValuesById();//getting a weird crash here. rarely. + vector values = MTGAllCards::getCreatureValuesById(); for (size_t i = 0; i < values.size(); ++i) { if ( source->hasSubtype( values[i] ) && find(source->controller()->prowledTypes.begin(), source->controller()->prowledTypes.end(), values[i])==source->controller()->prowledTypes.end() ) diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 2464aa980..693b232c2 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1057,115 +1057,208 @@ void GameObserver::Affinity() if (!card) continue; - /////////////////////////// - //reset extracost shadows// - /////////////////////////// - card->isExtraCostTarget = false; - if (mExtraPayment != NULL) - { - for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) + /////////////////////////// + //reset extracost shadows// + /////////////////////////// + card->isExtraCostTarget = false; + if (mExtraPayment != NULL) + { + for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) + { + + if (mExtraPayment->costs[ec]->tc) + { + vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + Targetable * cardMasked = *it; + dynamic_cast(cardMasked)->isExtraCostTarget = true; + } + + } + } + } + //////////////////////////// + bool NewAffinityFound = false; + for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) + { + if (!card->cardsAbilities[na]) + break; + ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); + if (newAff) + { + NewAffinityFound = true; + } + } + bool DoReduceIncrease = false; + if (card->has(Constants::AFFINITYARTIFACTS) || + card->has(Constants::AFFINITYFOREST) || + card->has(Constants::AFFINITYGREENCREATURES) || + card->has(Constants::AFFINITYISLAND) || + card->has(Constants::AFFINITYMOUNTAIN) || + card->has(Constants::AFFINITYPLAINS) || + card->has(Constants::AFFINITYSWAMP) || + card->has(Constants::TRINISPHERE) || + card->getIncreasedManaCost()->getConvertedCost() || + card->getReducedManaCost()->getConvertedCost() || + NewAffinityFound) + DoReduceIncrease = true; + if (!DoReduceIncrease) + continue; + //above we check if there are even any cards that effect cards manacost + //if there are none, leave this function. manacost->copy( is a very expensive funtion + //1mb a sec to run at all time even when no known reducers or increasers are in play. + //memory snapshot shots pointed to this as such a heavy load that games with many cards inplay + //would slow to a crawl. + //only do any of the following if a card with the stated ability is in your hand. + int color = 0; + string type = ""; + + ManaCost * original = NEW ManaCost(); + original->copy(card->model->data->getManaCost()); + if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost()) + {//start1 + if(card->getIncreasedManaCost()->getConvertedCost()) + original->add(card->getIncreasedManaCost()); + if(card->getReducedManaCost()->getConvertedCost()) + original->remove(card->getReducedManaCost()); + if(card->getManaCost()) + card->getManaCost()->copy(original); + if(card->getManaCost()->extraCosts) { - - if (mExtraPayment->costs[ec]->tc) + for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) { - vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - Targetable * cardMasked = *it; - dynamic_cast(cardMasked)->isExtraCostTarget = true; - } - + card->getManaCost()->extraCosts->costs[i]->setSource(card); } } - } - //////////////////////////// - bool NewAffinityFound = false; - for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) - { - if (!card->cardsAbilities[na]) - break; + }//end1 + int reducem = 0; + bool resetCost = false; + for(unsigned int na = 0; na < card->cardsAbilities.size();na++) + {//start2 + if (!card->cardsAbilities[na]) + break; ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if (newAff) + if(newAff) { - NewAffinityFound = true; + if(!resetCost) + { + resetCost = true; + card->getManaCost()->copy(original); + if(card->getManaCost()->extraCosts) + { + for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + { + card->getManaCost()->extraCosts->costs[i]->setSource(card); + } + } + } + TargetChooserFactory tf(this); + TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); + + for (int w = 0; w < 2; ++w) + { + Player *p = this->players[w]; + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) + { + MTGGameZone * z = zones[k]; + if (tcn->targetsZone(z)) + { + reducem += z->countByCanTarget(tcn); + } + } + } + SAFE_DELETE(tcn); + ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); + for(int j = 0; j < reducem; j++) + card->getManaCost()->remove(removingCost); + SAFE_DELETE(removingCost); + } + }//end2 + if(card->has(Constants::AFFINITYARTIFACTS)|| + card->has(Constants::AFFINITYFOREST)|| + card->has(Constants::AFFINITYGREENCREATURES)|| + card->has(Constants::AFFINITYISLAND)|| + card->has(Constants::AFFINITYMOUNTAIN)|| + card->has(Constants::AFFINITYPLAINS)|| + card->has(Constants::AFFINITYSWAMP)) + {//start3 + if (card->has(Constants::AFFINITYARTIFACTS)) + { + type = "artifact"; + } + else if (card->has(Constants::AFFINITYSWAMP)) + { + type = "swamp"; + } + else if (card->has(Constants::AFFINITYMOUNTAIN)) + { + type = "mountain"; + } + else if (card->has(Constants::AFFINITYPLAINS)) + { + type = "plains"; + } + else if (card->has(Constants::AFFINITYISLAND)) + { + type = "island"; + } + else if (card->has(Constants::AFFINITYFOREST)) + { + type = "forest"; + } + else if (card->has(Constants::AFFINITYGREENCREATURES)) + { + color = 1; + type = "creature"; + } + card->getManaCost()->copy(original); + if(card->getManaCost()->extraCosts) + { + for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++) + { + card->getManaCost()->extraCosts->costs[i]->setSource(card); + } + } + int reduce = 0; + if(card->has(Constants::AFFINITYGREENCREATURES)) + { + TargetChooserFactory tf(this); + TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); + reduce = card->controller()->game->battlefield->countByCanTarget(tc); + SAFE_DELETE(tc); + } + else + { + reduce = card->controller()->game->battlefield->countByType(type); + } + for(int i = 0; i < reduce;i++) + { + if(card->getManaCost()->getCost(color) > 0) + card->getManaCost()->remove(color,1); + } + }//end3 + //trinisphere... now how to implement kicker recomputation + + if(card->has(Constants::TRINISPHERE)) + { + for(int jj = card->getManaCost()->getConvertedCost(); jj < 3; jj++) + { + card->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1); + card->countTrini++; } } - bool DoReduceIncrease = false; - if (card->has(Constants::AFFINITYARTIFACTS) || - card->has(Constants::AFFINITYFOREST) || - card->has(Constants::AFFINITYGREENCREATURES) || - card->has(Constants::AFFINITYISLAND) || - card->has(Constants::AFFINITYMOUNTAIN) || - card->has(Constants::AFFINITYPLAINS) || - card->has(Constants::AFFINITYSWAMP) || - card->has(Constants::TRINISPHERE) || - card->getIncreasedManaCost()->getConvertedCost() || - card->getReducedManaCost()->getConvertedCost() || - NewAffinityFound) - DoReduceIncrease = true; - if (!DoReduceIncrease) - continue; - //above we check if there are even any cards that effect cards manacost - //if there are none, leave this function. manacost->copy( is a very expensive funtion - //1mb a sec to run at all time even when no known reducers or increasers are in play. - //memory snapshot shots pointed to this as such a heavy load that games with many cards inplay - //would slow to a crawl. - //only do any of the following if a card with the stated ability is in your hand. - //kicker is an addon to normal cost, suspend is not casting. add cost as needed EXACTLY as seen below. - card->getManaCost()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost())); - card->getManaCost()->copy(newCost); - SAFE_DELETE(newCost); - if (card->getManaCost()->getAlternative()) + else { - card->getManaCost()->getAlternative()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative())); - card->getManaCost()->getAlternative()->copy(newCost); - SAFE_DELETE(newCost); + if(card->countTrini) + { + card->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); + card->countTrini=0; + } } - if (card->getManaCost()->getBestow()) - { - card->getManaCost()->getBestow()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow())); - card->getManaCost()->getBestow()->copy(newCost); - SAFE_DELETE(newCost); - } - if (card->getManaCost()->getRetrace()) - { - card->getManaCost()->getRetrace()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace())); - card->getManaCost()->getRetrace()->copy(newCost); - SAFE_DELETE(newCost); - } - if (card->getManaCost()->getBuyback()) - { - card->getManaCost()->getBuyback()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback())); - card->getManaCost()->getBuyback()->copy(newCost); - SAFE_DELETE(newCost); - } - if (card->getManaCost()->getFlashback()) - { - card->getManaCost()->getFlashback()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback())); - card->getManaCost()->getFlashback()->copy(newCost); - SAFE_DELETE(newCost); - } - if (card->getManaCost()->getMorph()) - { - card->getManaCost()->getMorph()->resetCosts(); - ManaCost * newCost = NEW ManaCost(); - newCost->copy(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph())); - card->getManaCost()->getMorph()->copy(newCost); - SAFE_DELETE(newCost); - } - + + SAFE_DELETE(original); }//end } } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 3cea0730c..c8d800eec 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -69,8 +69,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to cardistargetted = 0; cardistargetter = 0; myconvertedcost = getManaCost()->getConvertedCost(); - revealedLast = NULL; - MadnessPlay = false; + revealedLast = NULL; + MadnessPlay = false; } MTGCardInstance * MTGCardInstance::createSnapShot() @@ -153,14 +153,14 @@ int MTGCardInstance::init() data = this; X = 0; castX = 0; - setX = -1; + setX = -1; return 1; } void MTGCardInstance::initMTGCI() { X = 0; - setX = -1; + setX = -1; sample = ""; model = NULL; isToken = false; @@ -198,7 +198,7 @@ void MTGCardInstance::initMTGCI() wasDealtDamage = false; isDualWielding = false; suspended = false; - isBestowed = false; + isBestowed = false; castMethod = Constants::NOT_CAST; mPropertiesChangedSinceLastUpdate = false; stillNeeded = true; @@ -228,7 +228,7 @@ void MTGCardInstance::initMTGCI() imprintW = 0; currentimprintName = ""; imprintedNames.clear(); - CountedObjects = 0; + CountedObjects = 0; for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++) alternateCostPaid[i] = 0; @@ -782,8 +782,8 @@ int MTGCardInstance::getCurrentToughness() //check stack bool MTGCardInstance::StackIsEmptyandSorcerySpeed() { - Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. - Player * whoCurrent = getObserver()->currentPlayer; + Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. + Player * whoCurrent = getObserver()->currentPlayer; if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) && (getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) && @@ -961,156 +961,121 @@ JQuadPtr MTGCardInstance::getIcon() return WResourceManager::Instance()->RetrieveCard(this, CACHE_THUMB); } -ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cost, ManaCost * Data, bool noTrinisphere) +ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * newCost, ManaCost * refCost, bool noTrinisphere) { - int color = 0; - string type = ""; - ManaCost * original = NEW ManaCost(); - original->copy(Data); - if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost()) - {//start1 - if (card->getIncreasedManaCost()->getConvertedCost()) - original->add(card->getIncreasedManaCost()); - if (card->getReducedManaCost()->getConvertedCost()) - original->remove(card->getReducedManaCost()); - - Cost->copy(original); - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + if(!card) + return NULL; + + if(card->getIncreasedManaCost()->getConvertedCost()) + newCost->add(card->getIncreasedManaCost()); + if(card->getReducedManaCost()->getConvertedCost()) + newCost->remove(card->getReducedManaCost()); + if(refCost->extraCosts) + newCost->extraCosts = refCost->extraCosts; + //affinity + int color = 0; + string type = ""; + ManaCost * original = NEW ManaCost(); + original->copy(newCost); + + int reducem = 0; + bool resetCost = false; + for(unsigned int na = 0; na < card->cardsAbilities.size();na++) + {//start2 + ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); + if(newAff) { - Cost->extraCosts->costs[i]->setSource(card); - } - } - }//end1 - int reducem = 0; - bool resetCost = false; - for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) - {//start2 - if (!card->cardsAbilities[na]) - break; - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if (newAff) - { - if (!resetCost) - { - resetCost = true; - Cost->copy(original); - if (Cost->extraCosts) + if(!resetCost) { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + resetCost = true; + newCost->copy(original); + } + TargetChooserFactory tf(observer); + TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL); + + for (int w = 0; w < 2; ++w) + { + Player *p = observer->players[w]; + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) { - Cost->extraCosts->costs[i]->setSource(card); + MTGGameZone * z = zones[k]; + if (tcn->targetsZone(z)) + reducem += z->countByCanTarget(tcn); } } + SAFE_DELETE(tcn); + ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); + for(int j = 0; j < reducem; j++) + newCost->remove(removingCost); + SAFE_DELETE(removingCost); } - TargetChooserFactory tf(getObserver()); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL); - - for (int w = 0; w < 2; ++w) - { - Player *p = getObserver()->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) + }//end2 + if(card->has(Constants::AFFINITYARTIFACTS)|| + card->has(Constants::AFFINITYFOREST)|| + card->has(Constants::AFFINITYGREENCREATURES)|| + card->has(Constants::AFFINITYISLAND)|| + card->has(Constants::AFFINITYMOUNTAIN)|| + card->has(Constants::AFFINITYPLAINS)|| + card->has(Constants::AFFINITYSWAMP)) + {//start3 + if (card->has(Constants::AFFINITYARTIFACTS)) + type = "artifact"; + else if (card->has(Constants::AFFINITYSWAMP)) + type = "swamp"; + else if (card->has(Constants::AFFINITYMOUNTAIN)) + type = "mountain"; + else if (card->has(Constants::AFFINITYPLAINS)) + type = "plains"; + else if (card->has(Constants::AFFINITYISLAND)) + type = "island"; + else if (card->has(Constants::AFFINITYFOREST)) + type = "forest"; + else if (card->has(Constants::AFFINITYGREENCREATURES)) { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - { - reducem += z->countByCanTarget(tcn); - } + color = 1; + type = "creature"; } - } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for (int j = 0; j < reducem; j++) - original->remove(removingCost); - SAFE_DELETE(removingCost); - } - }//end2 - if (card->has(Constants::AFFINITYARTIFACTS) || - card->has(Constants::AFFINITYFOREST) || - card->has(Constants::AFFINITYGREENCREATURES) || - card->has(Constants::AFFINITYISLAND) || - card->has(Constants::AFFINITYMOUNTAIN) || - card->has(Constants::AFFINITYPLAINS) || - card->has(Constants::AFFINITYSWAMP)) - {//start3 - if (card->has(Constants::AFFINITYARTIFACTS)) + newCost->copy(original); + int reduce = 0; + if(card->has(Constants::AFFINITYGREENCREATURES)) + { + TargetChooserFactory tf(observer); + TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); + reduce = card->controller()->game->battlefield->countByCanTarget(tc); + SAFE_DELETE(tc); + } + else + reduce = card->controller()->game->battlefield->countByType(type); + for(int i = 0; i < reduce;i++) + if(newCost->getCost(color) > 0) + newCost->remove(color,1); + }//end3 + + if(!noTrinisphere) + { + //trinisphere... now how to implement kicker recomputation + if(card->has(Constants::TRINISPHERE)) { - type = "artifact"; - } - else if (card->has(Constants::AFFINITYSWAMP)) - { - type = "swamp"; - } - else if (card->has(Constants::AFFINITYMOUNTAIN)) - { - type = "mountain"; - } - else if (card->has(Constants::AFFINITYPLAINS)) - { - type = "plains"; - } - else if (card->has(Constants::AFFINITYISLAND)) - { - type = "island"; - } - else if (card->has(Constants::AFFINITYFOREST)) - { - type = "forest"; - } - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - - Cost->copy(original); - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + for(int jj = newCost->getConvertedCost(); jj < 3; jj++) { - Cost->extraCosts->costs[i]->setSource(card); + newCost->add(Constants::MTG_COLOR_ARTIFACT, 1); + card->countTrini++; } } - int reduce = 0; - if (card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(getObserver()); - TargetChooser * tc = tf.createTargetChooser("creature[green]", NULL); - reduce = card->controller()->game->battlefield->countByCanTarget(tc); - SAFE_DELETE(tc); - } else { - reduce = card->controller()->game->battlefield->countByType(type); + if(card->countTrini) + { + newCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); + card->countTrini=0; + } } - for (int i = 0; i < reduce; i++) - { - if (Cost->getCost(color) > 0) - Cost->remove(color, 1); - } - }//end3 - //trinisphere... now how to implement kicker recomputation + } - if (card->has(Constants::TRINISPHERE)) - { - for (int jj = Cost->getConvertedCost(); jj < 3; jj++) - { - Cost->add(Constants::MTG_COLOR_ARTIFACT, 1); - card->countTrini++; - } - } - else - { - if (card->countTrini) - { - Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); - card->countTrini = 0; - } - } SAFE_DELETE(original); - return Cost; + + return newCost; } MTGCardInstance * MTGCardInstance::getNextPartner() diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index fbb74087c..d9f77b0e6 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -49,10 +49,6 @@ PermanentAbility(observer, _id) Angel[i] = 0; dragonbonusgranted[i] = false; dragon[i] = 0; - eldrazibonusgranted[i] = false; - eldrazi[i] = 0; - werewolfbonusgranted[i] = false; - werewolf[i] = 0; } } @@ -175,10 +171,6 @@ int MTGEventBonus::receiveEvent(WEvent * event) Angel[currentPlayer->getId()]++; if(e->card->hasType("dragon")||e->card->hasType("wurm")||e->card->hasType("drake")||e->card->hasType("snake")||e->card->hasType("hydra")) dragon[currentPlayer->getId()]++; - if (e->card->hasType("eldrazi")) - eldrazi[currentPlayer->getId()]++; - if (e->card->hasType("werewolf") || e->card->hasType("wolf")) - werewolf[currentPlayer->getId()]++; } if(toys[currentPlayer->getId()] > 30 && !toybonusgranted[currentPlayer->getId()]) { @@ -236,16 +228,6 @@ int MTGEventBonus::receiveEvent(WEvent * event) grantAward("Teeth And Scales!",300); dragonbonusgranted[currentPlayer->getId()] = true; } - if (eldrazi[currentPlayer->getId()] > 30 && !eldrazibonusgranted[currentPlayer->getId()]) - { - grantAward("Colorblind!", 300); - eldrazibonusgranted[currentPlayer->getId()] = true; - } - if (werewolf[currentPlayer->getId()] > 30 && !werewolfbonusgranted[currentPlayer->getId()]) - { - grantAward("Full Moon!", 300); - werewolfbonusgranted[currentPlayer->getId()] = true; - } } } //bonus for dealing 100+ damage from a single source @@ -383,65 +365,65 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) return 0; Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); - ManaCost * playerMana = player->getManaPool(); - ///////announce X cost/////// - if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) - { - vectorselection; - int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; - //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would - //give me the correct amount sorry. - for (int i = 0; i < options; ++i) - { + ManaCost * playerMana = player->getManaPool(); + ///////announce X cost/////// + if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { - MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); - MTGAbility * setCardX = setX->clone(); - setCardX->oneShot = true; - selection.push_back(setCardX); - SAFE_DELETE(setX); - } - if (selection.size()) - { - MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); - game->mLayers->actionLayer()->currentActionCard = card; - a1->resolve(); - } - return 0; - } - /////////////////////////////////////////////////////////////////////////////////////// - //////X is set, below we set sunburst for X if needed and cast or reset the card.////// - //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// - //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// - //////and the value of X isn’t defined by the text of that spell or ability, the ////// - //////controller of that spell or ability chooses and announces the value of X as////// - //////part of casting the spell or activating the ability. ////// - //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// - //////its mana cost or in any alternative cost or additional cost it has equals ////// - //////the announced value.While an activated ability is on the stack, any X in ////// - //////its activation cost equals the announced value. ////// - /////////////////////////////////////////////////////////////////////////////////////// - if (card->setX > -1) - { - ManaCost * Xcost = NEW ManaCost(); - Xcost->copy(cost); - Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); - Xcost->remove(7, 1); - if (playerMana->canAfford(Xcost)) - { - cost->copy(Xcost); - SAFE_DELETE(Xcost); - } - else - { - if (card->setX > -1) - card->setX = -1; - SAFE_DELETE(Xcost); - return 0; - } - } - ////////////////////////////////////////// - ////cards without X contenue from here//// - ////////////////////////////////////////// + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(cost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1); + if (playerMana->canAfford(Xcost)) + { + cost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } + ////////////////////////////////////////// + ////cards without X contenue from here//// + ////////////////////////////////////////// //this handles extra cost payments at the moment a card is played. if (cost->isExtraPaymentSet()) { @@ -456,7 +438,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) game->mExtraPayment = cost->extraCosts; return 0; } - + ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); int payResult = player->getManaPool()->pay(card->getManaCost()); if (card->getManaCost()->getKicker() && (OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number || card->controller()->isAI())) @@ -570,9 +552,9 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *) ManaCost * withKickerCost= NEW ManaCost(card->getManaCost()); withKickerCost->add(card->getManaCost()->getKicker()); //cost reduction/recalculation must be here or outside somehow... - //no recalculations beyound this point, reactToClick is the function that - //happens only with the assumption that you could actually pay for it, any calculations after will - //have negitive effects. this function is basically "can i play this card?" + //no recalculations beyound this point, reactToClick is the function that + //happens only with the assumption that you could actually pay for it, any calculations after will + //have negitive effects. this function is basically "can i play this card?" #ifdef WIN32 withKickerCost->Dump(); #endif @@ -709,7 +691,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * return 0;//overload has its own rule if(!card->getManaCost()->getAlternative()) return 0; - ManaCost * alternateCost = card->getManaCost()->getAlternative(); + ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative()); if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) { @@ -773,7 +755,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card) if ( !isReactingToClick(card)) return 0; - ManaCost * alternateCost = card->getManaCost()->getAlternative(); + ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative()); card->paymenttype = MTGAbility::ALTERNATIVE_COST; if(alternateCost->extraCosts) for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++) @@ -787,61 +769,61 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter Player * player = game->currentlyActing(); ManaPool * playerMana = player->getManaPool(); - ///////announce X cost/////// - if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) - { - vectorselection; - int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; - //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would - //give me the correct amount sorry. - for (int i = 0; i < options; ++i) - { + ///////announce X cost/////// + if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { - MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); - MTGAbility * setCardX = setX->clone(); - setCardX->oneShot = true; - selection.push_back(setCardX); - SAFE_DELETE(setX); - } - if (selection.size()) - { - MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); - game->mLayers->actionLayer()->currentActionCard = card; - a1->resolve(); - } - return 0; - } - /////////////////////////////////////////////////////////////////////////////////////// - //////X is set, below we set sunburst for X if needed and cast or reset the card.////// - //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// - //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// - //////and the value of X isn’t defined by the text of that spell or ability, the ////// - //////controller of that spell or ability chooses and announces the value of X as////// - //////part of casting the spell or activating the ability. ////// - //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// - //////its mana cost or in any alternative cost or additional cost it has equals ////// - //////the announced value.While an activated ability is on the stack, any X in ////// - //////its activation cost equals the announced value. ////// - /////////////////////////////////////////////////////////////////////////////////////// - if (card->setX > -1) - { - ManaCost * Xcost = NEW ManaCost(); - Xcost->copy(alternateCost); - Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); - Xcost->remove(7, 1);//remove the X - if (playerMana->canAfford(Xcost)) - { - alternateCost->copy(Xcost); - SAFE_DELETE(Xcost); - } - else - { - if (card->setX > -1) - card->setX = -1; - SAFE_DELETE(Xcost); - return 0; - } - } + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(alternateCost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1);//remove the X + if (playerMana->canAfford(Xcost)) + { + alternateCost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } //this handles extra cost payments at the moment a card is played. @@ -898,7 +880,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter { ManaCost * c = spellCost->Diff(alternateCost); - copy->X = card->setX; + copy->X = card->setX; copy->castX = copy->X; delete c; } @@ -942,7 +924,7 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getBuyback()) return 0; - ManaCost * buybackCost = card->getManaCost()->getBuyback(); + ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback()); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -956,7 +938,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * buybackCost = card->getManaCost()->getBuyback(); + ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback()); if(buybackCost->extraCosts) for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++) { @@ -996,7 +978,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) return 0; if(!card->getManaCost()->getFlashback()) return 0; - ManaCost * flashbackCost = card->getManaCost()->getFlashback(); + ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback()); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1007,7 +989,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGFlashBackRule::reactToClick(MTGCardInstance * card) { - ManaCost * flashbackCost = card->getManaCost()->getFlashback(); + ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback()); if(flashbackCost->extraCosts) for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++) { @@ -1049,17 +1031,17 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) Player * player = game->currentlyActing(); if(!card->getManaCost()->getRetrace()) return 0; - if (!player->game->graveyard->hasCard(card)) - { - return 0; - } - auto retraceCost = card->getManaCost()->getRetrace(); + ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace()); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { retraceCost->extraCosts->costs[i]->setSource(card); - } - return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost); + } + + if (!player->game->graveyard->hasCard(card)) + return 0; + + return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost ); } @@ -1068,7 +1050,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card) if (!isReactingToClick(card)) return 0; - ManaCost * retraceCost = card->getManaCost()->getRetrace(); + ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace()); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1245,7 +1227,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY) return 0; ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->getManaCost()->getMorph(); + ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph()); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1274,7 +1256,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card) Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); ManaCost * playerMana = player->getManaPool(); - ManaCost * morph = card->getManaCost()->getMorph(); + ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph()); if(morph->extraCosts) for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++) { @@ -1364,26 +1346,23 @@ MTGAlternativeCostRule(observer, _id) int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if (!card->has(Constants::PAYZERO)) + if(!card->has(Constants::PAYZERO)) return 0; Player * player = game->currentlyActing(); - if (card->isLand() || (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))) - { - //only allowed to pay zero for cards in library??? above is "if you dont have it in hand, grave, or exile" - return 0; - } - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - { - return 0; - } - ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); - ManaCost * newCost = card->computeNewCost(card, cost, cost); - SAFE_DELETE(cost); - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL)); + ManaCost * newCost = card->computeNewCost(card,cost,cost); + if(newCost->extraCosts) + for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { newCost->extraCosts->costs[i]->setSource(card); } + + if(card->isLand()) + return 0; + if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) + return 0; + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + return 0; if(card->has(Constants::CANPLAYFROMGRAVEYARD)) CustomName = "Zero Cast From Graveyard"; else if(card->has(Constants::CANPLAYFROMEXILE)) @@ -1433,26 +1412,22 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { if (!card->has(Constants::OVERLOAD)) return 0; - if (card->isLand()) - { - return 0; - } - Player * player = card->controller(); - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) - { - return 0; - } - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - { - return 0; - } - ManaCost * newCost = card->getManaCost()->getAlternative(); + Player * player = game->currentlyActing(); + ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); + ManaCost * newCost = card->computeNewCost(card,cost,cost); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { newCost->extraCosts->costs[i]->setSource(card); } + if (card->isLand()) + return 0; + if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) + return 0; + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + return 0; + return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } @@ -1462,7 +1437,7 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card) return 0; ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative()); - ManaCost * newCost = card->getManaCost()->getAlternative(); + ManaCost * newCost = card->computeNewCost(card,cost,cost); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) { @@ -1487,64 +1462,64 @@ MTGOverloadRule * MTGOverloadRule::clone() const /////////////////////////////////////////////////////////////////////////////////////////////////// //bestow MTGBestowRule::MTGBestowRule(GameObserver* observer, int _id) : - MTGAlternativeCostRule(observer, _id) + MTGAlternativeCostRule(observer, _id) { - aType = MTGAbility::BESTOW_COST; + aType = MTGAbility::BESTOW_COST; } int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if (!card->model) - return 0; - if (!card->model->data->getManaCost()->getBestow()) - return 0; - if (card->isInPlay(game)) - return 0; - if (card->isLand()) - { - return 0; - } - if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) - { - return 0; - } - ManaCost * newCost = card->getManaCost()->getBestow(); - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } - return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); + if (!card->model) + return 0; + //Player * player = game->currentlyActing(); + if (!card->model->data->getManaCost()->getBestow()) + return 0; + if (card->isInPlay(game)) + return 0; + ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow()); + ManaCost * newCost = card->computeNewCost(card, cost, cost); + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } + SAFE_DELETE(cost); + if (card->isLand()) + return 0; + if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) + return 0; + return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } int MTGBestowRule::reactToClick(MTGCardInstance * card) { - if (!isReactingToClick(card)) - return 0; - //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash - //TODO::::we need to get to the source of this leak and fix it. - ManaCost * newCost = card->getManaCost()->getBestow(); - - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } + if (!isReactingToClick(card)) + return 0; + //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash + //TODO::::we need to get to the source of this leak and fix it. + ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow()); + ManaCost * newCost = card->computeNewCost(card, cost, cost); + + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } - card->paymenttype = MTGAbility::BESTOW_COST; - card->spellTargetType = "creature|battlefield"; - return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false); + card->paymenttype = MTGAbility::BESTOW_COST; + card->spellTargetType = "creature|battlefield"; + return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false); } ostream& MTGBestowRule::toString(ostream& out) const { - out << "MTGBestowRule ::: ("; - return MTGAbility::toString(out) << ")"; + out << "MTGBestowRule ::: ("; + return MTGAbility::toString(out) << ")"; } MTGBestowRule * MTGBestowRule::clone() const { - return NEW MTGBestowRule(*this); + return NEW MTGBestowRule(*this); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1735,19 +1710,19 @@ int MTGAttackRule::receiveEvent(WEvent *e) for (int i = 0; i < z->nb_cards; i++) { MTGCardInstance * card = z->cards[i]; - if (card->isAttacker() && card->has(Constants::NOSOLO)) - { - TargetChooserFactory tf(game); - TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL); - int Check = card->controller()->game->battlefield->countByCanTarget(tc); - if (Check <2) - card->initAttackersDefensers(); - } - if (card->isAttacker() && card->has(Constants::DETHRONE)) - { - if (p->opponent()->life >= p->life) - card->counters->addCounter(1, 1); - } + if (card->isAttacker() && card->has(Constants::NOSOLO)) + { + TargetChooserFactory tf(game); + TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL); + int Check = card->controller()->game->battlefield->countByCanTarget(tc); + if (Check <2) + card->initAttackersDefensers(); + } + if (card->isAttacker() && card->has(Constants::DETHRONE)) + { + if (p->opponent()->life >= p->life) + card->counters->addCounter(1, 1); + } if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn. reactToClick(card); if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI()) @@ -2061,49 +2036,49 @@ PermanentAbility(observer, _id) int MTGBlockRule::receiveEvent(WEvent *e) { - if (dynamic_cast(e)) - {//do not refactor, these are keep seperate for readability. - Player * p = game->currentPlayer; + if (dynamic_cast(e)) + {//do not refactor, these are keep seperate for readability. + Player * p = game->currentPlayer; - vector Attacker; - MTGGameZone * k = p->game->inPlay; - for (int i = 0; i < k->nb_cards; i++) - { - MTGCardInstance * card = k->cards[i]; - if (card->isAttacker()) - { - Attacker.push_back(card); - } - } - //force cards that must block, to block whatever is first found. players have a chance to set thier own - //but if ignored we do it for them. - if (Attacker.size()) - { - MTGGameZone * tf = p->opponent()->game->inPlay; - for (size_t i = 0; i < tf->cards.size(); i++) - { - MTGCardInstance * card = tf->cards[i]; - if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock()) - {//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them - //unassigned as a block. - for (size_t i = 0; i < Attacker.size(); i++) - { - if (card->canBlock(Attacker[i]) && !card->defenser) - { - blocker = NEW AABlock(card->getObserver(), -1, card, NULL); - blocker->oneShot = true; - blocker->forceDestroy = 1; - blocker->canBeInterrupted = false; - blocker->target = Attacker[i]; - blocker->resolve(); - SAFE_DELETE(blocker); - } - } + vector Attacker; + MTGGameZone * k = p->game->inPlay; + for (int i = 0; i < k->nb_cards; i++) + { + MTGCardInstance * card = k->cards[i]; + if (card->isAttacker()) + { + Attacker.push_back(card); + } + } + //force cards that must block, to block whatever is first found. players have a chance to set thier own + //but if ignored we do it for them. + if (Attacker.size()) + { + MTGGameZone * tf = p->opponent()->game->inPlay; + for (size_t i = 0; i < tf->cards.size(); i++) + { + MTGCardInstance * card = tf->cards[i]; + if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock()) + {//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them + //unassigned as a block. + for (size_t i = 0; i < Attacker.size(); i++) + { + if (card->canBlock(Attacker[i]) && !card->defenser) + { + blocker = NEW AABlock(card->getObserver(), -1, card, NULL); + blocker->oneShot = true; + blocker->forceDestroy = 1; + blocker->canBeInterrupted = false; + blocker->target = Attacker[i]; + blocker->resolve(); + SAFE_DELETE(blocker); + } + } - } - } + } + } - } + } if (dynamic_cast(e)) { @@ -2123,23 +2098,23 @@ int MTGBlockRule::receiveEvent(WEvent *e) } } - //if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal. - MTGGameZone * z = p->game->inPlay; - for (int i = 0; i < z->nb_cards; i++) - { - MTGCardInstance * card = z->cards[i]; - if (card->has(Constants::MENACE) && card->blockers.size() < 2) - { - while (card->blockers.size()) - { - MTGCardInstance * blockingCard = card->blockers.front(); - blockingCard->toggleDefenser(NULL); - - } - } - } + //if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal. + MTGGameZone * z = p->game->inPlay; + for (int i = 0; i < z->nb_cards; i++) + { + MTGCardInstance * card = z->cards[i]; + if (card->has(Constants::MENACE) && card->blockers.size() < 2) + { + while (card->blockers.size()) + { + MTGCardInstance * blockingCard = card->blockers.front(); + blockingCard->toggleDefenser(NULL); + + } + } + } - } + } return 1; @@ -2902,7 +2877,6 @@ int MTGPersistRule::receiveEvent(WEvent * event) } AAMover *putinplay = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), copy, copy,"ownerbattlefield",code,NULL,undying,persist); putinplay->oneShot = true; - game->mLayers->actionLayer()->garbage.push_back(putinplay); putinplay->fireAbility(); return 1; } diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index cfb5a4caf..de9991d65 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -153,7 +153,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'e': - //Exile + //Exile manaCost->addExtraCost(NEW ExileTargetCost(tc)); break; case 'h': //bounce (move to Hand) @@ -179,12 +179,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'd': //DiscardRandom cost - if (value.find("delve") != string::npos) - { - if(!tc) - tc = tcf.createTargetChooser("*|mygraveyard", c); - manaCost->addExtraCost(NEW Delve(tc)); - } + if (value.find("delve") != string::npos) + { + if(!tc) + tc = tcf.createTargetChooser("*|mygraveyard", c); + manaCost->addExtraCost(NEW Delve(tc)); + } else if (value == "d") { manaCost->addExtraCost(NEW DiscardRandomCost(tc)); @@ -259,12 +259,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan break; case 'c': //Counters or cycle { - if (value.find("convoke") != string::npos) - { - if (!tc) - tc = tcf.createTargetChooser("creature|mybattlefield", c); - manaCost->addExtraCost(NEW Convoke(tc)); - } + if (value.find("convoke") != string::npos) + { + if (!tc) + tc = tcf.createTargetChooser("creature|mybattlefield", c); + manaCost->addExtraCost(NEW Convoke(tc)); + } else if(value == "chosencolor") { if(c) @@ -390,21 +390,19 @@ ManaCost::ManaCost(ManaCost * manaCost) cost[i] = manaCost->getCost(i); } hybrids = manaCost->hybrids; - kicker = NEW ManaCost(manaCost->kicker); - if (kicker) - kicker->isMulti = manaCost->isMulti; + + kicker = NEW ManaCost( manaCost->kicker ); + if(kicker) + kicker->isMulti = manaCost->isMulti; Retrace = NEW ManaCost( manaCost->Retrace ); BuyBack = NEW ManaCost( manaCost->BuyBack ); alternative = NEW ManaCost( manaCost->alternative ); FlashBack = NEW ManaCost( manaCost->FlashBack ); morph = NEW ManaCost( manaCost->morph ); suspend = NEW ManaCost( manaCost->suspend ); - Bestow = NEW ManaCost(manaCost->Bestow); - extraCosts = NULL; - if (manaCost->extraCosts) - { - extraCosts = manaCost->extraCosts->clone(); - } + Bestow = NEW ManaCost(manaCost->Bestow); + + extraCosts = manaCost->extraCosts ? manaCost->extraCosts->clone() : NULL; manaUsedToCast = NULL; xColor = manaCost->xColor; } @@ -431,13 +429,9 @@ ManaCost::ManaCost(const ManaCost& manaCost) FlashBack = NEW ManaCost( manaCost.FlashBack ); morph = NEW ManaCost( manaCost.morph ); suspend = NEW ManaCost( manaCost.suspend ); - Bestow = NEW ManaCost(manaCost.Bestow); - extraCosts = NULL; - if (manaCost.extraCosts) - { - extraCosts = manaCost.extraCosts->clone(); - } + Bestow = NEW ManaCost(manaCost.Bestow); + extraCosts = manaCost.extraCosts ? manaCost.extraCosts->clone() : NULL; manaUsedToCast = NULL; xColor = manaCost.xColor; } @@ -459,7 +453,7 @@ ManaCost & ManaCost::operator= (const ManaCost & manaCost) FlashBack = manaCost.FlashBack; morph = manaCost.morph; suspend = manaCost.suspend; - Bestow = manaCost.Bestow; + Bestow = manaCost.Bestow; manaUsedToCast = manaCost.manaUsedToCast; xColor = manaCost.xColor; } @@ -476,7 +470,7 @@ ManaCost::~ManaCost() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); SAFE_DELETE(manaUsedToCast); cost.erase(cost.begin() ,cost.end()); @@ -486,6 +480,7 @@ void ManaCost::x() { if (cost.size() <= (size_t)Constants::NB_Colors) { + DebugTrace("Seems ManaCost was not properly initialized"); return; } @@ -496,6 +491,7 @@ int ManaCost::hasX() { if (cost.size() <= (size_t)Constants::NB_Colors) { + DebugTrace("Seems ManaCost was not properly initialized"); return 0; } if (xColor > 0) @@ -508,6 +504,7 @@ void ManaCost::specificX(int color) { if (cost.size() <= (size_t)Constants::NB_Colors) { + DebugTrace("Seems ManaCost was not properly initialized"); return; } xColor = color; @@ -518,6 +515,7 @@ int ManaCost::hasSpecificX() { if (cost.size() <= (size_t)Constants::NB_Colors) { + DebugTrace("Seems ManaCost was not properly initialized"); return 0; } if(xColor > 0) @@ -558,7 +556,7 @@ void ManaCost::init() Retrace = NULL; morph = NULL; suspend = NULL; - Bestow = NULL; + Bestow = NULL; manaUsedToCast = NULL; isMulti = false; xColor = -1; @@ -583,7 +581,7 @@ void ManaCost::resetCosts() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); } void ManaCost::copy(ManaCost * _manaCost) @@ -601,7 +599,6 @@ void ManaCost::copy(ManaCost * _manaCost) hybrids = _manaCost->hybrids; SAFE_DELETE(extraCosts); - if (_manaCost->extraCosts) { extraCosts = _manaCost->extraCosts->clone(); @@ -650,12 +647,12 @@ void ManaCost::copy(ManaCost * _manaCost) suspend = NEW ManaCost(); suspend->copy(_manaCost->suspend); } - SAFE_DELETE(Bestow); - if (_manaCost->Bestow) - { - Bestow = NEW ManaCost(); - Bestow->copy(_manaCost->Bestow); - } + SAFE_DELETE(Bestow); + if (_manaCost->Bestow) + { + Bestow = NEW ManaCost(); + Bestow->copy(_manaCost->Bestow); + } xColor = _manaCost->xColor; } @@ -1120,7 +1117,7 @@ void ManaPool::Empty() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); SAFE_DELETE(manaUsedToCast); init(); WEvent * e = NEW WEventEmptyManaPool(this); @@ -1150,8 +1147,8 @@ int ManaPool::remove(int color, int value) int ManaPool::add(int color, int value, MTGCardInstance * source, bool extra) { - if (color == Constants::MTG_COLOR_ARTIFACT) - color = Constants::MTG_COLOR_WASTE; + if (color == Constants::MTG_COLOR_ARTIFACT) + color = Constants::MTG_COLOR_WASTE; int result = ManaCost::add(color, value); for (int i = 0; i < value; ++i) { @@ -1171,15 +1168,15 @@ int ManaPool::add(ManaCost * _cost, MTGCardInstance * source) { if (!_cost) return 0; - //while colorless is still exactly the same, there are now cards that require - //true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the - //new type. keeping the old type intact for payment methods {1}{c} .... - int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT); - if (replaceArtifact) - { - _cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact); - _cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact); - } + //while colorless is still exactly the same, there are now cards that require + //true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the + //new type. keeping the old type intact for payment methods {1}{c} .... + int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT); + if (replaceArtifact) + { + _cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact); + _cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact); + } int result = ManaCost::add(_cost); for (int i = 0; i < Constants::NB_Colors; i++) { From c5442064370a218d5cd0ca99ba16ddfc15863815 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 7 Jul 2016 13:10:30 +0800 Subject: [PATCH 5/6] Sorted Primitives --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 85 +++++++++---------- .../bin/Res/sets/primitives/unsupported.txt | 31 +------ 2 files changed, 44 insertions(+), 72 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 8e9c0ad75..44b75dae5 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -1,6 +1,6 @@ #Primitives Pack for Wagic the Homebrew. #Please keep these card alphabetized, and try to have the "name=" line at the top of each card -#I sorted this programatically so the other comments are removed except for AUTO_DEFINE - kevlahnota 7-4-2016 +#I sorted this programatically so the other comments are removed except for AUTO_DEFINE - kevlahnota 7-7-2016 [card] name=Abandoned Outpost auto=tap @@ -10126,7 +10126,7 @@ type=Sorcery [card] name=Black Vise auto=name(choose opponent) notatarget(opponent) deplete:0 -auto=@each targetedplayer upkeep:damage:type:*:opponenthandminus4minusend targetedplayer +auto=@each targetedplayer upkeep:damage:type:*:targetedpersonshandminus4minusend targetedplayer text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. mana={1} type=Artifact @@ -14420,6 +14420,13 @@ mana={4} type=Artifact [/card] [card] +name=Bulwark +auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent +text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. +mana={3}{R}{R} +type=Enchantment +[/card] +[card] name=Bump in the Night auto=life:-3 opponent flashback={5}{R} @@ -23720,6 +23727,18 @@ mana={2}{B} type=Instant [/card] [card] +name=Dark Deal +auto=count(type:*:myhand) +auto=all(*|myhand) reject +auto=draw:countedamountplus1plusend controller +auto=count(type:*:opponenthand) +auto=all(*|opponenthand) reject +auto=draw:countedamountplus1plusend opponent +text=Each player discards all the cards in his or her hand, then draws that many cards minus one. +mana={2}{B} +type=Sorcery +[/card] +[card] name=Dark Depths auto=counter(0/0,10,Ice) auto={3}:counter(0/0,-1,Ice) all(this) @@ -23829,6 +23848,13 @@ power=1 toughness=1 [/card] [card] +name=Dark Suspicions +auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent +text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. +mana={2}{B}{B} +type=Enchantment +[/card] +[card] name=Dark Temper target=creature auto=aslongas(*[black]|myBattlefield) destroy @@ -82160,7 +82186,8 @@ type=Enchantment [/card] [card] name=Prized Amalgam -autograveyard=@movedto(creature|mybattlefield) from(mygraveyard):phaseaction[endofturn once] moveto(mybattlefield) and!(tap)! +autograveyard=@movedto(other creature|mybattlefield) from(mygraveyard):phaseactionmulti[endofturn once] moveto(mybattlefield) && tap +autograveyard=@movedto(other creature|mystack) from(mygraveyard):phaseactionmulti[endofturn once] moveto(mybattlefield) && tap text=Whenever a creature enters the battlefield, if it entered from your graveyard or you cast it from your graveyard, return Prized Amalgam from your graveyard to the battlefield tapped at the beginning of the next end step. mana={1}{U}{B} type=Creature @@ -89005,6 +89032,18 @@ mana={1}{W}{U} type=Sorcery [/card] [card] +name=Roiling Horror +anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive +autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller +text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. +mana={3}{B}{B} +suspend(0)={X}{b}{b}{b} +type=Creature +subtype=Horror +power=* +toughness=* +[/card] +[card] name=Roiling Terrain target=land auto=destroy @@ -127555,46 +127594,6 @@ subtype=Orc Warrior power=7 toughness=2 [/card] -###### -######unsorted -[card] -name=Dark Suspicions -auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] -name=Bulwark -auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] -name=Roiling Horror -anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive -autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -suspend(0)={X}{b}{b}{b} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] -name=Dark Deal -auto=count(type:*:myhand) -auto=all(*|myhand) reject -auto=draw:countedamountplus1plusend controller -auto=count(type:*:opponenthand) -auto=all(*|opponenthand) reject -auto=draw:countedamountplus1plusend opponent -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 853855c96..3bbd45bbd 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -1,6 +1,6 @@ grade=unsupported #The cards in this file are not implemented/incomplete yet (UNGLUED, UNHINGED REMOVED) -#Updated Card lists not in primitives (Borderline, Crappy, Unsupported and Missing Cards up to Shadows over Innistrad) as of 7/4/2016 +#Updated Card lists not in primitives (Borderline, Crappy, Unsupported and Missing Cards up to Shadows over Innistrad) as of 7/7/2016 [card] name=1996 World Champion text=Cannot be the targets of spells or effects. World Champion has power and toughness equal to the life totals of target opponent. {0}: Discard your hand to search your library for 1996 World Champion and reveal it to all players. Shuffle your library and put 1996 World Champion on top of it. Use this ability only at the beginning of your upkeep, and only if 1996 World Champion is in your library. @@ -1927,12 +1927,6 @@ mana={B} type=Sorcery [/card] [card] -name=Bulwark -text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand. -mana={3}{R}{R} -type=Enchantment -[/card] -[card] name=Burn at the Stake text=As an additional cost to cast Burn at the Stake, tap any number of untapped creatures you control. -- Burn at the Stake deals damage to target creature or player equal to three times the number of creatures tapped this way. mana={2}{R}{R}{R} @@ -3698,12 +3692,6 @@ power=2 toughness=3 [/card] [card] -name=Dark Deal -text=Each player discards all the cards in his or her hand, then draws that many cards minus one. -mana={2}{B} -type=Sorcery -[/card] -[card] name=Dark Impostor text={4}{B}{B}: Exile target creature and put a +1/+1 counter on Dark Impostor. -- Dark Impostor has all activated abilities of all creature cards exiled with it. mana={2}{B} @@ -3719,12 +3707,6 @@ mana={0} type=Artifact [/card] [card] -name=Dark Suspicions -text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand. -mana={2}{B}{B} -type=Enchantment -[/card] -[card] name=Darkpact text=Remove Darkpact from your deck before playing if you're not playing for ante. -- You own target card in the ante. Exchange that card with the top card of your library. mana={B}{B}{B} @@ -14687,15 +14669,6 @@ power=3 toughness=2 [/card] [card] -name=Roiling Horror -text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. -mana={3}{B}{B} -type=Creature -subtype=Horror -power=* -toughness=* -[/card] -[card] name=Roiling Waters text=Return up to two target creatures your opponents control to their owners' hands. Target player draws two cards. mana={5}{U}{U} @@ -20395,4 +20368,4 @@ name=Zur's Weirding text=Players play with their hands revealed. -- If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card. mana={3}{U} type=Enchantment -[/card] \ No newline at end of file +[/card] From 4da7f770893b11ac3c2509c7c14726f1581b5751 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 7 Jul 2016 13:25:36 +0800 Subject: [PATCH 6/6] Cleanup tabs --- projects/mtg/include/AllAbilities.h | 522 ++++----- projects/mtg/include/ExtraCost.h | 22 +- projects/mtg/include/MTGAbility.h | 2 +- projects/mtg/include/MTGCardInstance.h | 10 +- projects/mtg/include/MTGDefinitions.h | 4 +- projects/mtg/include/MTGGameZones.h | 16 +- projects/mtg/include/MTGRules.h | 26 +- projects/mtg/include/ManaCost.h | 6 +- projects/mtg/include/TargetChooser.h | 2 +- projects/mtg/src/ActionLayer.cpp | 28 +- projects/mtg/src/ActionStack.cpp | 8 +- projects/mtg/src/AllAbilities.cpp | 1488 ++++++++++++------------ projects/mtg/src/ExtraCost.cpp | 382 +++--- projects/mtg/src/GameObserver.cpp | 66 +- projects/mtg/src/GameStateOptions.cpp | 2 +- projects/mtg/src/GuiStatic.cpp | 12 +- projects/mtg/src/MTGAbility.cpp | 334 +++--- projects/mtg/src/MTGCardInstance.cpp | 16 +- projects/mtg/src/MTGDeck.cpp | 22 +- projects/mtg/src/MTGGamePhase.cpp | 2 +- projects/mtg/src/MTGGameZones.cpp | 60 +- projects/mtg/src/MTGRules.cpp | 564 ++++----- projects/mtg/src/ManaCost.cpp | 102 +- projects/mtg/src/Rules.cpp | 2 +- projects/mtg/src/TargetChooser.cpp | 38 +- projects/mtg/src/TargetsList.cpp | 12 +- projects/mtg/src/WEvent.cpp | 2 +- 27 files changed, 1875 insertions(+), 1875 deletions(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index a7045d5e9..4e20da195 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -41,111 +41,111 @@ public: class MTGRevealingCards : public MTGAbility, public CardDisplay { public: - vector cards; - Player * playerForZone; - MTGGameZone * RevealZone; - MTGGameZone * RevealFromZone; - string revealCertainTypes; - string revealUntil; + vector cards; + Player * playerForZone; + MTGGameZone * RevealZone; + MTGGameZone * RevealFromZone; + string revealCertainTypes; + string revealUntil; - CardDisplay * revealDisplay; - vectortrashDisplays;//used for repeat - int nbCard; - string abilityString; - string number; - string abilityOne; - string abilityTwo; - string afterReveal; - bool afterEffectActivated; - MTGAbility * abilityToCast; - MTGAbility * abilityFirst; - MTGAbility * abilitySecond; - MTGAbility * abilityAfter; - vectorabilities; - bool repeat;//only the first ability can be repeated, and it must be targeted. - bool initCD; + CardDisplay * revealDisplay; + vectortrashDisplays;//used for repeat + int nbCard; + string abilityString; + string number; + string abilityOne; + string abilityTwo; + string afterReveal; + bool afterEffectActivated; + MTGAbility * abilityToCast; + MTGAbility * abilityFirst; + MTGAbility * abilitySecond; + MTGAbility * abilityAfter; + vectorabilities; + bool repeat;//only the first ability can be repeated, and it must be targeted. + bool initCD; - void Update(float dt); - int testDestroy(); - int toResolve(); - void CardViewBackup(MTGCardInstance * backup); - void Render(); - bool CheckUserInput(JButton key); - MTGAbility * contructAbility(string abilityToMake = ""); - MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); - virtual MTGRevealingCards * clone() const; - ~MTGRevealingCards(); - int receiveEvent(WEvent*); + void Update(float dt); + int testDestroy(); + int toResolve(); + void CardViewBackup(MTGCardInstance * backup); + void Render(); + bool CheckUserInput(JButton key); + MTGAbility * contructAbility(string abilityToMake = ""); + MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); + virtual MTGRevealingCards * clone() const; + ~MTGRevealingCards(); + int receiveEvent(WEvent*); }; class RevealDisplay : public CardDisplay { public: - RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL, - int nb_displayed_items = 7); - void AddCard(MTGCardInstance * _card); - bool CheckUserInput(JButton key); + RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL, + int nb_displayed_items = 7); + void AddCard(MTGCardInstance * _card); + bool CheckUserInput(JButton key); }; class GenericRevealAbility : public ActivatedAbility { public: - string howMany; - MTGRevealingCards * ability; - GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); - int resolve(); - const string getMenuText(); - GenericRevealAbility * clone() const; - ~GenericRevealAbility(); + string howMany; + MTGRevealingCards * ability; + GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); + int resolve(); + const string getMenuText(); + GenericRevealAbility * clone() const; + ~GenericRevealAbility(); }; class MTGScryCards : public MTGAbility, public CardDisplay { public: - vector cards; - MTGGameZone * RevealZone; - MTGGameZone * RevealFromZone; + vector cards; + MTGGameZone * RevealZone; + MTGGameZone * RevealFromZone; - CardDisplay * revealDisplay; - vectortrashDisplays;//used for repeat - int nbCard; - bool delayed; - bool dontRevealAfter; - int revealTopAmount; - string delayedAbilityString; - string abilityString; - string number; - string abilityOne; - string abilityTwo; - MTGAbility * abilityToCast; - MTGAbility * abilityFirst; - MTGAbility * abilitySecond; - vectorabilities; - bool initCD; - void Update(float dt); - int testDestroy(); - void initDisplay(int value = 0); - int toResolve(); - void Render(); - bool CheckUserInput(JButton key); - MTGAbility * contructAbility(string abilityToMake = ""); - MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); - virtual MTGScryCards * clone() const; - ~MTGScryCards(); - int receiveEvent(WEvent*); + CardDisplay * revealDisplay; + vectortrashDisplays;//used for repeat + int nbCard; + bool delayed; + bool dontRevealAfter; + int revealTopAmount; + string delayedAbilityString; + string abilityString; + string number; + string abilityOne; + string abilityTwo; + MTGAbility * abilityToCast; + MTGAbility * abilityFirst; + MTGAbility * abilitySecond; + vectorabilities; + bool initCD; + void Update(float dt); + int testDestroy(); + void initDisplay(int value = 0); + int toResolve(); + void Render(); + bool CheckUserInput(JButton key); + MTGAbility * contructAbility(string abilityToMake = ""); + MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text); + virtual MTGScryCards * clone() const; + ~MTGScryCards(); + int receiveEvent(WEvent*); }; class GenericScryAbility : public ActivatedAbility { public: - string howMany; - MTGScryCards * ability; - GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); - int resolve(); - const string getMenuText(); - GenericScryAbility * clone() const; - ~GenericScryAbility(); + string howMany; + MTGScryCards * ability; + GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany); + int resolve(); + const string getMenuText(); + GenericScryAbility * clone() const; + ~GenericScryAbility(); }; @@ -166,11 +166,11 @@ private: { if(!s.size()) return; - if (!card) - { - intValue = atoi(s.c_str());//if there is no card, try parsing a number. - return; - } + if (!card) + { + intValue = atoi(s.c_str());//if there is no card, try parsing a number. + return; + } MTGCardInstance * target = card->target; if(!card->storedCard) card->storedCard = card->storedSourceCard; @@ -255,57 +255,57 @@ private: s.erase(otc,otc + 5); } - if (s.find("plusend") != string::npos || s.find("minusend") != string::npos || s.find("math") != string::npos) - { - //plus#plusend and minus#minusend splits the first part and second parts and parses the - //ints for each part, then either adds or subtracts those 2 variables as specified. - vectormathFound = parseBetween(s, "math", "mathend", true); - if (mathFound.size())//maths allows us to get the value before applying multipliers - { - WParsedInt numPar(mathFound[1], NULL, card); - intValue = numPar.getValue(); + if (s.find("plusend") != string::npos || s.find("minusend") != string::npos || s.find("math") != string::npos) + { + //plus#plusend and minus#minusend splits the first part and second parts and parses the + //ints for each part, then either adds or subtracts those 2 variables as specified. + vectormathFound = parseBetween(s, "math", "mathend", true); + if (mathFound.size())//maths allows us to get the value before applying multipliers + { + WParsedInt numPar(mathFound[1], NULL, card); + intValue = numPar.getValue(); - } - else - { - vectorplusSplit = parseBetween(s, "", "plus", true); - if (plusSplit.size()) - { - WParsedInt numPar(plusSplit[1], NULL, card); - intValue = numPar.getValue(); - } - vectorplusFound = parseBetween(s, "plus", "plusend", true); - if (plusFound.size()) - { - WParsedInt numPar(plusFound[1], NULL, card); - intValue += numPar.getValue(); - } - vectorminusSplit = parseBetween(s, "", "minus", true); - if (minusSplit.size()) - { - WParsedInt numPar(minusSplit[1], NULL, card); - intValue = numPar.getValue(); - } - vectorminusFound = parseBetween(s, "minus", "minusend", true); - if (minusFound.size()) - { - WParsedInt numPar(minusFound[1], NULL, card); - intValue -= numPar.getValue(); - } - } - } + } + else + { + vectorplusSplit = parseBetween(s, "", "plus", true); + if (plusSplit.size()) + { + WParsedInt numPar(plusSplit[1], NULL, card); + intValue = numPar.getValue(); + } + vectorplusFound = parseBetween(s, "plus", "plusend", true); + if (plusFound.size()) + { + WParsedInt numPar(plusFound[1], NULL, card); + intValue += numPar.getValue(); + } + vectorminusSplit = parseBetween(s, "", "minus", true); + if (minusSplit.size()) + { + WParsedInt numPar(minusSplit[1], NULL, card); + intValue = numPar.getValue(); + } + vectorminusFound = parseBetween(s, "minus", "minusend", true); + if (minusFound.size()) + { + WParsedInt numPar(minusFound[1], NULL, card); + intValue -= numPar.getValue(); + } + } + } else if(s == "prex") { - if (card->setX > -1) - { - intValue = card->setX; - } - else - { - ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); - intValue = cX->getCost(Constants::NB_Colors); - delete cX; - } + if (card->setX > -1) + { + intValue = card->setX; + } + else + { + ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); + intValue = cX->getCost(Constants::NB_Colors); + delete cX; + } } else if (s == "x" || s == "X") { @@ -382,10 +382,10 @@ private: { intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_GREEN); } - else if (s == "Iroas")//devotion to red white - { - intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE); - } + else if (s == "Iroas")//devotion to red white + { + intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE); + } else if (s.find("type:") != string::npos) { size_t begins = s.find("type:"); @@ -702,10 +702,10 @@ private: { intValue = target->getCurrentToughness(); } - else if (s == "countedamount") - { - intValue = target->CountedObjects; - } + else if (s == "countedamount") + { + intValue = target->CountedObjects; + } else if (s == "kicked") { intValue = target->kicked; @@ -828,17 +828,17 @@ private: { MTGGameZone * checkZone = card->controller()->inPlay(); intValue = //mtg rules 205.4c - cardHasTypeinZone("waste", checkZone) + - cardHasTypeinZone("forest", checkZone) + - cardHasTypeinZone("plains", checkZone) + - cardHasTypeinZone("swamp", checkZone) + - cardHasTypeinZone("island", checkZone) + - cardHasTypeinZone("mountain", checkZone) + - cardHasTypeinZone("snow-covered forest", checkZone) + - cardHasTypeinZone("snow-covered plains", checkZone) + - cardHasTypeinZone("snow-covered swamp", checkZone) + - cardHasTypeinZone("snow-covered island", checkZone) + - cardHasTypeinZone("snow-covered mountain", checkZone); + cardHasTypeinZone("waste", checkZone) + + cardHasTypeinZone("forest", checkZone) + + cardHasTypeinZone("plains", checkZone) + + cardHasTypeinZone("swamp", checkZone) + + cardHasTypeinZone("island", checkZone) + + cardHasTypeinZone("mountain", checkZone) + + cardHasTypeinZone("snow-covered forest", checkZone) + + cardHasTypeinZone("snow-covered plains", checkZone) + + cardHasTypeinZone("snow-covered swamp", checkZone) + + cardHasTypeinZone("snow-covered island", checkZone) + + cardHasTypeinZone("snow-covered mountain", checkZone); } else if (s == "myname")//Name of the card you control { @@ -894,49 +894,49 @@ private: intValue += card->controller()->game->inPlay->cards[j]->power; } } - else if (s == "revealedp") - { - if (card->revealedLast) - intValue = card->revealedLast->power; - } - else if (s == "revealedt") - { - if (card->revealedLast) - intValue = card->revealedLast->toughness; - } - else if (s == "revealedmana") - { - if (card->revealedLast) - intValue = card->revealedLast->getManaCost()->getConvertedCost(); - } + else if (s == "revealedp") + { + if (card->revealedLast) + intValue = card->revealedLast->power; + } + else if (s == "revealedt") + { + if (card->revealedLast) + intValue = card->revealedLast->toughness; + } + else if (s == "revealedmana") + { + if (card->revealedLast) + intValue = card->revealedLast->getManaCost()->getConvertedCost(); + } else if(!intValue)//found nothing, try parsing a atoi { intValue = atoi(s.c_str()); - } - if (intValue > 0)//dont divide by 0 the rest are valid. - { - if (halfup) - { - if (intValue % 2 == 1) - intValue++; - intValue = intValue / 2; - } - if (halfdown) - intValue = intValue / 2; - } - if (twice) - intValue = intValue * 2; - if (thrice) - intValue = intValue * 3; - if (intValue < 0) - { - //we remove "-" at the start and are parsing for real values. - //if we ended up with a value less than 0, then we return just 0 - intValue = 0; - } + } + if (intValue > 0)//dont divide by 0 the rest are valid. + { + if (halfup) + { + if (intValue % 2 == 1) + intValue++; + intValue = intValue / 2; + } + if (halfdown) + intValue = intValue / 2; + } + if (twice) + intValue = intValue * 2; + if (thrice) + intValue = intValue * 3; + if (intValue < 0) + { + //we remove "-" at the start and are parsing for real values. + //if we ended up with a value less than 0, then we return just 0 + intValue = 0; + } - intValue *= multiplier; - } + intValue *= multiplier; + } public: int countDevotionTo(MTGCardInstance * card, MTGGameZone * zone, int color1, int color2) @@ -3489,7 +3489,7 @@ public: list colors; int power, toughness; int tokenId; - string _cardName; + string _cardName; string name; string sabilities; string starfound; @@ -3501,7 +3501,7 @@ public: MTGCardInstance * myToken; vector currentAbilities; Player * tokenReciever; - //by id + //by id ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, int tokenId,string starfound, WParsedInt * multiplier = NULL, int who = 0,bool aLivingWeapon = false) : ActivatedAbility(observer, _id, _source, _cost, 0), tokenId(tokenId), starfound(starfound),multiplier(multiplier), who(who),aLivingWeapon(aLivingWeapon) @@ -3511,18 +3511,18 @@ public: if (card) name = card->data->getName(); battleReady = false; } - //by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)... - ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL, - int who = 0, bool aLivingWeapon = false) : - ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon) - { - if (!multiplier) this->multiplier = NEW WParsedInt(1); - MTGCard * card = MTGCollection()->getCardByName(_cardName); - tokenId = card->getId(); - if (card) name = card->data->getName(); - battleReady = false; - } - //by construction + //by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)... + ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL, + int who = 0, bool aLivingWeapon = false) : + ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon) + { + if (!multiplier) this->multiplier = NEW WParsedInt(1); + MTGCard * card = MTGCollection()->getCardByName(_cardName); + tokenId = card->getId(); + if (card) name = card->data->getName(); + battleReady = false; + } + //by construction ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string sname, string stypes, int _power, int _toughness, string sabilities, string starfound,WParsedInt * multiplier = NULL, int _who = 0,bool aLivingWeapon = false,string spt = "") : ActivatedAbility(observer, _id, _source, _cost, 0),sabilities(sabilities),starfound(starfound), multiplier(multiplier), who(_who),aLivingWeapon(aLivingWeapon),spt(spt) @@ -4045,12 +4045,12 @@ class AThis: public MTGAbility, public NestedAbility public: MTGAbility * a; ThisDescriptor * td; - string restrictionCheck; + string restrictionCheck; AThis(GameObserver* observer, int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability, string restriction = "") : MTGAbility(observer, _id, _source, _target), NestedAbility(ability) { td = _td; - restrictionCheck = restriction; + restrictionCheck = restriction; ability->source = source; ability->target = target; a = NULL; @@ -4074,18 +4074,18 @@ public: int resolve() { - int match = 0; - if (td) - { - match = td->match(source); - } - else - {//restriction check instead of Targetchooser - AbilityFactory abf(target->getObserver()); - int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck); - if (checkCond) - match = 1; - } + int match = 0; + if (td) + { + match = td->match(source); + } + else + {//restriction check instead of Targetchooser + AbilityFactory abf(target->getObserver()); + int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck); + if (checkCond) + match = 1; + } if (match > 0) { addAbilityToGame(); @@ -4132,7 +4132,7 @@ public: { AThis * a = NEW AThis(*this); a->ability = ability->clone(); - if(a->td) + if(a->td) a->td = td->clone(); return a; } @@ -4350,11 +4350,11 @@ public: class ABestow : public ActivatedAbility { public: - MTGCardInstance * _card; - ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); - int resolve(); - const string getMenuText(); - ABestow * clone() const; + MTGCardInstance * _card; + ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); + int resolve(); + const string getMenuText(); + ABestow * clone() const; }; /* Can tap a target for a cost */ @@ -4381,16 +4381,16 @@ public: class AAWhatsX : public ActivatedAbility { public: - int value; - MTGAbility * costRule; - AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); - int resolve(); - const string getMenuText() - { - sprintf(menuText, "%i", value); - return menuText; - }; - AAWhatsX * clone() const; + int value; + MTGAbility * costRule; + AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); + int resolve(); + const string getMenuText() + { + sprintf(menuText, "%i", value); + return menuText; + }; + AAWhatsX * clone() const; }; /* set max level up on a levelup creature this is an Ai hint ability, no effect for players.*/ @@ -4407,17 +4407,17 @@ public: class AACountObject : public ActivatedAbility { public: - string value; + string value; - AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value =""); - int resolve(); - AACountObject * clone() const; + AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value =""); + int resolve(); + AACountObject * clone() const; }; /* Can prevent a card from untapping next untap */ class AAFrozen: public ActivatedAbility { public: - bool freeze; + bool freeze; AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, bool tap, ManaCost * _cost = NULL); int resolve(); const string getMenuText(); @@ -5208,32 +5208,32 @@ public: class AGrant : public MTGAbility { public: - MTGCardInstance * Blessed; - bool resolved; - MTGAbility * Granted; - MTGAbility * toGrant; - AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); - void Update(float dt); - void resolveGrant(); - int resolve(); - const string getMenuText(); - AGrant * clone() const; - ~AGrant(); + MTGCardInstance * Blessed; + bool resolved; + MTGAbility * Granted; + MTGAbility * toGrant; + AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + void Update(float dt); + void resolveGrant(); + int resolve(); + const string getMenuText(); + AGrant * clone() const; + ~AGrant(); private: - void removeGranted(MTGCardInstance *_target); + void removeGranted(MTGCardInstance *_target); }; //GrantWrapper class AGrantWrapper : public InstantAbility { public: - AGrant * ability; - MTGAbility * Granted; - AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); - int resolve(); - const string getMenuText(); - AGrantWrapper * clone() const; - ~AGrantWrapper(); + AGrant * ability; + MTGAbility * Granted; + AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + int resolve(); + const string getMenuText(); + AGrantWrapper * clone() const; + ~AGrantWrapper(); }; //ABlink @@ -6485,7 +6485,7 @@ public: MTGCardInstance * theNamedCard; bool noEvent; bool putinplay; - bool asNormalMadness; + bool asNormalMadness; AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay,bool asNormalMadness = false); int testDestroy(){return 0;}; diff --git a/projects/mtg/include/ExtraCost.h b/projects/mtg/include/ExtraCost.h index 8d8e8f2b1..9d3690e99 100644 --- a/projects/mtg/include/ExtraCost.h +++ b/projects/mtg/include/ExtraCost.h @@ -278,22 +278,22 @@ public: class Convoke : public ExtraCost { public: - ManaCost * getReduction(); - Convoke(TargetChooser *_tc = NULL); - virtual int canPay(); - virtual int isPaymentSet(); - virtual int doPay(); - virtual Convoke * clone() const; + ManaCost * getReduction(); + Convoke(TargetChooser *_tc = NULL); + virtual int canPay(); + virtual int isPaymentSet(); + virtual int doPay(); + virtual Convoke * clone() const; }; //delve class Delve : public ExtraCost { public: - Delve(TargetChooser *_tc = NULL); - virtual int canPay(); - virtual int isPaymentSet(); - virtual int doPay(); - virtual Delve * clone() const; + Delve(TargetChooser *_tc = NULL); + virtual int canPay(); + virtual int isPaymentSet(); + virtual int doPay(); + virtual Delve * clone() const; }; //offering cost class Offering : public ExtraCost diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index 80f1d8447..752c5341e 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -121,7 +121,7 @@ public: ManaCost* BuyBack; ManaCost* FlashBack; ManaCost* Retrace; - ManaCost* Bestow; + ManaCost* Bestow; ManaCost* morph; ManaCost* suspend; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 1bd266b1b..eabdea192 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -55,7 +55,7 @@ public: Pos* view; int X; int castX; - int setX; + int setX; int alternateCostPaid[ManaCost::MANA_PAID_WITH_BESTOW + 1]; int paymenttype; int castMethod; /* Tells if the card reached its current zone by being cast or not (brought into the zone by an effect). non 0 == cast, 0 == not cast */ @@ -96,7 +96,7 @@ public: bool exileEffects; bool suspended; bool miracle; - bool isBestowed; + bool isBestowed; int chooseacolor; string chooseasubtype; int coinSide;//1 = tails @@ -107,7 +107,7 @@ public: int notblocked; int fresh; int MaxLevelUp; - int CountedObjects; + int CountedObjects; int kicked; int dredge; bool isDualWielding; @@ -276,8 +276,8 @@ public: string currentimprintName; vectorimprintedNames; - MTGCardInstance * revealedLast;//last card revealed by a ability this card owns. - bool MadnessPlay; + MTGCardInstance * revealedLast;//last card revealed by a ability this card owns. + bool MadnessPlay; void eventattacked(); void eventattackedAlone(); void eventattackednotblocked(); diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index caea4b9d5..98224a8e0 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -98,7 +98,7 @@ class Constants MTG_COLOR_WHITE = 5, MTG_COLOR_WASTE = 6, MTG_COLOR_LAND = 7, - + MTG_NB_COLORS = 8, @@ -315,7 +315,7 @@ class Constants CAST_WITH_RETRACE = 6, CAST_WITH_MORPH = 7, CAST_WITH_SUSPEND = 8, - CAST_WITH_BESTOW = 9, + CAST_WITH_BESTOW = 9, CAST_ALTERNATE = -1, //matches all alternate costs, including itself CAST_ALL = -2, // matches everything except NOT_CAST diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index b37b555bf..96f3bfb29 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -72,13 +72,13 @@ class MTGGameZone { OWNER_STACK = 66, TARGETED_PLAYER_STACK = 67, - MY_REVEAL = 71, - OPPONENT_REVEAL = 72, - TARGET_OWNER_REVEAL = 73, - TARGET_CONTROLLER_REVEAL = 74, - REVEAL = 75, - OWNER_REVEAL = 76, - TARGETED_PLAYER_REVEAL = 77, + MY_REVEAL = 71, + OPPONENT_REVEAL = 72, + TARGET_OWNER_REVEAL = 73, + TARGET_CONTROLLER_REVEAL = 74, + REVEAL = 75, + OWNER_REVEAL = 76, + TARGETED_PLAYER_REVEAL = 77, }; @@ -202,7 +202,7 @@ public: MTGRemovedFromGame * exile; //alias to removedFromZone MTGGameZone * garbage; MTGGameZone * garbageLastTurn; - MTGGameZone * reveal; + MTGGameZone * reveal; MTGGameZone * temp; MTGPlayerCards(); diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 084273425..1b52f72e3 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -58,10 +58,10 @@ public: int Angel[2]; bool dragonbonusgranted[2]; int dragon[2]; - bool eldrazibonusgranted[2]; - int eldrazi[2]; - bool werewolfbonusgranted[2]; - int werewolf[2]; + bool eldrazibonusgranted[2]; + int eldrazi[2]; + bool werewolfbonusgranted[2]; + int werewolf[2]; int receiveEvent(WEvent * event); void grantAward(string awardName,int amount); @@ -213,15 +213,15 @@ public: class MTGBestowRule : public MTGAlternativeCostRule { public: - int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); - int reactToClick(MTGCardInstance * card); - virtual ostream& toString(ostream& out) const; - MTGBestowRule(GameObserver* observer, int _id); - const string getMenuText() - { - return "Bestow"; - } - virtual MTGBestowRule * clone() const; + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); + int reactToClick(MTGCardInstance * card); + virtual ostream& toString(ostream& out) const; + MTGBestowRule(GameObserver* observer, int _id); + const string getMenuText() + { + return "Bestow"; + } + virtual MTGBestowRule * clone() const; }; diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index 205dead10..fc5438d7d 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -31,7 +31,7 @@ protected: ManaCost * manaUsedToCast; ManaCost * morph; ManaCost * Retrace; - ManaCost * Bestow; + ManaCost * Bestow; ManaCost * FlashBack; ManaCost * BuyBack; ManaCost * kicker; @@ -76,8 +76,8 @@ public: ManaCost * getSuspend(){ return suspend; }; void setSuspend(ManaCost * aMana){ SAFE_DELETE(suspend); suspend = aMana;}; - ManaCost * getBestow() { return Bestow; }; - void setBestow(ManaCost * aMana) { SAFE_DELETE(Bestow); Bestow = aMana; }; + ManaCost * getBestow() { return Bestow; }; + void setBestow(ManaCost * aMana) { SAFE_DELETE(Bestow); Bestow = aMana; }; ManaCost * getManaUsedToCast(){ return manaUsedToCast; }; void setManaUsedToCast(ManaCost * aMana){ SAFE_DELETE(manaUsedToCast); manaUsedToCast = aMana;}; diff --git a/projects/mtg/include/TargetChooser.h b/projects/mtg/include/TargetChooser.h index a457024cb..497b2d5ae 100644 --- a/projects/mtg/include/TargetChooser.h +++ b/projects/mtg/include/TargetChooser.h @@ -25,7 +25,7 @@ class TargetChooser: public TargetsList protected: int forceTargetListReady; public: - int forceTargetListReadyByPlayer; + int forceTargetListReadyByPlayer; const static int UNLITMITED_TARGETS = 1000; enum { diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index 06162dd1a..dffe260c6 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -105,11 +105,11 @@ bool ActionLayer::CheckUserInput(JButton key) //being cancelled. currently only menuability and paidability will care. } } - if (observer->mExtraPayment->costs.size() && observer->mExtraPayment->costs[0]->tc) - { - //if we cancel, clear the targets list so that when you try again you dont already have targets from before. - observer->mExtraPayment->costs[0]->tc->initTargets(); - } + if (observer->mExtraPayment->costs.size() && observer->mExtraPayment->costs[0]->tc) + { + //if we cancel, clear the targets list so that when you try again you dont already have targets from before. + observer->mExtraPayment->costs[0]->tc->initTargets(); + } observer->mExtraPayment = NULL; return 1; } @@ -191,11 +191,11 @@ void ActionLayer::Update(float dt) without this, the game locks into a freeze state while you try to select the targets and dont have enough to fill the maxtargets list. */ - if (int(ae->getActionTc()->getNbTargets()) == countTargets)//if the amount of targets is equal the all we can target - { - ae->getActionTc()->done = true;//were done - ae->getActionTc()->source->getObserver()->cardClick(ae->getActionTc()->source, 0, false);//click source. - } + if (int(ae->getActionTc()->getNbTargets()) == countTargets)//if the amount of targets is equal the all we can target + { + ae->getActionTc()->done = true;//were done + ae->getActionTc()->source->getObserver()->cardClick(ae->getActionTc()->source, 0, false);//click source. + } } } } @@ -467,10 +467,10 @@ void ActionLayer::doReactTo(int menuIndex) { int controlid = abilitiesMenu->mObjects[menuIndex]->GetId(); DebugTrace("ActionLayer::doReactTo " << controlid); - if (abilitiesMenu && abilitiesMenu->isMultipleChoice) - { - return ButtonPressedOnMultipleChoice(menuIndex); - } + if (abilitiesMenu && abilitiesMenu->isMultipleChoice) + { + return ButtonPressedOnMultipleChoice(menuIndex); + } ButtonPressed(0, controlid); } } diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 40546d735..6d9620ec7 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -578,10 +578,10 @@ int ActionStack::addAbility(MTGAbility * ability) if (!observer->players[0]->isAI() && ability->source->controller() == observer->players[0] && 0 == options[Options::INTERRUPTMYABILITIES].number) interruptDecision[0] = DONT_INTERRUPT; - if (observer->OpenedDisplay && observer->players[0]->game->reveal->cards.size()) - { - interruptDecision[0] = DONT_INTERRUPT; - } + if (observer->OpenedDisplay && observer->players[0]->game->reveal->cards.size()) + { + interruptDecision[0] = DONT_INTERRUPT; + } return result; } diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index e89becee5..eb2d7e5bb 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -45,477 +45,477 @@ MTGEventText * MTGEventText::clone() const //generic activated ability for wrapping reveals. GenericRevealAbility::GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _howMany) : - ActivatedAbility(observer, id, source, NULL), howMany(_howMany) + Targetable * target, string _howMany) : + ActivatedAbility(observer, id, source, NULL), howMany(_howMany) { - this->GetId(); + this->GetId(); } int GenericRevealAbility::resolve() { - MTGAbility * ability = NEW MTGRevealingCards(game, this->GetId(), source, howMany); - ability->addToGame(); - return 1; + MTGAbility * ability = NEW MTGRevealingCards(game, this->GetId(), source, howMany); + ability->addToGame(); + return 1; } const string GenericRevealAbility::getMenuText() { - return "Reveal Cards"; + return "Reveal Cards"; } GenericRevealAbility * GenericRevealAbility::clone() const { - GenericRevealAbility * a = NEW GenericRevealAbility(*this); - return a; + GenericRevealAbility * a = NEW GenericRevealAbility(*this); + return a; } GenericRevealAbility::~GenericRevealAbility() { - //SAFE_DELETE(ability); + //SAFE_DELETE(ability); } //carddisplay created for use in abilities. RevealDisplay::RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener, TargetChooser * tc, - int nb_displayed_items) : - CardDisplay(id, game, x, y, listener, tc, nb_displayed_items) + int nb_displayed_items) : + CardDisplay(id, game, x, y, listener, tc, nb_displayed_items) { } void RevealDisplay::AddCard(MTGCardInstance * _card) { - CardGui * card = NEW CardView(CardView::nullZone, _card, static_cast (x + 20 + (mObjects.size() - start_item) * 30), - static_cast (y + 25)); - Add(card); + CardGui * card = NEW CardView(CardView::nullZone, _card, static_cast (x + 20 + (mObjects.size() - start_item) * 30), + static_cast (y + 25)); + Add(card); } bool RevealDisplay::CheckUserInput(JButton key) { - if (JGE_BTN_SEC == key || JGE_BTN_PRI == key || JGE_BTN_UP == key || JGE_BTN_DOWN == key) - return false; + if (JGE_BTN_SEC == key || JGE_BTN_PRI == key || JGE_BTN_UP == key || JGE_BTN_DOWN == key) + return false; - return CardDisplay::CheckUserInput(key); + return CardDisplay::CheckUserInput(key); } //display card selector box of specified zone. MTGRevealingCards::MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string coreAbility) : - MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) + MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) { - abilityToCast = NULL; - revealDisplay = NULL; - abilityFirst = NULL; + abilityToCast = NULL; + revealDisplay = NULL; + abilityFirst = NULL; abilitySecond = NULL; - abilityString = coreAbility; - initCD = false; + abilityString = coreAbility; + initCD = false; - afterReveal = ""; - afterEffectActivated = false; + afterReveal = ""; + afterEffectActivated = false; - repeat = false; - playerForZone = NULL; - revealCertainTypes = ""; - revealUntil = ""; + repeat = false; + playerForZone = NULL; + revealCertainTypes = ""; + revealUntil = ""; - if (card->playerTarget) - playerForZone = card->playerTarget; - else - playerForZone = source->controller(); + if (card->playerTarget) + playerForZone = card->playerTarget; + else + playerForZone = source->controller(); - RevealZone = playerForZone->game->reveal; - zone = RevealZone; - RevealFromZone = playerForZone->game->library; + RevealZone = playerForZone->game->reveal; + zone = RevealZone; + RevealFromZone = playerForZone->game->library; - vectoramount = parseBetween(coreAbility, "", " "); - if (amount.size()) - { - number = amount[1]; - } + vectoramount = parseBetween(coreAbility, "", " "); + if (amount.size()) + { + number = amount[1]; + } - vectordifferentZone = parseBetween(coreAbility, "revealzone(", ")"); - if (differentZone.size()) - { - RevealFromZone = MTGGameZone::stringToZone(game,differentZone[1],source,NULL); - } + vectordifferentZone = parseBetween(coreAbility, "revealzone(", ")"); + if (differentZone.size()) + { + RevealFromZone = MTGGameZone::stringToZone(game,differentZone[1],source,NULL); + } - vectorcertainTypes = parseBetween(coreAbility, "revealtype(", ")"); - if (certainTypes.size()) - { - revealCertainTypes = certainTypes[1]; - } + vectorcertainTypes = parseBetween(coreAbility, "revealtype(", ")"); + if (certainTypes.size()) + { + revealCertainTypes = certainTypes[1]; + } - vectorRevealCardUntil = parseBetween(coreAbility, "revealuntil(", ")"); - if (RevealCardUntil.size()) - { - revealUntil = RevealCardUntil[1]; - } + vectorRevealCardUntil = parseBetween(coreAbility, "revealuntil(", ")"); + if (RevealCardUntil.size()) + { + revealUntil = RevealCardUntil[1]; + } - vectorfirst = parseBetween(coreAbility, "optionone ", " optiononeend"); - if (first.size()) - { - abilityOne = first[1]; - } - vectorsecond = parseBetween(coreAbility, "optiontwo ", " optiontwoend"); - if (second.size()) - { - abilityTwo = second[1]; - } - vectorafterEffect = parseBetween(coreAbility, "afterrevealed ", " afterrevealedend"); - if (afterEffect.size()) - { - afterReveal = afterEffect[1]; - } + vectorfirst = parseBetween(coreAbility, "optionone ", " optiononeend"); + if (first.size()) + { + abilityOne = first[1]; + } + vectorsecond = parseBetween(coreAbility, "optiontwo ", " optiontwoend"); + if (second.size()) + { + abilityTwo = second[1]; + } + vectorafterEffect = parseBetween(coreAbility, "afterrevealed ", " afterrevealedend"); + if (afterEffect.size()) + { + afterReveal = afterEffect[1]; + } - repeat = coreAbility.find("repeat") != string::npos; + repeat = coreAbility.find("repeat") != string::npos; } void MTGRevealingCards::Update(float dt) { - if (game->OpenedDisplay != this->revealDisplay && !initCD)//wait your turn - { - //if any carddisplays are open, dont do anything until theyre closed, then wait your turn if multiple reveals trigger. - return; - } - if (game->mLayers->actionLayer()->menuObject) - return;//dont do any of this if a menuobject exist. - if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) - { + if (game->OpenedDisplay != this->revealDisplay && !initCD)//wait your turn + { + //if any carddisplays are open, dont do anything until theyre closed, then wait your turn if multiple reveals trigger. + return; + } + if (game->mLayers->actionLayer()->menuObject) + return;//dont do any of this if a menuobject exist. + if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) + { - WParsedInt nbCardP(number, NULL, source); - nbCard = nbCardP.getValue(); - int adjust = 0; - switch (nbCard) - { - //adjust length and location of carddisplay box. - case 1:adjust = 120; break; - case 2:adjust = 145; break; - case 3:adjust = 175; break; - case 4:adjust = 200; break; - case 5:adjust = 225; break; - default:adjust = 225; break; - } - if (revealUntil.size()) - { - adjust = 225; - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL,5); - } - else - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); - revealDisplay->zone = RevealFromZone; - trashDisplays.push_back(revealDisplay); + WParsedInt nbCardP(number, NULL, source); + nbCard = nbCardP.getValue(); + int adjust = 0; + switch (nbCard) + { + //adjust length and location of carddisplay box. + case 1:adjust = 120; break; + case 2:adjust = 145; break; + case 3:adjust = 175; break; + case 4:adjust = 200; break; + case 5:adjust = 225; break; + default:adjust = 225; break; + } + if (revealUntil.size()) + { + adjust = 225; + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL,5); + } + else + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); + revealDisplay->zone = RevealFromZone; + trashDisplays.push_back(revealDisplay); - if (revealCertainTypes.size())//revealing cards of a TARGETCHOOSER type. - { - TargetChooserFactory tcf(game); - TargetChooser * rTc = tcf.createTargetChooser(revealCertainTypes, source); - int startingNumber = RevealFromZone->nb_cards - 1; - if (rTc) - for (int i = startingNumber; i > -1; i--) - { - if (!RevealFromZone->cards.size()) - break; - MTGCardInstance * toMove = RevealFromZone->cards[i]; - if (toMove) - { - if (rTc->canTarget(toMove, true)) - { - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } - } + if (revealCertainTypes.size())//revealing cards of a TARGETCHOOSER type. + { + TargetChooserFactory tcf(game); + TargetChooser * rTc = tcf.createTargetChooser(revealCertainTypes, source); + int startingNumber = RevealFromZone->nb_cards - 1; + if (rTc) + for (int i = startingNumber; i > -1; i--) + { + if (!RevealFromZone->cards.size()) + break; + MTGCardInstance * toMove = RevealFromZone->cards[i]; + if (toMove) + { + if (rTc->canTarget(toMove, true)) + { + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } + } - } - SAFE_DELETE(rTc); - } - else if(revealUntil.size())//reveal cards until you reveal a TARGETCHOOSER. - { - TargetChooserFactory tcf(game); - TargetChooser * rUc = tcf.createTargetChooser(revealUntil, source); - bool foundCard = false; - int howMany = nbCard; - int startingNumber = RevealFromZone->nb_cards; - for (int i = 0; i < startingNumber; i++) - { - if (foundCard && howMany == 0) - break; - if (howMany == 0) - break; //not allowed to reveal until 0 of something is revealed. - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - if (rUc->canTarget(toMove, true)) - { - foundCard = true; - howMany--; - } + } + SAFE_DELETE(rTc); + } + else if(revealUntil.size())//reveal cards until you reveal a TARGETCHOOSER. + { + TargetChooserFactory tcf(game); + TargetChooser * rUc = tcf.createTargetChooser(revealUntil, source); + bool foundCard = false; + int howMany = nbCard; + int startingNumber = RevealFromZone->nb_cards; + for (int i = 0; i < startingNumber; i++) + { + if (foundCard && howMany == 0) + break; + if (howMany == 0) + break; //not allowed to reveal until 0 of something is revealed. + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + if (rUc->canTarget(toMove, true)) + { + foundCard = true; + howMany--; + } - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } - } - SAFE_DELETE(rUc); - } - else - { - for (int i = 0; i < nbCard; i++)//normal reveal - { - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - CardViewBackup(toMove); - playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } + } + SAFE_DELETE(rUc); + } + else + { + for (int i = 0; i < nbCard; i++)//normal reveal + { + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + CardViewBackup(toMove); + playerForZone->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } - } + } - } + } - //build the zone, create the first ability. - revealDisplay->init(RevealZone); - revealDisplay->zone = RevealZone; - game->OpenedDisplay = revealDisplay; - toResolve(); - initCD = true; - } + //build the zone, create the first ability. + revealDisplay->init(RevealZone); + revealDisplay->zone = RevealZone; + game->OpenedDisplay = revealDisplay; + toResolve(); + initCD = true; + } - //card display is ready and loaded, abilities have fired at this point. - //critical for testdestroy, a function that determines if a ability can - //exist in condiations such as source not being in play. - - if (!zone->cards.size()) - { - //all possible actions are done, the zone is empty, lets NULL it so it clears it off the screen. - //DO NOT SAFE_DELETE here, it destroys the card->view and backups kept for the second ability. - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; + //card display is ready and loaded, abilities have fired at this point. + //critical for testdestroy, a function that determines if a ability can + //exist in condiations such as source not being in play. + + if (!zone->cards.size()) + { + //all possible actions are done, the zone is empty, lets NULL it so it clears it off the screen. + //DO NOT SAFE_DELETE here, it destroys the card->view and backups kept for the second ability. + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; - if (repeat) - { - initCD = false; - } - else if (afterReveal.size() && !afterEffectActivated) - { - afterEffectActivated = true; - abilityAfter = contructAbility(afterReveal); - game->addObserver(abilityAfter); - } - else - this->removeFromGame(); - } + if (repeat) + { + initCD = false; + } + else if (afterReveal.size() && !afterEffectActivated) + { + afterEffectActivated = true; + abilityAfter = contructAbility(afterReveal); + game->addObserver(abilityAfter); + } + else + this->removeFromGame(); + } - if (revealDisplay) - { - revealDisplay->Update(dt); - Render(); - } + if (revealDisplay) + { + revealDisplay->Update(dt); + Render(); + } - MTGAbility::Update(dt); + MTGAbility::Update(dt); } void MTGRevealingCards::CardViewBackup(MTGCardInstance * backup) { - CardView* t; + CardView* t; - t = NEW CardView(CardView::nullZone, backup, 0, 0); - //we store copies of the card view since the safe_delete of card displays also deletes the guis stored in them. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); - return; + t = NEW CardView(CardView::nullZone, backup, 0, 0); + //we store copies of the card view since the safe_delete of card displays also deletes the guis stored in them. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); + return; } int MTGRevealingCards::testDestroy() { - if (game->mExtraPayment) - return 0; - if (revealDisplay) - return 0; - if (zone->cards.size()) - return 0; - if (!initCD) - return 0; - if (game->mLayers->actionLayer()->menuObject) - return 0; - if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) - return 0; + if (game->mExtraPayment) + return 0; + if (revealDisplay) + return 0; + if (zone->cards.size()) + return 0; + if (!initCD) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) + return 0; - return 1; + return 1; } int MTGRevealingCards::toResolve() { - TargetChooserFactory tcf(game); - vectorsplitTarget = parseBetween(abilityOne, "target(", ")"); - //we build a tc to check if the first ability has any valid targets, if it doesnt, just add the 2nd one. - if (splitTarget.size()) - { - TargetChooser * rTc = tcf.createTargetChooser(splitTarget[1].c_str(), source); + TargetChooserFactory tcf(game); + vectorsplitTarget = parseBetween(abilityOne, "target(", ")"); + //we build a tc to check if the first ability has any valid targets, if it doesnt, just add the 2nd one. + if (splitTarget.size()) + { + TargetChooser * rTc = tcf.createTargetChooser(splitTarget[1].c_str(), source); - if (rTc && rTc->countValidTargets()) - { - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - - } - else - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); + if (rTc && rTc->countValidTargets()) + { + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); - } - SAFE_DELETE(rTc); - } - else//the first ability is not targeted - { - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - } - return 1; + } + else + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + + } + SAFE_DELETE(rTc); + } + else//the first ability is not targeted + { + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + } + return 1; } MTGAbility * MTGRevealingCards::contructAbility(string abilityToMake) { - AbilityFactory af(game); - abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); - if (!abilityToCast) - return NULL; - abilityToCast->canBeInterrupted = false; - abilityToCast->forceDestroy = 1; - return abilityToCast; + AbilityFactory af(game); + abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); + if (!abilityToCast) + return NULL; + abilityToCast->canBeInterrupted = false; + abilityToCast->forceDestroy = 1; + return abilityToCast; } void MTGRevealingCards::Render() { - if (!revealDisplay) - return; - CheckUserInput(mEngine->ReadButton()); - revealDisplay->CheckUserInput(mEngine->ReadButton()); - revealDisplay->Render(); - return; + if (!revealDisplay) + return; + CheckUserInput(mEngine->ReadButton()); + revealDisplay->CheckUserInput(mEngine->ReadButton()); + revealDisplay->Render(); + return; } bool MTGRevealingCards::CheckUserInput(JButton key) { - //DO NOT REFACTOR BELOW, IT KEPT SPLIT UP TO MAINTAIN READABILITY. + //DO NOT REFACTOR BELOW, IT KEPT SPLIT UP TO MAINTAIN READABILITY. //we override check inputs, we MUST complete reveal and its effects before being allowed to do anything else. - TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); - if (this->source->controller()->isAI()) - { - if (this->source->controller() != game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); - } - if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key)//android back button - { - if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) - { - tc->done = true; - tc->forceTargetListReadyByPlayer = 1; - //this is for when we have targets but only want to move Y targets, it allows us to - //tell the targetchooser we are done. - if (!abilitySecond && !tc->getNbTargets() && tc->source) - {//we selected nothing for the first ability. - tc->source->getObserver()->cardClick(tc->source, 0, false); - if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(0); - //remove it from the game, update, and remove it from stack if needed. - //before adding next ability, otherwise we end up with a menu reactToClick. - if (zone->cards.size() && abilityFirst->testDestroy())//generally only want to add ability 2 if anything is left in the zone. - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } - } - else if (tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - } - } - else if (!tc && !abilitySecond)//the actions of the first card have finished and we're done looking at the cards. - { //or the first ability was an "all(" which was not a mover ability. - CheckUserInput(JGE_BTN_OK); - } - return false; - } - if (JGE_BTN_OK == key)//for ease if we're sitting there looking at the card display and click a card after first ability. - { //looks redundent and can be added above as another condiational, however we would end up with a massive - //if statement that becomes very very hard to follow. - if (!tc && !abilitySecond) - { - if (abilityFirst) - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(1); + TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); + if (this->source->controller()->isAI()) + { + if (this->source->controller() != game->isInterrupting) + game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); + } + if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key)//android back button + { + if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) + { + tc->done = true; + tc->forceTargetListReadyByPlayer = 1; + //this is for when we have targets but only want to move Y targets, it allows us to + //tell the targetchooser we are done. + if (!abilitySecond && !tc->getNbTargets() && tc->source) + {//we selected nothing for the first ability. + tc->source->getObserver()->cardClick(tc->source, 0, false); + if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(0); + //remove it from the game, update, and remove it from stack if needed. + //before adding next ability, otherwise we end up with a menu reactToClick. + if (zone->cards.size() && abilityFirst->testDestroy())//generally only want to add ability 2 if anything is left in the zone. + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } + } + else if (tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + } + } + else if (!tc && !abilitySecond)//the actions of the first card have finished and we're done looking at the cards. + { //or the first ability was an "all(" which was not a mover ability. + CheckUserInput(JGE_BTN_OK); + } + return false; + } + if (JGE_BTN_OK == key)//for ease if we're sitting there looking at the card display and click a card after first ability. + { //looks redundent and can be added above as another condiational, however we would end up with a massive + //if statement that becomes very very hard to follow. + if (!tc && !abilitySecond) + { + if (abilityFirst) + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(1); - if (zone->cards.size()) - { - repeat = false; - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } + if (zone->cards.size()) + { + repeat = false; + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } - } - } - if(revealDisplay) + } + } + if(revealDisplay) return revealDisplay->CheckUserInput(key); - return false; + return false; } MTGRevealingCards * MTGRevealingCards::clone() const { - return NEW MTGRevealingCards(*this); + return NEW MTGRevealingCards(*this); } MTGRevealingCards::~MTGRevealingCards() { - for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) - SAFE_DELETE(*it); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - SAFE_DELETE(*it); + for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) + SAFE_DELETE(*it); + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + SAFE_DELETE(*it); } int MTGRevealingCards::receiveEvent(WEvent* e) { - if (WEventZoneChange* event = dynamic_cast(e)) - { - if (event->from == zone) - { - CardView* t; - if (event->card->view) - t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + if (WEventZoneChange* event = dynamic_cast(e)) + { + if (event->from == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); else t = NEW CardView(CardView::nullZone, event->card, (float)x, (float)y); - //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. - //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than - //they should be, possibly someone being to over cautious. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); + //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. + //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than + //they should be, possibly someone being to over cautious. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); return 1; - } - } - return 0; + } + } + return 0; } @@ -532,353 +532,353 @@ int MTGRevealingCards::receiveEvent(WEvent* e) ///delayed changes the order, makes the ability fire after the 2nd reveal is finished. /// MTGScryCards::MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string coreAbility) : - MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) + MTGAbility(observer, _id, card), CardDisplay(_id, game, x, y, listener, NULL, nb_displayed_items) { - abilityToCast = NULL; - revealDisplay = NULL; - abilityFirst = NULL; - abilitySecond = NULL; - abilityString = coreAbility; - delayedAbilityString = ""; - revealTopAmount = 1;//scry, then reveal the top card and do effect. + abilityToCast = NULL; + revealDisplay = NULL; + abilityFirst = NULL; + abilitySecond = NULL; + abilityString = coreAbility; + delayedAbilityString = ""; + revealTopAmount = 1;//scry, then reveal the top card and do effect. - initCD = false; - RevealZone = source->controller()->game->reveal; - zone =RevealZone; - RevealFromZone = source->controller()->game->library; + initCD = false; + RevealZone = source->controller()->game->reveal; + zone =RevealZone; + RevealFromZone = source->controller()->game->library; - vectoramount = parseBetween(coreAbility, "", " "); - if (amount.size()) - { - number = amount[1]; - } + vectoramount = parseBetween(coreAbility, "", " "); + if (amount.size()) + { + number = amount[1]; + } - vectordifferentZone = parseBetween(coreAbility, "scryzone(", ")"); - if (differentZone.size()) - { - RevealFromZone = MTGGameZone::stringToZone(game, differentZone[1], source, NULL); - } + vectordifferentZone = parseBetween(coreAbility, "scryzone(", ")"); + if (differentZone.size()) + { + RevealFromZone = MTGGameZone::stringToZone(game, differentZone[1], source, NULL); + } - abilityOne = "name(Place on top) target(*|myreveal) moveto(mylibrary)"; + abilityOne = "name(Place on top) target(*|myreveal) moveto(mylibrary)"; delayed = coreAbility.find("delayed") != string::npos; - dontRevealAfter = coreAbility.find("dontshow") != string::npos; - if(dontRevealAfter) - revealTopAmount = 0; - vectorsecond = parseBetween(coreAbility, "scrycore ", " scrycoreend"); - if (second.size()) - { - if (delayed) - { - abilityTwo = "target(*|reveal) name(Reveal the top card) donothing"; - delayedAbilityString = second[1]; - } - else - abilityTwo = second[1]; - } + dontRevealAfter = coreAbility.find("dontshow") != string::npos; + if(dontRevealAfter) + revealTopAmount = 0; + vectorsecond = parseBetween(coreAbility, "scrycore ", " scrycoreend"); + if (second.size()) + { + if (delayed) + { + abilityTwo = "target(*|reveal) name(Reveal the top card) donothing"; + delayedAbilityString = second[1]; + } + else + abilityTwo = second[1]; + } - + } void MTGScryCards::Update(float dt) { - if (game->OpenedDisplay != this->revealDisplay && !initCD) - return; - if (game->mLayers->actionLayer()->menuObject) - return; - if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) - { - WParsedInt nbCardP(number, NULL, source); - nbCard = nbCardP.getValue(); - initDisplay(nbCard); - toResolve(); - } - initCD = true; - if (!zone->cards.size() && abilitySecond) - { - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; - this->removeFromGame(); - } - if (revealDisplay) - { - revealDisplay->Update(dt); - Render(); - } - MTGAbility::Update(dt); + if (game->OpenedDisplay != this->revealDisplay && !initCD) + return; + if (game->mLayers->actionLayer()->menuObject) + return; + if (!source->getObserver()->mLayers->actionLayer()->getCurrentTargetChooser() && !revealDisplay && !initCD) + { + WParsedInt nbCardP(number, NULL, source); + nbCard = nbCardP.getValue(); + initDisplay(nbCard); + toResolve(); + } + initCD = true; + if (!zone->cards.size() && abilitySecond) + { + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; + this->removeFromGame(); + } + if (revealDisplay) + { + revealDisplay->Update(dt); + Render(); + } + MTGAbility::Update(dt); } void MTGScryCards::initDisplay(int value) { - if (RevealZone->cards.size()) - { - do - { - MTGCardInstance * toMove = RevealZone->cards[0]; - if (toMove) - { - MTGAbility * a = NEW AALibraryBottom(game, getMaxId(), source, toMove); - a->oneShot = 1; - a->resolve(); - SAFE_DELETE(a); - } - } while (RevealZone->cards.size()); + if (RevealZone->cards.size()) + { + do + { + MTGCardInstance * toMove = RevealZone->cards[0]; + if (toMove) + { + MTGAbility * a = NEW AALibraryBottom(game, getMaxId(), source, toMove); + a->oneShot = 1; + a->resolve(); + SAFE_DELETE(a); + } + } while (RevealZone->cards.size()); - game->Update(0); - revealDisplay = NULL; - game->OpenedDisplay = revealDisplay; - } - int adjust = 0; - switch (value) - { - case 1:adjust = 120; break; - case 2:adjust = 145; break; - case 3:adjust = 175; break; - case 4:adjust = 200; break; - case 5:adjust = 225; break; - default:adjust = 225; break; - } - revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); - revealDisplay->zone = RevealFromZone; - trashDisplays.push_back(revealDisplay); - for (int i = 0; i < value; i++) - { - if (RevealFromZone->nb_cards - 1 < 0) - break; - MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; - if (toMove) - { - CardView* t; - t = NEW CardView(CardView::nullZone, toMove, 0, 0); - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - cards.push_back(t); - source->controller()->game->putInZone(toMove, RevealFromZone, RevealZone); - source->revealedLast = toMove; - } - } - revealDisplay->init(RevealZone); - revealDisplay->zone = RevealZone; - game->OpenedDisplay = revealDisplay; + game->Update(0); + revealDisplay = NULL; + game->OpenedDisplay = revealDisplay; + } + int adjust = 0; + switch (value) + { + case 1:adjust = 120; break; + case 2:adjust = 145; break; + case 3:adjust = 175; break; + case 4:adjust = 200; break; + case 5:adjust = 225; break; + default:adjust = 225; break; + } + revealDisplay = NEW RevealDisplay(1, game, SCREEN_WIDTH - adjust, SCREEN_HEIGHT, listener, NULL, nbCard > 5 ? 5 : nbCard); + revealDisplay->zone = RevealFromZone; + trashDisplays.push_back(revealDisplay); + for (int i = 0; i < value; i++) + { + if (RevealFromZone->nb_cards - 1 < 0) + break; + MTGCardInstance * toMove = RevealFromZone->cards[RevealFromZone->nb_cards - 1]; + if (toMove) + { + CardView* t; + t = NEW CardView(CardView::nullZone, toMove, 0, 0); + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + cards.push_back(t); + source->controller()->game->putInZone(toMove, RevealFromZone, RevealZone); + source->revealedLast = toMove; + } + } + revealDisplay->init(RevealZone); + revealDisplay->zone = RevealZone; + game->OpenedDisplay = revealDisplay; } int MTGScryCards::testDestroy() { - if (game->mExtraPayment) - return 0; - if (revealDisplay) - return 0; - if (zone->cards.size()) - return 0; - if (!initCD) - return 0; - if (game->mLayers->actionLayer()->menuObject) - return 0; - if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) - return 0; + if (game->mExtraPayment) + return 0; + if (revealDisplay) + return 0; + if (zone->cards.size()) + return 0; + if (!initCD) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(abilityFirst) != -1) + return 0; - return 1; + return 1; } int MTGScryCards::toResolve() { - //scry will always have valid targets. - abilityFirst = contructAbility(abilityOne); - game->addObserver(abilityFirst); - return 1; + //scry will always have valid targets. + abilityFirst = contructAbility(abilityOne); + game->addObserver(abilityFirst); + return 1; } MTGAbility * MTGScryCards::contructAbility(string abilityToMake) { - AbilityFactory af(game); - abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); - if (!abilityToCast) - return NULL; - abilityToCast->canBeInterrupted = false; - abilityToCast->forceDestroy = 1; - return abilityToCast; + AbilityFactory af(game); + abilityToCast = af.parseMagicLine(abilityToMake, getMaxId(), NULL, source, false); + if (!abilityToCast) + return NULL; + abilityToCast->canBeInterrupted = false; + abilityToCast->forceDestroy = 1; + return abilityToCast; } void MTGScryCards::Render() { - if (!revealDisplay) - return; - CheckUserInput(mEngine->ReadButton()); - if (revealDisplay) - { - revealDisplay->CheckUserInput(mEngine->ReadButton()); - revealDisplay->Render(); - } - return; + if (!revealDisplay) + return; + CheckUserInput(mEngine->ReadButton()); + if (revealDisplay) + { + revealDisplay->CheckUserInput(mEngine->ReadButton()); + revealDisplay->Render(); + } + return; } bool MTGScryCards::CheckUserInput(JButton key) { - //DO NOT REFACTOR BELOW - TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); - if (this->source->controller()->isAI()) - {//ai doesnt click button, and the engine has no way of knowing whos clicking button - //for now we will cancel interrupts made when ai is making choice - //in the future we will need a way to find out if the human is pressing the keys and which player. - if (this->source->controller() != game->isInterrupting) - game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); - } - if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key) - { - if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) - { - tc->done = true; - tc->forceTargetListReadyByPlayer = 1; - if (!abilitySecond && !tc->getNbTargets() && tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(0); - if (zone->cards.size() && abilityFirst->testDestroy()) - { - initDisplay(revealTopAmount); - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } - } - else if (tc->source) - { - tc->source->getObserver()->cardClick(tc->source, 0, false); - } - } - else if (!tc && !abilitySecond) - { - CheckUserInput(JGE_BTN_OK); - } - return false; - } - if (JGE_BTN_OK == key) - { - if (!tc && !abilitySecond) - { - if (abilityFirst) - { - abilityFirst->removeFromGame(); - game->mLayers->stackLayer()->Remove(abilityFirst); - } - game->Update(1); + //DO NOT REFACTOR BELOW + TargetChooser * tc = this->observer->mLayers->actionLayer()->getCurrentTargetChooser(); + if (this->source->controller()->isAI()) + {//ai doesnt click button, and the engine has no way of knowing whos clicking button + //for now we will cancel interrupts made when ai is making choice + //in the future we will need a way to find out if the human is pressing the keys and which player. + if (this->source->controller() != game->isInterrupting) + game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); + } + if (JGE_BTN_SEC == key || JGE_BTN_PREV == key || JGE_BTN_NEXT == key || JGE_BTN_MENU == key) + { + if (tc && (tc->targetMin == false || tc->maxtargets == TargetChooser::UNLITMITED_TARGETS)) + { + tc->done = true; + tc->forceTargetListReadyByPlayer = 1; + if (!abilitySecond && !tc->getNbTargets() && tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + if (abilityFirst)///some abilities resolve themselves and remove faster than you can removethem from the game. + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(0); + if (zone->cards.size() && abilityFirst->testDestroy()) + { + initDisplay(revealTopAmount); + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } + } + else if (tc->source) + { + tc->source->getObserver()->cardClick(tc->source, 0, false); + } + } + else if (!tc && !abilitySecond) + { + CheckUserInput(JGE_BTN_OK); + } + return false; + } + if (JGE_BTN_OK == key) + { + if (!tc && !abilitySecond) + { + if (abilityFirst) + { + abilityFirst->removeFromGame(); + game->mLayers->stackLayer()->Remove(abilityFirst); + } + game->Update(1); - if (zone->cards.size() || (revealDisplay && !zone->cards.size())) - { - initDisplay(revealTopAmount); - abilitySecond = contructAbility(abilityTwo); - game->addObserver(abilitySecond); - } + if (zone->cards.size() || (revealDisplay && !zone->cards.size())) + { + initDisplay(revealTopAmount); + abilitySecond = contructAbility(abilityTwo); + game->addObserver(abilitySecond); + } - } - if (!tc && abilitySecond && abilitySecond->testDestroy()) - { - do - { - if (!RevealZone->cards.size()) - break; - MTGCardInstance * toMove = RevealZone->cards[0]; - if (toMove) - { - source->revealedLast = toMove; - MTGAbility * a = NEW AAMover(game, getMaxId(), source, toMove,"library", "Place on top"); - a->oneShot = true; - a->resolve(); - SAFE_DELETE(a); - } - } while (RevealZone->cards.size()); + } + if (!tc && abilitySecond && abilitySecond->testDestroy()) + { + do + { + if (!RevealZone->cards.size()) + break; + MTGCardInstance * toMove = RevealZone->cards[0]; + if (toMove) + { + source->revealedLast = toMove; + MTGAbility * a = NEW AAMover(game, getMaxId(), source, toMove,"library", "Place on top"); + a->oneShot = true; + a->resolve(); + SAFE_DELETE(a); + } + } while (RevealZone->cards.size()); - if (delayed) - { - MTGAbility * delayedA = contructAbility(delayedAbilityString); - if (delayedA->oneShot) - { - delayedA->resolve(); - SAFE_DELETE(delayedA); - } - else - delayedA->addToGame(); - - } - } - } - if (revealDisplay) - return revealDisplay->CheckUserInput(key); - return false; + if (delayed) + { + MTGAbility * delayedA = contructAbility(delayedAbilityString); + if (delayedA->oneShot) + { + delayedA->resolve(); + SAFE_DELETE(delayedA); + } + else + delayedA->addToGame(); + + } + } + } + if (revealDisplay) + return revealDisplay->CheckUserInput(key); + return false; } MTGScryCards * MTGScryCards::clone() const { - return NEW MTGScryCards(*this); + return NEW MTGScryCards(*this); } MTGScryCards::~MTGScryCards() { - for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) - SAFE_DELETE(*it); - for (vector::iterator it = cards.begin(); it != cards.end(); ++it) - SAFE_DELETE(*it); + for (vector::iterator it = trashDisplays.begin(); it != trashDisplays.end(); ++it) + SAFE_DELETE(*it); + for (vector::iterator it = cards.begin(); it != cards.end(); ++it) + SAFE_DELETE(*it); } int MTGScryCards::receiveEvent(WEvent* e) { - if (WEventZoneChange* event = dynamic_cast(e)) - { - if (event->from == zone) - { - CardView* t; - if (event->card->view) - t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); + if (WEventZoneChange* event = dynamic_cast(e)) + { + if (event->from == zone) + { + CardView* t; + if (event->card->view) + t = NEW CardView(CardView::nullZone, event->card, *(event->card->view)); else t = NEW CardView(CardView::nullZone, event->card, (float)x, (float)y); - //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. - //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than - //they should be, possibly someone being to over cautious. - t->actX = SCREEN_WIDTH; - t->actY = SCREEN_HEIGHT * -2; - //correct cards x and y, last known location was the reveal display. - cards.push_back(t); + //we store copies of the card view since moving to and from card displays also deletes the guis stored in cards. + //GuiLayer::resetObjects() is the main reason we need to back them up. card views are set to NULL maybe more often than + //they should be, possibly someone being to over cautious. + t->actX = SCREEN_WIDTH; + t->actY = SCREEN_HEIGHT * -2; + //correct cards x and y, last known location was the reveal display. + cards.push_back(t); return 1; - } - } - return 0; + } + } + return 0; } //scry wrapper GenericScryAbility::GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, - Targetable * target, string _howMany) : - ActivatedAbility(observer, id, source, NULL), howMany(_howMany) + Targetable * target, string _howMany) : + ActivatedAbility(observer, id, source, NULL), howMany(_howMany) { - this->GetId(); + this->GetId(); } int GenericScryAbility::resolve() { - MTGAbility * ability = NEW MTGScryCards(game, this->GetId(), source, howMany); - ability->addToGame(); - return 1; + MTGAbility * ability = NEW MTGScryCards(game, this->GetId(), source, howMany); + ability->addToGame(); + return 1; } const string GenericScryAbility::getMenuText() { - return "Scry Cards"; + return "Scry Cards"; } GenericScryAbility * GenericScryAbility::clone() const { - GenericScryAbility * a = NEW GenericScryAbility(*this); - return a; + GenericScryAbility * a = NEW GenericScryAbility(*this); + return a; } GenericScryAbility::~GenericScryAbility() { - //SAFE_DELETE(ability); + //SAFE_DELETE(ability); } //////////////////////// @@ -1319,7 +1319,7 @@ int AACopier::resolve() MTGCard* clone = MTGCollection()->getCardById(_target->copiedID); MTGCardInstance * myClone = NEW MTGCardInstance(clone, source->controller()->game); source->copy(myClone); - SAFE_DELETE(myClone); + SAFE_DELETE(myClone); source->isACopier = true; source->copiedID = _target->getMTGId(); source->modifiedbAbi = _target->modifiedbAbi; @@ -2184,9 +2184,9 @@ int GenericPaidAbility::resolve() } else { - //dangerous code below, parse a string line that might not exist. baseAbilityStrSplit[0] - //you either have a string and do stuff, or dont and leave the ability - //not fixing this since its been heavily modified from the orginal implementation. + //dangerous code below, parse a string line that might not exist. baseAbilityStrSplit[0] + //you either have a string and do stuff, or dont and leave the ability + //not fixing this since its been heavily modified from the orginal implementation. nomenu = true; baseAbility = Af.parseMagicLine(baseAbilityStrSplit[0], this->GetId(), NULL, source); baseAbility->target = target; @@ -2381,7 +2381,7 @@ int AAEPIC::resolve() MTGCardInstance * _target = (MTGCardInstance *)target; if(FField) _target->controller()->forcefield = 1; - else + else _target->controller()->epic = 1; return 1; } @@ -2733,7 +2733,7 @@ AAFrozen::AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCa ActivatedAbility(observer, id, card, _cost, 0) { target = _target; - freeze = tap; + freeze = tap; } int AAFrozen::resolve() @@ -2743,10 +2743,10 @@ int AAFrozen::resolve() { while (_target->next) _target = _target->next; //This is for cards such as rampant growth - if (freeze) - { - _target->tap();//easier to manage for cards that allow you to tap and also freeze. - } + if (freeze) + { + _target->tap();//easier to manage for cards that allow you to tap and also freeze. + } _target->frozen += 1; } return 1; @@ -3887,13 +3887,13 @@ int AAMover::resolve() delete spell; return 1; } - if (destZone == game->players[i]->game->graveyard && fromZone == game->players[i]->game->hand) - { - //movers that take a card from hand and place them in graveyard are always discards. we send an event for it here. + if (destZone == game->players[i]->game->graveyard && fromZone == game->players[i]->game->hand) + { + //movers that take a card from hand and place them in graveyard are always discards. we send an event for it here. - WEvent * e = NEW WEventCardDiscard(_target); - game->receiveEvent(e); - } + WEvent * e = NEW WEventCardDiscard(_target); + game->receiveEvent(e); + } } @@ -4301,36 +4301,36 @@ AARemoveMana::~AARemoveMana() //Bestow ABestow::ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) : - ActivatedAbility(observer, id, card, _cost, 0) + ActivatedAbility(observer, id, card, _cost, 0) { - target = _target; - aType = MTGAbility::TAPPER; - _card = card; + target = _target; + aType = MTGAbility::TAPPER; + _card = card; } int ABestow::resolve() { - if (target) - { - if (_card->hasType("creature")) - { - _card->removeType("creature"); - _card->addType("aura"); - } - _card->target = (MTGCardInstance*)target; - _card->isBestowed = true; - } - return 1; + if (target) + { + if (_card->hasType("creature")) + { + _card->removeType("creature"); + _card->addType("aura"); + } + _card->target = (MTGCardInstance*)target; + _card->isBestowed = true; + } + return 1; } const string ABestow::getMenuText() { - return "Bestow"; + return "Bestow"; } ABestow * ABestow::clone() const { - return NEW ABestow(*this); + return NEW ABestow(*this); } //Tapper @@ -4415,48 +4415,48 @@ AAWhatsMax * AAWhatsMax::clone() const } //set X value AAWhatsX::AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, int value, MTGAbility * _costRule) : - ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) + ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) { } int AAWhatsX::resolve() { - if (source) - { - source->setX = value; - - } - costRule->reactToClick(source); - return 1; + if (source) + { + source->setX = value; + + } + costRule->reactToClick(source); + return 1; } AAWhatsX * AAWhatsX::clone() const { - return NEW AAWhatsX(*this); + return NEW AAWhatsX(*this); } //count objects on field before doing an effect AACountObject::AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, ManaCost * _cost, string value) : - ActivatedAbility(observer, id, card, _cost, 0), value(value) + ActivatedAbility(observer, id, card, _cost, 0), value(value) { } int AACountObject::resolve() { - if (source) - { - int amount = 0; - WParsedInt * use = NEW WParsedInt(value, NULL, source); - amount = use->getValue(); - source->CountedObjects = amount; - SAFE_DELETE(use); - } - return 1; + if (source) + { + int amount = 0; + WParsedInt * use = NEW WParsedInt(value, NULL, source); + amount = use->getValue(); + source->CountedObjects = amount; + SAFE_DELETE(use); + } + return 1; } AACountObject * AACountObject::clone() const { - return NEW AACountObject(*this); + return NEW AACountObject(*this); } // Win Game @@ -4750,16 +4750,16 @@ void MenuAbility::Update(float dt) { if(game->mExtraPayment->isPaymentSet() && game->mExtraPayment->canPay() ) { - if (game->mExtraPayment->costs.size()) - { - if (game->mExtraPayment->costs[0]->costToPay) - { - ManaCost * diff = game->mExtraPayment->costs[0]->costToPay; - ManaCost * c = source->controller()->getManaPool()->Diff(diff); - source->X = c->getCost(Constants::NB_Colors); - delete c; - } - } + if (game->mExtraPayment->costs.size()) + { + if (game->mExtraPayment->costs[0]->costToPay) + { + ManaCost * diff = game->mExtraPayment->costs[0]->costToPay; + ManaCost * c = source->controller()->getManaPool()->Diff(diff); + source->X = c->getCost(Constants::NB_Colors); + delete c; + } + } game->mExtraPayment->doPay(); game->mLayers->actionLayer()->reactToClick(game->mExtraPayment->action, game->mExtraPayment->source); @@ -5013,7 +5013,7 @@ MultiAbility * MultiAbility::clone() const a->abilities.clear(); for (size_t i = 0; i < abilities.size(); ++i) { - if(abilities[i]) + if(abilities[i]) a->abilities.push_back(abilities[i]->clone()); } return a; @@ -6134,7 +6134,7 @@ int AProduceMana::produce() { AManaProducer *amp = NEW AManaProducer(game, game->mLayers->actionLayer()->getMaxId(), source, source->controller(), ManaCost::parseManaCost(ManaDescription,NULL,source), NULL, 0,"",false); amp->resolve(); - SAFE_DELETE(amp);//once you call resolve() on a ability, you can safely delete it. + SAFE_DELETE(amp);//once you call resolve() on a ability, you can safely delete it. } return 1; } @@ -6613,108 +6613,108 @@ AShackleWrapper::~AShackleWrapper() //grant AGrant::AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : - MTGAbility(observer, _id, card) + MTGAbility(observer, _id, card) { - Granted = _Grant; - target = _target; - Blessed = NULL; - resolved = false; - toGrant = NULL; + Granted = _Grant; + target = _target; + Blessed = NULL; + resolved = false; + toGrant = NULL; } void AGrant::Update(float dt) { - if (resolved == false) - { - resolved = true; - resolveGrant(); - } + if (resolved == false) + { + resolved = true; + resolveGrant(); + } - if (!source->isTapped() || !source->isInPlay(game)) - { - if (Blessed == NULL || !Blessed->isInPlay(game)) - MTGAbility::Update(dt); - MTGCardInstance * _target = Blessed; - removeGranted(_target); - } - else - resolveGrant(); - MTGAbility::Update(dt); + if (!source->isTapped() || !source->isInPlay(game)) + { + if (Blessed == NULL || !Blessed->isInPlay(game)) + MTGAbility::Update(dt); + MTGCardInstance * _target = Blessed; + removeGranted(_target); + } + else + resolveGrant(); + MTGAbility::Update(dt); } void AGrant::resolveGrant() { - if (toGrant) return; - MTGCardInstance * _target = (MTGCardInstance *)target; - if (_target) - { - toGrant = Granted->clone(); - toGrant->target = _target; - toGrant->addToGame(); - Blessed = _target; - } + if (toGrant) return; + MTGCardInstance * _target = (MTGCardInstance *)target; + if (_target) + { + toGrant = Granted->clone(); + toGrant->target = _target; + toGrant->addToGame(); + Blessed = _target; + } } void AGrant::removeGranted(MTGCardInstance* _target) { - if (!toGrant) return; - game->removeObserver(toGrant); - game->removeObserver(this); - Blessed = NULL; - return; + if (!toGrant) return; + game->removeObserver(toGrant); + game->removeObserver(this); + Blessed = NULL; + return; } int AGrant::resolve() { - return 0; + return 0; } const string AGrant::getMenuText() { - return Granted->getMenuText(); + return Granted->getMenuText(); } AGrant * AGrant::clone() const { - AGrant * a = NEW AGrant(*this); - a->forceDestroy = -1; - a->Granted = Granted->clone(); - return a; + AGrant * a = NEW AGrant(*this); + a->forceDestroy = -1; + a->Granted = Granted->clone(); + return a; }; AGrant::~AGrant() { - SAFE_DELETE(Granted); + SAFE_DELETE(Granted); } AGrantWrapper::AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : - InstantAbility(observer, _id, source, _target), Granted(_Grant) + InstantAbility(observer, _id, source, _target), Granted(_Grant) { - ability = NEW AGrant(observer, _id, card, _target,_Grant); + ability = NEW AGrant(observer, _id, card, _target,_Grant); } int AGrantWrapper::resolve() { - AGrant * a = ability->clone(); - a->target = target; - a->addToGame(); - return 1; + AGrant * a = ability->clone(); + a->target = target; + a->addToGame(); + return 1; } const string AGrantWrapper::getMenuText() { - return "Grant"; + return "Grant"; } AGrantWrapper * AGrantWrapper::clone() const { - AGrantWrapper * a = NEW AGrantWrapper(*this); - a->ability = this->ability->clone(); - a->oneShot = 1; - return a; + AGrantWrapper * a = NEW AGrantWrapper(*this); + a->ability = this->ability->clone(); + a->oneShot = 1; + return a; } AGrantWrapper::~AGrantWrapper() { - SAFE_DELETE(ability); + SAFE_DELETE(ability); } //a blink @@ -7324,8 +7324,8 @@ int AACastCard::resolveSpell() else copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack,noEvent); copy->changeController(source->controller(),true); - if(asNormalMadness) - copy->MadnessPlay = true; + if(asNormalMadness) + copy->MadnessPlay = true; } else { diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index d8fc5dd65..dd46a3103 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -72,10 +72,10 @@ int ExtraCost::setPayment(MTGCardInstance * card) if (tc) { result = tc->addTarget(card); - //this is flawed logic, we need to fix. if there is a target in list - //we return targetready instead, the card is not pushed back into list - //how ever, it is made the target becuase the result is 1 even if we couldnt - //target it with the targetchooser. + //this is flawed logic, we need to fix. if there is a target in list + //we return targetready instead, the card is not pushed back into list + //how ever, it is made the target becuase the result is 1 even if we couldnt + //target it with the targetchooser. if (result) { target = card; @@ -166,7 +166,7 @@ int SnowCost::isPaymentSet() return 1; else return 0; - } + } } return 0; } @@ -763,7 +763,7 @@ int TapTargetCost::doPay() if (target) { - source->storedCard = target->createSnapShot(); + source->storedCard = target->createSnapShot(); _target->tap(); target = NULL; if (tc) @@ -807,7 +807,7 @@ int UnTapTargetCost::doPay() if (target) { - source->storedCard = target->createSnapShot(); + source->storedCard = target->createSnapShot(); _target->untap(); target = NULL; if (tc) @@ -929,189 +929,189 @@ int Ninja::doPay() //Convoke Convoke * Convoke::clone() const { - Convoke * ec = NEW Convoke(*this); - if (tc) - ec->tc = tc->clone(); - return ec; + Convoke * ec = NEW Convoke(*this); + if (tc) + ec->tc = tc->clone(); + return ec; } Convoke::Convoke(TargetChooser *_tc) : - ExtraCost("Select Cards To Tap", _tc) + ExtraCost("Select Cards To Tap", _tc) { } int Convoke::canPay() { - return isPaymentSet(); + return isPaymentSet(); } int Convoke::isPaymentSet() { - if (target && target->isTapped()) - { - tc->removeTarget(target); - target->isExtraCostTarget = false; - target = NULL; - return 0; - } - ManaCost * toReduce = getReduction(); - if (target && (!source->controller()->getManaPool()->canAfford(toReduce))) - { - target = NULL; - SAFE_DELETE(toReduce); - return 0; - } - if (target && (source->controller()->getManaPool()->canAfford(toReduce))) - { - SAFE_DELETE(toReduce); - return 1; - } - SAFE_DELETE(toReduce); - return 0; + if (target && target->isTapped()) + { + tc->removeTarget(target); + target->isExtraCostTarget = false; + target = NULL; + return 0; + } + ManaCost * toReduce = getReduction(); + if (target && (!source->controller()->getManaPool()->canAfford(toReduce))) + { + target = NULL; + SAFE_DELETE(toReduce); + return 0; + } + if (target && (source->controller()->getManaPool()->canAfford(toReduce))) + { + SAFE_DELETE(toReduce); + return 1; + } + SAFE_DELETE(toReduce); + return 0; } ManaCost * Convoke::getReduction() { - ManaCost * toReduce = NEW ManaCost(source->getManaCost()); - tc->maxtargets = source->getManaCost()->getConvertedCost(); - if (tc->getNbTargets()) - { - vectortargetlist = tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - bool next = false; - for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) - { - if (next == true) - break; - MTGCardInstance * targetCard = dynamic_cast(*it); - if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i)) - { - toReduce->remove(i, 1); - next = true; - } - else - { - toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1); - next = true; - } - } - } - //if we didnt find it payable one way, lets try again backwards. - if (!source->controller()->getManaPool()->canAfford(toReduce)) - { - SAFE_DELETE(toReduce); - toReduce = NEW ManaCost(source->getManaCost()); - for (vector::reverse_iterator it = targetlist.rbegin(); it != targetlist.rend(); it++) - { - bool next = false; - for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) - { - if (next == true) - break; - MTGCardInstance * targetCard = dynamic_cast(*it); - if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i)) - { - toReduce->remove(i, 1); - next = true; - } - else - { - toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1); - next = true; - } - } - } - } - } - return toReduce; + ManaCost * toReduce = NEW ManaCost(source->getManaCost()); + tc->maxtargets = source->getManaCost()->getConvertedCost(); + if (tc->getNbTargets()) + { + vectortargetlist = tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + bool next = false; + for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) + { + if (next == true) + break; + MTGCardInstance * targetCard = dynamic_cast(*it); + if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i)) + { + toReduce->remove(i, 1); + next = true; + } + else + { + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1); + next = true; + } + } + } + //if we didnt find it payable one way, lets try again backwards. + if (!source->controller()->getManaPool()->canAfford(toReduce)) + { + SAFE_DELETE(toReduce); + toReduce = NEW ManaCost(source->getManaCost()); + for (vector::reverse_iterator it = targetlist.rbegin(); it != targetlist.rend(); it++) + { + bool next = false; + for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) + { + if (next == true) + break; + MTGCardInstance * targetCard = dynamic_cast(*it); + if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i)) + { + toReduce->remove(i, 1); + next = true; + } + else + { + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1); + next = true; + } + } + } + } + } + return toReduce; } int Convoke::doPay() { - if (target && tc->getNbTargets()) - { - ManaCost * toReduce = getReduction(); - target->controller()->getManaPool()->pay(toReduce); - SAFE_DELETE(toReduce); - vectortargetlist = tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - MTGCardInstance * targetCard = dynamic_cast(*it); - source->storedCard = targetCard->createSnapShot(); - targetCard->tap(); - } - if (tc) - tc->initTargets(); - return 1; - } - return 0; + if (target && tc->getNbTargets()) + { + ManaCost * toReduce = getReduction(); + target->controller()->getManaPool()->pay(toReduce); + SAFE_DELETE(toReduce); + vectortargetlist = tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + MTGCardInstance * targetCard = dynamic_cast(*it); + source->storedCard = targetCard->createSnapShot(); + targetCard->tap(); + } + if (tc) + tc->initTargets(); + return 1; + } + return 0; } //DELVE Delve * Delve::clone() const { - Delve * ec = NEW Delve(*this); - if (tc) - ec->tc = tc->clone(); - return ec; + Delve * ec = NEW Delve(*this); + if (tc) + ec->tc = tc->clone(); + return ec; } Delve::Delve(TargetChooser *_tc) : - ExtraCost("Select Cards To Exile", _tc) + ExtraCost("Select Cards To Exile", _tc) { } int Delve::canPay() { - return isPaymentSet(); + return isPaymentSet(); } int Delve::isPaymentSet() { - ManaCost * toReduce = NEW ManaCost(source->getManaCost()); - tc->maxtargets = source->getManaCost()->getCost(Constants::MTG_COLOR_ARTIFACT); - if (tc->getNbTargets()) - { - toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets()); - } - if (target && (!source->controller()->getManaPool()->canAfford(toReduce))) - { - target = NULL; - SAFE_DELETE(toReduce); - return 0; - } - if (target && (source->controller()->getManaPool()->canAfford(toReduce))) - { - SAFE_DELETE(toReduce); - return 1; - } - SAFE_DELETE(toReduce); - return 0; + ManaCost * toReduce = NEW ManaCost(source->getManaCost()); + tc->maxtargets = source->getManaCost()->getCost(Constants::MTG_COLOR_ARTIFACT); + if (tc->getNbTargets()) + { + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets()); + } + if (target && (!source->controller()->getManaPool()->canAfford(toReduce))) + { + target = NULL; + SAFE_DELETE(toReduce); + return 0; + } + if (target && (source->controller()->getManaPool()->canAfford(toReduce))) + { + SAFE_DELETE(toReduce); + return 1; + } + SAFE_DELETE(toReduce); + return 0; } int Delve::doPay() { - if (target && tc->getNbTargets()) - { - ManaCost * toReduce = NEW ManaCost(source->getManaCost()); + if (target && tc->getNbTargets()) + { + ManaCost * toReduce = NEW ManaCost(source->getManaCost()); - toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets()); + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets()); - target->controller()->getManaPool()->pay(toReduce); - SAFE_DELETE(toReduce); - vectortargetlist = tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - MTGCardInstance * targetCard = dynamic_cast(*it); - source->storedCard = targetCard->createSnapShot(); - targetCard->controller()->game->putInExile(targetCard); - } - if (tc) - tc->initTargets(); - return 1; - } - return 0; + target->controller()->getManaPool()->pay(toReduce); + SAFE_DELETE(toReduce); + vectortargetlist = tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + MTGCardInstance * targetCard = dynamic_cast(*it); + source->storedCard = targetCard->createSnapShot(); + targetCard->controller()->game->putInExile(targetCard); + } + if (tc) + tc->initTargets(); + return 1; + } + return 0; } /////////////// @@ -1402,41 +1402,41 @@ int ExtraCosts::tryToSetPayment(MTGCardInstance * card) { for(size_t k = 0; k < costs.size(); k++) { - if (card == costs[k]->target) - { - //tapping or sacrificing a target to pay for its own cost - //is allowed, unless the source is already being tapped and contains a tap target - //or sacced and contains a sactarget - //cost like {t}{s(creature)} the source is allowed to be targeted for this - //if it is a creature. these cases below should be added whenever we a need - //for extra cost that have both a source and target version used on cards. - if (dynamic_cast(costs[k])) - { - for (size_t tapCheck = 0; tapCheck < costs.size(); tapCheck++) - { - if (dynamic_cast(costs[tapCheck])) - { - return 0;//{t}{t(creature)} - } - } + if (card == costs[k]->target) + { + //tapping or sacrificing a target to pay for its own cost + //is allowed, unless the source is already being tapped and contains a tap target + //or sacced and contains a sactarget + //cost like {t}{s(creature)} the source is allowed to be targeted for this + //if it is a creature. these cases below should be added whenever we a need + //for extra cost that have both a source and target version used on cards. + if (dynamic_cast(costs[k])) + { + for (size_t tapCheck = 0; tapCheck < costs.size(); tapCheck++) + { + if (dynamic_cast(costs[tapCheck])) + { + return 0;//{t}{t(creature)} + } + } - } - else if (SacrificeCost * checking = dynamic_cast(costs[k])) - { - for (size_t sacCheck = 0; sacCheck < costs.size(); sacCheck++) - { - SacrificeCost * checking2 = dynamic_cast(costs[sacCheck]); - if (checking2) - if ((checking->tc != NULL && checking2->tc == NULL) - || (checking->tc == NULL && checking2->tc != NULL)) - { - return 0; //{s}{s(creature)} - } - } - } - else - return 0; - } + } + else if (SacrificeCost * checking = dynamic_cast(costs[k])) + { + for (size_t sacCheck = 0; sacCheck < costs.size(); sacCheck++) + { + SacrificeCost * checking2 = dynamic_cast(costs[sacCheck]); + if (checking2) + if ((checking->tc != NULL && checking2->tc == NULL) + || (checking->tc == NULL && checking2->tc != NULL)) + { + return 0; //{s}{s(creature)} + } + } + } + else + return 0; + } } if (int result = costs[i]->setPayment(card)) { @@ -1481,16 +1481,16 @@ int ExtraCosts::doPay() { costs[i]->target->isExtraCostTarget = false; } - if (costs[i]->tc) - { - vectortargetlist = costs[i]->tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - costs[i]->target = dynamic_cast(*it); - costs[i]->doPay(); - } - } - else + if (costs[i]->tc) + { + vectortargetlist = costs[i]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + costs[i]->target = dynamic_cast(*it); + costs[i]->doPay(); + } + } + else result += costs[i]->doPay(); } return result; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 78db68e96..3d65cd041 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -52,7 +52,7 @@ void GameObserver::cleanup() connectRule = false; actionsList.clear(); gameTurn.clear(); - OpenedDisplay = NULL; + OpenedDisplay = NULL; } GameObserver::~GameObserver() @@ -97,7 +97,7 @@ GameObserver::GameObserver(WResourceManager *output, JGE* input) targetChooser = NULL; cardWaitingForTargets = NULL; mExtraPayment = NULL; - OpenedDisplay = NULL; + OpenedDisplay = NULL; guiOpenDisplay = NULL; gameOver = NULL; phaseRing = NULL; @@ -328,11 +328,11 @@ void GameObserver::userRequestNextGamePhase(bool allowInterrupt, bool log) // Here's what I find weird - if the extra cost is something like a sacrifice, doesn't that imply a TargetChooser? if (WaitForExtraPayment(NULL)) return; - /*if (OpenedDisplay)//dont let us fly through all the phases with grave and library box still open. - { - return;//I want this here, but it locks up on opponents turn, we need to come up with a clever way to close opened - //displays, it makes no sense that you travel through 4 or 5 phases with library or grave still open. - }*/ + /*if (OpenedDisplay)//dont let us fly through all the phases with grave and library box still open. + { + return;//I want this here, but it locks up on opponents turn, we need to come up with a clever way to close opened + //displays, it makes no sense that you travel through 4 or 5 phases with library or grave still open. + }*/ Phase * cPhaseOld = phaseRing->getCurrentPhase(); if (allowInterrupt && ((cPhaseOld->id == MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) || (cPhaseOld->id == MTG_PHASE_COMBATBLOCKERS && combatStep == TRIGGERS) @@ -716,27 +716,27 @@ void GameObserver::gameStateBasedEffects() } } card->bypassTC = false; //turn off bypass - /////////////////////////// - //reset extracost shadows// - /////////////////////////// - card->isExtraCostTarget = false; - if (mExtraPayment != NULL) - { - for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) - { + /////////////////////////// + //reset extracost shadows// + /////////////////////////// + card->isExtraCostTarget = false; + if (mExtraPayment != NULL) + { + for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) + { - if (mExtraPayment->costs[ec]->tc) - { - vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); - for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) - { - Targetable * cardMasked = *it; - dynamic_cast(cardMasked)->isExtraCostTarget = true; - } + if (mExtraPayment->costs[ec]->tc) + { + vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + Targetable * cardMasked = *it; + dynamic_cast(cardMasked)->isExtraCostTarget = true; + } - } - } - } + } + } + } //////////////////////////////////////////////////// //Unattach Equipments that dont have valid targets// //////////////////////////////////////////////////// @@ -759,13 +759,13 @@ void GameObserver::gameStateBasedEffects() /////////////////////////////////////////////////////// //Remove auras that don't have a valid target anymore// /////////////////////////////////////////////////////// - if (card->target && !isInPlay(card->target) && card->isBestowed && card->hasType("aura")) - { - card->removeType("aura"); - card->addType("creature"); - card->target = NULL; - card->isBestowed = false; - } + if (card->target && !isInPlay(card->target) && card->isBestowed && card->hasType("aura")) + { + card->removeType("aura"); + card->addType("creature"); + card->target = NULL; + card->isBestowed = false; + } if ((card->target||card->playerTarget) && !card->hasType(Subtypes::TYPE_EQUIPMENT)) { diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index 9562aba27..9209f5484 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -49,7 +49,7 @@ void GameStateOptions::Start() optionsList->Add(NEW OptionInteger(Options::INTERRUPT_SECONDS, "Seconds to pause for an Interrupt", 20, 1)); optionsList->Add(NEW OptionInteger(Options::INTERRUPTMYSPELLS, "Interrupt my spells")); // optionsList->Add(NEW OptionInteger(Options::INTERRUPTMYABILITIES, "Interrupt my abilities")); - //this is a dev option, not meant for standard play. uncomment if you need to see abilities you own hitting the stack. + //this is a dev option, not meant for standard play. uncomment if you need to see abilities you own hitting the stack. optionsList->Add(NEW OptionInteger(Options::INTERRUPT_SECONDMAIN, "Interrupt opponent's end of turn")); optionsTabs = NEW WGuiTabMenu(); optionsTabs->Add(optionsList); diff --git a/projects/mtg/src/GuiStatic.cpp b/projects/mtg/src/GuiStatic.cpp index d224a0a05..baa30379a 100644 --- a/projects/mtg/src/GuiStatic.cpp +++ b/projects/mtg/src/GuiStatic.cpp @@ -149,18 +149,18 @@ ostream& GuiAvatar::toString(ostream& out) const void GuiGameZone::toggleDisplay() { - if (showCards) - { + if (showCards) + { cd->zone->owner->getObserver()->guiOpenDisplay = NULL; - showCards = 0; - cd->zone->owner->getObserver()->OpenedDisplay = NULL; - } + showCards = 0; + cd->zone->owner->getObserver()->OpenedDisplay = NULL; + } else if(!cd->zone->owner->getObserver()->OpenedDisplay)//one display at a time please. { cd->zone->owner->getObserver()->guiOpenDisplay = this; showCards = 1; cd->init(zone); - cd->zone->owner->getObserver()->OpenedDisplay = cd; + cd->zone->owner->getObserver()->OpenedDisplay = cd; } } diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index fffb8ae10..9dfee7f4d 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -353,23 +353,23 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe return 0; } - check = restriction[i].find("delirium"); - if (check != string::npos) - { - Player * checkCurrent = card->controller(); - MTGGameZone * grave = checkCurrent->game->graveyard; + check = restriction[i].find("delirium"); + if (check != string::npos) + { + Player * checkCurrent = card->controller(); + MTGGameZone * grave = checkCurrent->game->graveyard; - int checkTypesAmount = 0; - if(grave->hasType("creature")) checkTypesAmount++; - if (grave->hasType("enchantment")) checkTypesAmount++; - if (grave->hasType("sorcery")) checkTypesAmount++; - if (grave->hasType("instant")) checkTypesAmount++; - if (grave->hasType("land")) checkTypesAmount++; - if (grave->hasType("artifact")) checkTypesAmount++; - if (grave->hasType("planeswalker")) checkTypesAmount++; - if (checkTypesAmount < 4) - return 0; - } + int checkTypesAmount = 0; + if(grave->hasType("creature")) checkTypesAmount++; + if (grave->hasType("enchantment")) checkTypesAmount++; + if (grave->hasType("sorcery")) checkTypesAmount++; + if (grave->hasType("instant")) checkTypesAmount++; + if (grave->hasType("land")) checkTypesAmount++; + if (grave->hasType("artifact")) checkTypesAmount++; + if (grave->hasType("planeswalker")) checkTypesAmount++; + if (checkTypesAmount < 4) + return 0; + } check = restriction[i].find("miracle"); if(check != string::npos) @@ -380,12 +380,12 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe return 0; } - check = restriction[i].find("madnessplayed"); - if (check != string::npos) - { - if (card->previous && !card->previous->MadnessPlay) - return 0; - } + check = restriction[i].find("madnessplayed"); + if (check != string::npos) + { + if (card->previous && !card->previous->MadnessPlay) + return 0; + } check = restriction[i].find("prowl"); if(check != string::npos) @@ -462,12 +462,12 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe return 0; } - check = restriction[i].find("geared"); - if (check != string::npos) - { - if (card->equipment < 1) - return 0; - } + check = restriction[i].find("geared"); + if (check != string::npos) + { + if (card->equipment < 1) + return 0; + } check = restriction[i].find("canuntap"); if(check != string::npos) @@ -1178,13 +1178,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG observer->addObserver(NEW MTGFlashBackRule(observer, -1)); return NULL; } - //alternative cost type flashback - found = s.find("bestowrule"); - if (found != string::npos) - { - observer->addObserver(NEW MTGBestowRule(observer, -1)); - return NULL; - } + //alternative cost type flashback + found = s.find("bestowrule"); + if (found != string::npos) + { + observer->addObserver(NEW MTGBestowRule(observer, -1)); + return NULL; + } //alternative cost type retrace found = s.find("retracerule"); if(found != string::npos) @@ -1353,53 +1353,53 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG string unchangedS = ""; unchangedS.append(s); - //Reveal:x remove the core so we dont build them prematurely - vectortransPayfound = parseBetween(s, "newability[pay(", " "); - vectortransfound = parseBetween(s,"newability[reveal:"," ");//if we are using reveal inside a newability, let transforms remove the string instead. - vectorabilfound = parseBetween(s, "ability$!name(reveal) reveal:", " "); - if(!abilfound.size()) - abilfound = parseBetween(s, "ability$!reveal:", " ");//see above. this allows us to nest reveals inside these 2 other master classes. while also allowing us to nest them inside reveals. - - found = s.find("pay("); - if (found != string::npos && storedPayString.empty() && !transPayfound.size()) - { - vector splitMayPaystr = parseBetween(s, "pay(", ")", true); - if (splitMayPaystr.size()) - { - storedPayString.append(splitMayPaystr[2]); - s = splitMayPaystr[0]; - s.append("pay("); - s.append(splitMayPaystr[1]); - s.append(")"); - } - } + //Reveal:x remove the core so we dont build them prematurely + vectortransPayfound = parseBetween(s, "newability[pay(", " "); + vectortransfound = parseBetween(s,"newability[reveal:"," ");//if we are using reveal inside a newability, let transforms remove the string instead. + vectorabilfound = parseBetween(s, "ability$!name(reveal) reveal:", " "); + if(!abilfound.size()) + abilfound = parseBetween(s, "ability$!reveal:", " ");//see above. this allows us to nest reveals inside these 2 other master classes. while also allowing us to nest them inside reveals. + + found = s.find("pay("); + if (found != string::npos && storedPayString.empty() && !transPayfound.size()) + { + vector splitMayPaystr = parseBetween(s, "pay(", ")", true); + if (splitMayPaystr.size()) + { + storedPayString.append(splitMayPaystr[2]); + s = splitMayPaystr[0]; + s.append("pay("); + s.append(splitMayPaystr[1]); + s.append(")"); + } + } - vector splitGrant = parseBetween(s, "grant ", " grantend", false); - if (splitGrant.size() && storedAbilityString.empty()) - { - storedAbilityString = splitGrant[1]; - s = splitGrant[0]; - s.append("grant "); - s.append(splitGrant[2]); - } + vector splitGrant = parseBetween(s, "grant ", " grantend", false); + if (splitGrant.size() && storedAbilityString.empty()) + { + storedAbilityString = splitGrant[1]; + s = splitGrant[0]; + s.append("grant "); + s.append(splitGrant[2]); + } - vector splitRevealx = parseBetween(s, "reveal:", " revealend", false); - if (!abilfound.size() && !transfound.size() && splitRevealx.size() && storedAbilityString.empty()) - { - storedAbilityString = splitRevealx[1]; - s = splitRevealx[0]; - s.append("reveal: "); - s.append(splitRevealx[2]); - } + vector splitRevealx = parseBetween(s, "reveal:", " revealend", false); + if (!abilfound.size() && !transfound.size() && splitRevealx.size() && storedAbilityString.empty()) + { + storedAbilityString = splitRevealx[1]; + s = splitRevealx[0]; + s.append("reveal: "); + s.append(splitRevealx[2]); + } - vector splitScryx = parseBetween(s, "scry:", " scryend", false); - if (splitScryx.size() && storedAbilityString.empty()) - { - storedAbilityString = splitScryx[1]; - s = splitScryx[0]; - s.append("scry: "); - s.append(splitScryx[2]); - } + vector splitScryx = parseBetween(s, "scry:", " scryend", false); + if (splitScryx.size() && storedAbilityString.empty()) + { + storedAbilityString = splitScryx[1]; + s = splitScryx[0]; + s.append("scry: "); + s.append(splitScryx[2]); + } found = s.find("transforms(("); if (found != string::npos && storedString.empty()) @@ -1832,25 +1832,25 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } if (end != string::npos) { - ThisDescriptor * td = NULL; + ThisDescriptor * td = NULL; string thisDescriptorString = s.substr(found + header, end - found - header); - vector splitRest = parseBetween(s, "restriction{", "}"); - if (splitRest.size()) - { + vector splitRest = parseBetween(s, "restriction{", "}"); + if (splitRest.size()) + { - } - else - { - ThisDescriptorFactory tdf; - td = tdf.createThisDescriptor(observer, thisDescriptorString); + } + else + { + ThisDescriptorFactory tdf; + td = tdf.createThisDescriptor(observer, thisDescriptorString); - if (!td) - { - DebugTrace("MTGABILITY: Parsing Error:" << s); - return NULL; - } - } + if (!td) + { + DebugTrace("MTGABILITY: Parsing Error:" << s); + return NULL; + } + } MTGAbility * a = parseMagicLine(s1, id, spell, card, 0, activated); if (!a) @@ -1887,9 +1887,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG case 1: result = NEW AThisForEach(observer, id, card, _target, td, a); break; - case 2: - result = NEW AThis(observer, id, card, _target, NULL, a, thisDescriptorString); - break; + case 2: + result = NEW AThis(observer, id, card, _target, NULL, a, thisDescriptorString); + break; default: result = NULL; } @@ -2251,15 +2251,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } - //grant ability until source is untapped or leaves battlefield - found = s.find("grant "); - if (found != string::npos) - { - MTGAbility * toGrant = parseMagicLine(storedAbilityString, id, spell, card); - MTGAbility * a = NEW AGrantWrapper(observer, id, card, target,toGrant); - a->oneShot = 1; - return a; - } + //grant ability until source is untapped or leaves battlefield + found = s.find("grant "); + if (found != string::npos) + { + MTGAbility * toGrant = parseMagicLine(storedAbilityString, id, spell, card); + MTGAbility * a = NEW AGrantWrapper(observer, id, card, target,toGrant); + a->oneShot = 1; + return a; + } //momentary blink found = s.find("(blink)"); @@ -2382,21 +2382,21 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG tok->oneShot = 1; return tok; } - + string tokenDesc = splitToken[1]; vector tokenParameters = split(tokenDesc, ','); - //lets try finding a token by card name. - if (splitToken[1].size() && tokenParameters.size() ==1) - { - string cardName = splitToken[1]; - MTGCard * safetycard = MTGCollection()->getCardByName(cardName); - if (safetycard) //lets try constructing it then,we didnt find it by name - { - ATokenCreator * tok = NEW ATokenCreator(observer, id, card, target, NULL, cardName, starfound, multiplier, who); - tok->oneShot = 1; - return tok; - } - } + //lets try finding a token by card name. + if (splitToken[1].size() && tokenParameters.size() ==1) + { + string cardName = splitToken[1]; + MTGCard * safetycard = MTGCollection()->getCardByName(cardName); + if (safetycard) //lets try constructing it then,we didnt find it by name + { + ATokenCreator * tok = NEW ATokenCreator(observer, id, card, target, NULL, cardName, starfound, multiplier, who); + tok->oneShot = 1; + return tok; + } + } if (tokenParameters.size() < 3) { DebugTrace("incorrect Parameters for Token" << tokenDesc); @@ -2599,7 +2599,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG bool withRestrictions = splitCastCard[1].find("restricted") != string::npos; bool asCopy = splitCastCard[1].find("copied") != string::npos; bool asNormal = splitCastCard[1].find("normal") != string::npos; - bool asNormalMadness = splitCastCard[1].find("madness") != string::npos; + bool asNormalMadness = splitCastCard[1].find("madness") != string::npos; bool sendNoEvent = splitCastCard[1].find("noevent") != string::npos; bool putinplay = splitCastCard[1].find("putinplay") != string::npos; string nameCard = ""; @@ -3058,15 +3058,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } - //bestow - found = s.find("bstw"); - if (found != string::npos) - { - MTGAbility * a = NEW ABestow(observer, id, card, target); - a->oneShot = 1; - return a; + //bestow + found = s.find("bstw"); + if (found != string::npos) + { + MTGAbility * a = NEW ABestow(observer, id, card, target); + a->oneShot = 1; + return a; - } + } //no counters on target of optional type vector splitCounterShroud = parseBetween(s, "countershroud(", ")"); @@ -3257,29 +3257,29 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } - //Reveal:x (activate aility) - vector splitReveal = parseBetween(s, "reveal:", "revealend", false); - if (splitReveal.size()) - { - string backup = storedAbilityString; - storedAbilityString = "";//we clear the string here for cards that contain more than 1 reveal. - GenericRevealAbility * a = NEW GenericRevealAbility(observer, id, card, target, backup); - a->oneShot = 1; - a->canBeInterrupted = false; - return a; - } + //Reveal:x (activate aility) + vector splitReveal = parseBetween(s, "reveal:", "revealend", false); + if (splitReveal.size()) + { + string backup = storedAbilityString; + storedAbilityString = "";//we clear the string here for cards that contain more than 1 reveal. + GenericRevealAbility * a = NEW GenericRevealAbility(observer, id, card, target, backup); + a->oneShot = 1; + a->canBeInterrupted = false; + return a; + } - //scry:x (activate aility) - vector splitScry = parseBetween(s, "scry:", "scryend", false); - if (splitScry.size()) - { - string backup = storedAbilityString; - storedAbilityString = "";//we clear the string here for cards that contain more than 1 reveal. - GenericScryAbility * a = NEW GenericScryAbility(observer, id, card, target, backup); - a->oneShot = 1; - a->canBeInterrupted = false; - return a; - } + //scry:x (activate aility) + vector splitScry = parseBetween(s, "scry:", "scryend", false); + if (splitScry.size()) + { + string backup = storedAbilityString; + storedAbilityString = "";//we clear the string here for cards that contain more than 1 reveal. + GenericScryAbility * a = NEW GenericScryAbility(observer, id, card, target, backup); + a->oneShot = 1; + a->canBeInterrupted = false; + return a; + } //flip vector splitFlipStat = parseBetween(s, "flip(", ")", true); @@ -3455,14 +3455,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } - //frozen, next untap this does not untap. - found = s.find("freeze"); - if (found != string::npos) - { - MTGAbility * a = NEW AAFrozen(observer, id, card, target,true); - a->oneShot = 1; - return a; - } + //frozen, next untap this does not untap. + found = s.find("freeze"); + if (found != string::npos) + { + MTGAbility * a = NEW AAFrozen(observer, id, card, target,true); + a->oneShot = 1; + return a; + } //get a new target - retarget and newtarget makes the card refreshed - from exile to play... if ((s.find("retarget") != string::npos) || s.find("newtarget") != string::npos) @@ -3498,13 +3498,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } - vector splitCountObject = parseBetween(s, "count(", ")", false); - if (splitCountObject.size()) - { - MTGAbility * a = NEW AACountObject(observer, id, card, card, NULL, splitCountObject[1]); - a->oneShot = 1; - return a; - } + vector splitCountObject = parseBetween(s, "count(", ")", false); + if (splitCountObject.size()) + { + MTGAbility * a = NEW AACountObject(observer, id, card, card, NULL, splitCountObject[1]); + a->oneShot = 1; + return a; + } //switch targest power with toughness found = s.find("swap"); @@ -4801,7 +4801,7 @@ MTGAbility::MTGAbility(const MTGAbility& a): ActionElement(a) BuyBack = a.BuyBack; //? NEW ManaCost(a.BuyBack) : NULL; FlashBack = a.FlashBack; // ? NEW ManaCost(a.FlashBack) : NULL; Retrace = a.Retrace;// ? NEW ManaCost(a.Retrace) : NULL; - Bestow = a.Bestow; + Bestow = a.Bestow; morph = a.morph; //? NEW ManaCost(a.morph) : NULL; suspend = a.suspend;// ? NEW ManaCost(a.suspend) : NULL; @@ -5949,7 +5949,7 @@ int AManaProducer::resolve() Player * player = getPlayerFromTarget(_target); if (!player) return 0; - + player->getManaPool()->add(output, source); if(DoesntEmpty) player->doesntEmpty->add(output); diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index f137c18a8..0e6bb1ea0 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -69,8 +69,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to cardistargetted = 0; cardistargetter = 0; myconvertedcost = getManaCost()->getConvertedCost(); - revealedLast = NULL; - MadnessPlay = false; + revealedLast = NULL; + MadnessPlay = false; } MTGCardInstance * MTGCardInstance::createSnapShot() @@ -153,14 +153,14 @@ int MTGCardInstance::init() data = this; X = 0; castX = 0; - setX = -1; + setX = -1; return 1; } void MTGCardInstance::initMTGCI() { X = 0; - setX = -1; + setX = -1; sample = ""; model = NULL; isToken = false; @@ -198,7 +198,7 @@ void MTGCardInstance::initMTGCI() wasDealtDamage = false; isDualWielding = false; suspended = false; - isBestowed = false; + isBestowed = false; castMethod = Constants::NOT_CAST; mPropertiesChangedSinceLastUpdate = false; stillNeeded = true; @@ -228,7 +228,7 @@ void MTGCardInstance::initMTGCI() imprintW = 0; currentimprintName = ""; imprintedNames.clear(); - CountedObjects = 0; + CountedObjects = 0; for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++) alternateCostPaid[i] = 0; @@ -782,8 +782,8 @@ int MTGCardInstance::getCurrentToughness() //check stack bool MTGCardInstance::StackIsEmptyandSorcerySpeed() { - Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. - Player * whoCurrent = getObserver()->currentPlayer; + Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. + Player * whoCurrent = getObserver()->currentPlayer; if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) && (getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) && diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 6c2ab7622..86fb175a2 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -107,17 +107,17 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi case 'b': //buyback/Bestow if (!primitive) primitive = NEW CardPrimitive(); - if (key[1] == 'e' && key[2] == 's') - { //bestow - if (!primitive) primitive = NEW CardPrimitive(); - if (ManaCost * cost = primitive->getManaCost()) - { - string value = val; - std::transform(value.begin(), value.end(), value.begin(), ::tolower); - cost->setBestow(ManaCost::parseManaCost(value)); - } - } - else//buyback + if (key[1] == 'e' && key[2] == 's') + { //bestow + if (!primitive) primitive = NEW CardPrimitive(); + if (ManaCost * cost = primitive->getManaCost()) + { + string value = val; + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + cost->setBestow(ManaCost::parseManaCost(value)); + } + } + else//buyback if (ManaCost * cost = primitive->getManaCost()) { string value = val; diff --git a/projects/mtg/src/MTGGamePhase.cpp b/projects/mtg/src/MTGGamePhase.cpp index 7bc8c5c51..0457c0afb 100644 --- a/projects/mtg/src/MTGGamePhase.cpp +++ b/projects/mtg/src/MTGGamePhase.cpp @@ -9,7 +9,7 @@ MTGGamePhase::MTGGamePhase(GameObserver* g, int id) : animation = 0; currentState = -1; mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); - if(mFont) + if(mFont) mFont->SetBase(0); // using 2nd font } diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 9f4e6e572..c04e5d1f0 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -74,7 +74,7 @@ MTGPlayerCards::~MTGPlayerCards() SAFE_DELETE(stack); SAFE_DELETE(removedFromGame); SAFE_DELETE(garbage); - SAFE_DELETE(reveal); + SAFE_DELETE(reveal); SAFE_DELETE(temp); SAFE_DELETE(playRestrictions); } @@ -92,7 +92,7 @@ void MTGPlayerCards::beforeBeginPhase() stack->beforeBeginPhase(); removedFromGame->beforeBeginPhase(); garbage->beforeBeginPhase(); - reveal->beforeBeginPhase(); + reveal->beforeBeginPhase(); temp->beforeBeginPhase(); } @@ -107,7 +107,7 @@ void MTGPlayerCards::setOwner(Player * player) stack->setOwner(player); garbage->setOwner(player); garbageLastTurn->setOwner(player); - reveal->setOwner(player); + reveal->setOwner(player); temp->setOwner(player); } @@ -275,7 +275,7 @@ void MTGPlayerCards::init() exile = removedFromGame; garbage = NEW MTGGameZone(); garbageLastTurn = garbage; - reveal = NEW MTGGameZone(); + reveal = NEW MTGGameZone(); temp = NEW MTGGameZone(); playRestrictions = NEW PlayRestrictions(); @@ -374,12 +374,12 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone } } - //all cards that go from the hand to the graveyard is ALWAYS a discard. - if ((to == g->players[0]->game->graveyard || to == g->players[1]->game->graveyard) && (from == g->players[0]->game->hand || from - == g->players[1]->game->hand)) - { - card->discarded = true; - } + //all cards that go from the hand to the graveyard is ALWAYS a discard. + if ((to == g->players[0]->game->graveyard || to == g->players[1]->game->graveyard) && (from == g->players[0]->game->hand || from + == g->players[1]->game->hand)) + { + card->discarded = true; + } //When a card is moved from inPlay to inPlay (controller change, for example), it is still the same object if ((to == g->players[0]->game->inPlay || to == g->players[1]->game->inPlay) && (from == g->players[0]->game->inPlay || from @@ -1019,12 +1019,12 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) case STACK: return p->game->stack; - case MY_REVEAL: - return p->game->reveal; - case OPPONENT_REVEAL: - return p->opponent()->game->reveal; - case REVEAL: - return p->game->reveal; + case MY_REVEAL: + return p->game->reveal; + case OPPONENT_REVEAL: + return p->opponent()->game->reveal; + case REVEAL: + return p->game->reveal; } if (!p2) return NULL; @@ -1048,8 +1048,8 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2) case TARGET_CONTROLLER_STACK: return p2->game->stack; - case TARGET_CONTROLLER_REVEAL: - return p2->game->reveal; + case TARGET_CONTROLLER_REVEAL: + return p2->game->reveal; default: return NULL; @@ -1149,16 +1149,16 @@ MTGGameZone * MTGGameZone::intToZone(GameObserver *g, int zoneId, MTGCardInstanc return source->playerTarget->game->stack; else return source->controller()->game->stack; - case TARGET_OWNER_REVEAL: - return target->owner->game->reveal; - case REVEAL: - return target->owner->game->reveal; - case OWNER_REVEAL: - return target->owner->game->reveal; - case TARGETED_PLAYER_REVEAL: - if (source->playerTarget) - return source->playerTarget->game->reveal; - else return source->controller()->game->reveal; + case TARGET_OWNER_REVEAL: + return target->owner->game->reveal; + case REVEAL: + return target->owner->game->reveal; + case OWNER_REVEAL: + return target->owner->game->reveal; + case TARGETED_PLAYER_REVEAL: + if (source->playerTarget) + return source->playerTarget->game->reveal; + else return source->controller()->game->reveal; default: return NULL; @@ -1187,7 +1187,7 @@ int MTGGameZone::zoneStringToId(string zoneName) "mystack", "opponentstack", "targetownerstack", "targetcontrollerstack", "ownerstack", "stack","targetedpersonsstack", - "myreveal", "opponentreveal", "targetownerreveal", "targetcontrollerreveal", "ownerreveal", "reveal","targetedpersonsreveal", + "myreveal", "opponentreveal", "targetownerreveal", "targetcontrollerreveal", "ownerreveal", "reveal","targetedpersonsreveal", }; @@ -1210,7 +1210,7 @@ int MTGGameZone::zoneStringToId(string zoneName) MY_STACK, OPPONENT_STACK, TARGET_OWNER_STACK, TARGET_CONTROLLER_STACK, OWNER_STACK, STACK,TARGETED_PLAYER_STACK, - MY_REVEAL, OPPONENT_REVEAL, TARGET_OWNER_REVEAL, TARGET_CONTROLLER_REVEAL, OWNER_REVEAL, REVEAL,TARGETED_PLAYER_REVEAL }; + MY_REVEAL, OPPONENT_REVEAL, TARGET_OWNER_REVEAL, TARGET_CONTROLLER_REVEAL, OWNER_REVEAL, REVEAL,TARGETED_PLAYER_REVEAL }; int max = sizeof(values) / sizeof *(values); diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index d2e72a9bf..1af7ac8bc 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -49,10 +49,10 @@ PermanentAbility(observer, _id) Angel[i] = 0; dragonbonusgranted[i] = false; dragon[i] = 0; - eldrazibonusgranted[i] = false; - eldrazi[i] = 0; - werewolfbonusgranted[i] = false; - werewolf[i] = 0; + eldrazibonusgranted[i] = false; + eldrazi[i] = 0; + werewolfbonusgranted[i] = false; + werewolf[i] = 0; } } @@ -175,10 +175,10 @@ int MTGEventBonus::receiveEvent(WEvent * event) Angel[currentPlayer->getId()]++; if(e->card->hasType("dragon")||e->card->hasType("wurm")||e->card->hasType("drake")||e->card->hasType("snake")||e->card->hasType("hydra")) dragon[currentPlayer->getId()]++; - if (e->card->hasType("eldrazi")) - eldrazi[currentPlayer->getId()]++; - if (e->card->hasType("werewolf") || e->card->hasType("wolf")) - werewolf[currentPlayer->getId()]++; + if (e->card->hasType("eldrazi")) + eldrazi[currentPlayer->getId()]++; + if (e->card->hasType("werewolf") || e->card->hasType("wolf")) + werewolf[currentPlayer->getId()]++; } if(toys[currentPlayer->getId()] > 30 && !toybonusgranted[currentPlayer->getId()]) { @@ -236,16 +236,16 @@ int MTGEventBonus::receiveEvent(WEvent * event) grantAward("Teeth And Scales!",300); dragonbonusgranted[currentPlayer->getId()] = true; } - if (eldrazi[currentPlayer->getId()] > 30 && !eldrazibonusgranted[currentPlayer->getId()]) - { - grantAward("Colorblind!", 300); - eldrazibonusgranted[currentPlayer->getId()] = true; - } - if (werewolf[currentPlayer->getId()] > 30 && !werewolfbonusgranted[currentPlayer->getId()]) - { - grantAward("Full Moon!", 300); - werewolfbonusgranted[currentPlayer->getId()] = true; - } + if (eldrazi[currentPlayer->getId()] > 30 && !eldrazibonusgranted[currentPlayer->getId()]) + { + grantAward("Colorblind!", 300); + eldrazibonusgranted[currentPlayer->getId()] = true; + } + if (werewolf[currentPlayer->getId()] > 30 && !werewolfbonusgranted[currentPlayer->getId()]) + { + grantAward("Full Moon!", 300); + werewolfbonusgranted[currentPlayer->getId()] = true; + } } } //bonus for dealing 100+ damage from a single source @@ -383,65 +383,65 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) return 0; Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); - ManaCost * playerMana = player->getManaPool(); - ///////announce X cost/////// - if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) - { - vectorselection; - int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; - //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would - //give me the correct amount sorry. - for (int i = 0; i < options; ++i) - { + ManaCost * playerMana = player->getManaPool(); + ///////announce X cost/////// + if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { - MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); - MTGAbility * setCardX = setX->clone(); - setCardX->oneShot = true; - selection.push_back(setCardX); - SAFE_DELETE(setX); - } - if (selection.size()) - { - MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); - game->mLayers->actionLayer()->currentActionCard = card; - a1->resolve(); - } - return 0; - } - /////////////////////////////////////////////////////////////////////////////////////// - //////X is set, below we set sunburst for X if needed and cast or reset the card.////// - //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// - //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// - //////and the value of X isn’t defined by the text of that spell or ability, the ////// - //////controller of that spell or ability chooses and announces the value of X as////// - //////part of casting the spell or activating the ability. ////// - //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// - //////its mana cost or in any alternative cost or additional cost it has equals ////// - //////the announced value.While an activated ability is on the stack, any X in ////// - //////its activation cost equals the announced value. ////// - /////////////////////////////////////////////////////////////////////////////////////// - if (card->setX > -1) - { - ManaCost * Xcost = NEW ManaCost(); - Xcost->copy(cost); - Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); - Xcost->remove(7, 1); - if (playerMana->canAfford(Xcost)) - { - cost->copy(Xcost); - SAFE_DELETE(Xcost); - } - else - { - if (card->setX > -1) - card->setX = -1; - SAFE_DELETE(Xcost); - return 0; - } - } - ////////////////////////////////////////// - ////cards without X contenue from here//// - ////////////////////////////////////////// + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(cost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1); + if (playerMana->canAfford(Xcost)) + { + cost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } + ////////////////////////////////////////// + ////cards without X contenue from here//// + ////////////////////////////////////////// //this handles extra cost payments at the moment a card is played. if (cost->isExtraPaymentSet()) { @@ -456,7 +456,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) game->mExtraPayment = cost->extraCosts; return 0; } - + ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); int payResult = player->getManaPool()->pay(card->getManaCost()); if (card->getManaCost()->getKicker() && (OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number || card->controller()->isAI())) @@ -570,9 +570,9 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *) ManaCost * withKickerCost= NEW ManaCost(card->getManaCost()); withKickerCost->add(card->getManaCost()->getKicker()); //cost reduction/recalculation must be here or outside somehow... - //no recalculations beyound this point, reactToClick is the function that - //happens only with the assumption that you could actually pay for it, any calculations after will - //have negitive effects. this function is basically "can i play this card?" + //no recalculations beyound this point, reactToClick is the function that + //happens only with the assumption that you could actually pay for it, any calculations after will + //have negitive effects. this function is basically "can i play this card?" #ifdef WIN32 withKickerCost->Dump(); #endif @@ -787,61 +787,61 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter Player * player = game->currentlyActing(); ManaPool * playerMana = player->getManaPool(); - ///////announce X cost/////// - if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) - { - vectorselection; - int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; - //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would - //give me the correct amount sorry. - for (int i = 0; i < options; ++i) - { + ///////announce X cost/////// + if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { - MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); - MTGAbility * setCardX = setX->clone(); - setCardX->oneShot = true; - selection.push_back(setCardX); - SAFE_DELETE(setX); - } - if (selection.size()) - { - MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); - game->mLayers->actionLayer()->currentActionCard = card; - a1->resolve(); - } - return 0; - } - /////////////////////////////////////////////////////////////////////////////////////// - //////X is set, below we set sunburst for X if needed and cast or reset the card.////// - //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// - //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// - //////and the value of X isn’t defined by the text of that spell or ability, the ////// - //////controller of that spell or ability chooses and announces the value of X as////// - //////part of casting the spell or activating the ability. ////// - //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// - //////its mana cost or in any alternative cost or additional cost it has equals ////// - //////the announced value.While an activated ability is on the stack, any X in ////// - //////its activation cost equals the announced value. ////// - /////////////////////////////////////////////////////////////////////////////////////// - if (card->setX > -1) - { - ManaCost * Xcost = NEW ManaCost(); - Xcost->copy(alternateCost); - Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); - Xcost->remove(7, 1);//remove the X - if (playerMana->canAfford(Xcost)) - { - alternateCost->copy(Xcost); - SAFE_DELETE(Xcost); - } - else - { - if (card->setX > -1) - card->setX = -1; - SAFE_DELETE(Xcost); - return 0; - } - } + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(alternateCost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1);//remove the X + if (playerMana->canAfford(Xcost)) + { + alternateCost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } //this handles extra cost payments at the moment a card is played. @@ -898,7 +898,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter { ManaCost * c = spellCost->Diff(alternateCost); - copy->X = card->setX; + copy->X = card->setX; copy->castX = copy->X; delete c; } @@ -1049,11 +1049,11 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) Player * player = game->currentlyActing(); if(!card->getManaCost()->getRetrace()) return 0; - if (!player->game->graveyard->hasCard(card)) - { - return 0; - } - ManaCost * retraceCost = card->getManaCost()->getRetrace(); + if (!player->game->graveyard->hasCard(card)) + { + return 0; + } + ManaCost * retraceCost = card->getManaCost()->getRetrace(); if(retraceCost->extraCosts) for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++) { @@ -1364,25 +1364,25 @@ MTGAlternativeCostRule(observer, _id) int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if (!card->has(Constants::PAYZERO)) - return 0; - Player * player = game->currentlyActing(); - if (card->isLand() || (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))) - { - //only allowed to pay zero for cards in library??? above is "if you dont have it in hand, grave, or exile" - return 0; - } - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - { - return 0; - } - ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); - ManaCost * newCost = card->computeNewCost(card, cost, cost); - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } + if (!card->has(Constants::PAYZERO)) + return 0; + Player * player = game->currentlyActing(); + if (card->isLand() || (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))) + { + //only allowed to pay zero for cards in library??? above is "if you dont have it in hand, grave, or exile" + return 0; + } + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + { + return 0; + } + ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL)); + ManaCost * newCost = card->computeNewCost(card, cost, cost); + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } if(card->has(Constants::CANPLAYFROMGRAVEYARD)) CustomName = "Zero Cast From Graveyard"; else if(card->has(Constants::CANPLAYFROMEXILE)) @@ -1432,19 +1432,19 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { if (!card->has(Constants::OVERLOAD)) return 0; - if (card->isLand()) - { - return 0; - } - Player * player = card->controller(); - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) - { - return 0; - } - if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) - { - return 0; - } + if (card->isLand()) + { + return 0; + } + Player * player = card->controller(); + if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) + { + return 0; + } + if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) + { + return 0; + } ManaCost * newCost = card->getManaCost()->getAlternative(); if(newCost->extraCosts) for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++) @@ -1484,64 +1484,64 @@ MTGOverloadRule * MTGOverloadRule::clone() const /////////////////////////////////////////////////////////////////////////////////////////////////// //bestow MTGBestowRule::MTGBestowRule(GameObserver* observer, int _id) : - MTGAlternativeCostRule(observer, _id) + MTGAlternativeCostRule(observer, _id) { - aType = MTGAbility::BESTOW_COST; + aType = MTGAbility::BESTOW_COST; } int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { - if (!card->model) - return 0; - if (!card->model->data->getManaCost()->getBestow()) - return 0; - if (card->isInPlay(game)) - return 0; - if (card->isLand()) - { - return 0; - } - if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) - { - return 0; - } - ManaCost * newCost = card->getManaCost()->getBestow(); - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } - return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); + if (!card->model) + return 0; + if (!card->model->data->getManaCost()->getBestow()) + return 0; + if (card->isInPlay(game)) + return 0; + if (card->isLand()) + { + return 0; + } + if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature")) + { + return 0; + } + ManaCost * newCost = card->getManaCost()->getBestow(); + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } + return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost); } int MTGBestowRule::reactToClick(MTGCardInstance * card) { - if (!isReactingToClick(card)) - return 0; - //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash - //TODO::::we need to get to the source of this leak and fix it. - ManaCost * newCost = card->getManaCost()->getBestow(); - - if (newCost->extraCosts) - for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) - { - newCost->extraCosts->costs[i]->setSource(card); - } + if (!isReactingToClick(card)) + return 0; + //this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash + //TODO::::we need to get to the source of this leak and fix it. + ManaCost * newCost = card->getManaCost()->getBestow(); + + if (newCost->extraCosts) + for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++) + { + newCost->extraCosts->costs[i]->setSource(card); + } - card->paymenttype = MTGAbility::BESTOW_COST; - card->spellTargetType = "creature|battlefield"; - return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false); + card->paymenttype = MTGAbility::BESTOW_COST; + card->spellTargetType = "creature|battlefield"; + return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false); } ostream& MTGBestowRule::toString(ostream& out) const { - out << "MTGBestowRule ::: ("; - return MTGAbility::toString(out) << ")"; + out << "MTGBestowRule ::: ("; + return MTGAbility::toString(out) << ")"; } MTGBestowRule * MTGBestowRule::clone() const { - return NEW MTGBestowRule(*this); + return NEW MTGBestowRule(*this); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1732,19 +1732,19 @@ int MTGAttackRule::receiveEvent(WEvent *e) for (int i = 0; i < z->nb_cards; i++) { MTGCardInstance * card = z->cards[i]; - if (card->isAttacker() && card->has(Constants::NOSOLO)) - { - TargetChooserFactory tf(game); - TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL); - int Check = card->controller()->game->battlefield->countByCanTarget(tc); - if (Check <2) - card->initAttackersDefensers(); - } - if (card->isAttacker() && card->has(Constants::DETHRONE)) - { - if (p->opponent()->life >= p->life) - card->counters->addCounter(1, 1); - } + if (card->isAttacker() && card->has(Constants::NOSOLO)) + { + TargetChooserFactory tf(game); + TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL); + int Check = card->controller()->game->battlefield->countByCanTarget(tc); + if (Check <2) + card->initAttackersDefensers(); + } + if (card->isAttacker() && card->has(Constants::DETHRONE)) + { + if (p->opponent()->life >= p->life) + card->counters->addCounter(1, 1); + } if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn. reactToClick(card); if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI()) @@ -2058,49 +2058,49 @@ PermanentAbility(observer, _id) int MTGBlockRule::receiveEvent(WEvent *e) { - if (dynamic_cast(e)) - {//do not refactor, these are keep seperate for readability. - Player * p = game->currentPlayer; + if (dynamic_cast(e)) + {//do not refactor, these are keep seperate for readability. + Player * p = game->currentPlayer; - vector Attacker; - MTGGameZone * k = p->game->inPlay; - for (int i = 0; i < k->nb_cards; i++) - { - MTGCardInstance * card = k->cards[i]; - if (card->isAttacker()) - { - Attacker.push_back(card); - } - } - //force cards that must block, to block whatever is first found. players have a chance to set thier own - //but if ignored we do it for them. - if (Attacker.size()) - { - MTGGameZone * tf = p->opponent()->game->inPlay; - for (size_t i = 0; i < tf->cards.size(); i++) - { - MTGCardInstance * card = tf->cards[i]; - if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock()) - {//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them - //unassigned as a block. - for (size_t i = 0; i < Attacker.size(); i++) - { - if (card->canBlock(Attacker[i]) && !card->defenser) - { - blocker = NEW AABlock(card->getObserver(), -1, card, NULL); - blocker->oneShot = true; - blocker->forceDestroy = 1; - blocker->canBeInterrupted = false; - blocker->target = Attacker[i]; - blocker->resolve(); - SAFE_DELETE(blocker); - } - } + vector Attacker; + MTGGameZone * k = p->game->inPlay; + for (int i = 0; i < k->nb_cards; i++) + { + MTGCardInstance * card = k->cards[i]; + if (card->isAttacker()) + { + Attacker.push_back(card); + } + } + //force cards that must block, to block whatever is first found. players have a chance to set thier own + //but if ignored we do it for them. + if (Attacker.size()) + { + MTGGameZone * tf = p->opponent()->game->inPlay; + for (size_t i = 0; i < tf->cards.size(); i++) + { + MTGCardInstance * card = tf->cards[i]; + if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock()) + {//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them + //unassigned as a block. + for (size_t i = 0; i < Attacker.size(); i++) + { + if (card->canBlock(Attacker[i]) && !card->defenser) + { + blocker = NEW AABlock(card->getObserver(), -1, card, NULL); + blocker->oneShot = true; + blocker->forceDestroy = 1; + blocker->canBeInterrupted = false; + blocker->target = Attacker[i]; + blocker->resolve(); + SAFE_DELETE(blocker); + } + } - } - } + } + } - } + } if (dynamic_cast(e)) { @@ -2120,23 +2120,23 @@ int MTGBlockRule::receiveEvent(WEvent *e) } } - //if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal. - MTGGameZone * z = p->game->inPlay; - for (int i = 0; i < z->nb_cards; i++) - { - MTGCardInstance * card = z->cards[i]; - if (card->has(Constants::MENACE) && card->blockers.size() < 2) - { - while (card->blockers.size()) - { - MTGCardInstance * blockingCard = card->blockers.front(); - blockingCard->toggleDefenser(NULL); - - } - } - } + //if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal. + MTGGameZone * z = p->game->inPlay; + for (int i = 0; i < z->nb_cards; i++) + { + MTGCardInstance * card = z->cards[i]; + if (card->has(Constants::MENACE) && card->blockers.size() < 2) + { + while (card->blockers.size()) + { + MTGCardInstance * blockingCard = card->blockers.front(); + blockingCard->toggleDefenser(NULL); + + } + } + } - } + } return 1; @@ -2906,7 +2906,7 @@ int MTGPersistRule::receiveEvent(WEvent * event) } AAMover *putinplay = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), copy, copy,"ownerbattlefield",code,NULL,undying,persist); putinplay->oneShot = true; - game->mLayers->actionLayer()->garbage.push_back(putinplay); + game->mLayers->actionLayer()->garbage.push_back(putinplay); putinplay->fireAbility(); return 1; } diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index f1d5d208c..cfb5a4caf 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -153,7 +153,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'e': - //Exile + //Exile manaCost->addExtraCost(NEW ExileTargetCost(tc)); break; case 'h': //bounce (move to Hand) @@ -179,12 +179,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'd': //DiscardRandom cost - if (value.find("delve") != string::npos) - { - if(!tc) - tc = tcf.createTargetChooser("*|mygraveyard", c); - manaCost->addExtraCost(NEW Delve(tc)); - } + if (value.find("delve") != string::npos) + { + if(!tc) + tc = tcf.createTargetChooser("*|mygraveyard", c); + manaCost->addExtraCost(NEW Delve(tc)); + } else if (value == "d") { manaCost->addExtraCost(NEW DiscardRandomCost(tc)); @@ -259,12 +259,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan break; case 'c': //Counters or cycle { - if (value.find("convoke") != string::npos) - { - if (!tc) - tc = tcf.createTargetChooser("creature|mybattlefield", c); - manaCost->addExtraCost(NEW Convoke(tc)); - } + if (value.find("convoke") != string::npos) + { + if (!tc) + tc = tcf.createTargetChooser("creature|mybattlefield", c); + manaCost->addExtraCost(NEW Convoke(tc)); + } else if(value == "chosencolor") { if(c) @@ -389,22 +389,22 @@ ManaCost::ManaCost(ManaCost * manaCost) { cost[i] = manaCost->getCost(i); } - hybrids = manaCost->hybrids; - kicker = NEW ManaCost(manaCost->kicker); - if (kicker) - kicker->isMulti = manaCost->isMulti; + hybrids = manaCost->hybrids; + kicker = NEW ManaCost(manaCost->kicker); + if (kicker) + kicker->isMulti = manaCost->isMulti; Retrace = NEW ManaCost( manaCost->Retrace ); BuyBack = NEW ManaCost( manaCost->BuyBack ); alternative = NEW ManaCost( manaCost->alternative ); FlashBack = NEW ManaCost( manaCost->FlashBack ); morph = NEW ManaCost( manaCost->morph ); suspend = NEW ManaCost( manaCost->suspend ); - Bestow = NEW ManaCost(manaCost->Bestow); - extraCosts = NULL; - if (manaCost->extraCosts) - { - extraCosts = manaCost->extraCosts->clone(); - } + Bestow = NEW ManaCost(manaCost->Bestow); + extraCosts = NULL; + if (manaCost->extraCosts) + { + extraCosts = manaCost->extraCosts->clone(); + } manaUsedToCast = NULL; xColor = manaCost->xColor; } @@ -431,12 +431,12 @@ ManaCost::ManaCost(const ManaCost& manaCost) FlashBack = NEW ManaCost( manaCost.FlashBack ); morph = NEW ManaCost( manaCost.morph ); suspend = NEW ManaCost( manaCost.suspend ); - Bestow = NEW ManaCost(manaCost.Bestow); - extraCosts = NULL; - if (manaCost.extraCosts) - { - extraCosts = manaCost.extraCosts->clone(); - } + Bestow = NEW ManaCost(manaCost.Bestow); + extraCosts = NULL; + if (manaCost.extraCosts) + { + extraCosts = manaCost.extraCosts->clone(); + } manaUsedToCast = NULL; xColor = manaCost.xColor; @@ -459,7 +459,7 @@ ManaCost & ManaCost::operator= (const ManaCost & manaCost) FlashBack = manaCost.FlashBack; morph = manaCost.morph; suspend = manaCost.suspend; - Bestow = manaCost.Bestow; + Bestow = manaCost.Bestow; manaUsedToCast = manaCost.manaUsedToCast; xColor = manaCost.xColor; } @@ -476,7 +476,7 @@ ManaCost::~ManaCost() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); SAFE_DELETE(manaUsedToCast); cost.erase(cost.begin() ,cost.end()); @@ -558,7 +558,7 @@ void ManaCost::init() Retrace = NULL; morph = NULL; suspend = NULL; - Bestow = NULL; + Bestow = NULL; manaUsedToCast = NULL; isMulti = false; xColor = -1; @@ -583,7 +583,7 @@ void ManaCost::resetCosts() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); } void ManaCost::copy(ManaCost * _manaCost) @@ -650,12 +650,12 @@ void ManaCost::copy(ManaCost * _manaCost) suspend = NEW ManaCost(); suspend->copy(_manaCost->suspend); } - SAFE_DELETE(Bestow); - if (_manaCost->Bestow) - { - Bestow = NEW ManaCost(); - Bestow->copy(_manaCost->Bestow); - } + SAFE_DELETE(Bestow); + if (_manaCost->Bestow) + { + Bestow = NEW ManaCost(); + Bestow->copy(_manaCost->Bestow); + } xColor = _manaCost->xColor; } @@ -1120,7 +1120,7 @@ void ManaPool::Empty() SAFE_DELETE(Retrace); SAFE_DELETE(morph); SAFE_DELETE(suspend); - SAFE_DELETE(Bestow); + SAFE_DELETE(Bestow); SAFE_DELETE(manaUsedToCast); init(); WEvent * e = NEW WEventEmptyManaPool(this); @@ -1150,8 +1150,8 @@ int ManaPool::remove(int color, int value) int ManaPool::add(int color, int value, MTGCardInstance * source, bool extra) { - if (color == Constants::MTG_COLOR_ARTIFACT) - color = Constants::MTG_COLOR_WASTE; + if (color == Constants::MTG_COLOR_ARTIFACT) + color = Constants::MTG_COLOR_WASTE; int result = ManaCost::add(color, value); for (int i = 0; i < value; ++i) { @@ -1171,15 +1171,15 @@ int ManaPool::add(ManaCost * _cost, MTGCardInstance * source) { if (!_cost) return 0; - //while colorless is still exactly the same, there are now cards that require - //true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the - //new type. keeping the old type intact for payment methods {1}{c} .... - int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT); - if (replaceArtifact) - { - _cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact); - _cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact); - } + //while colorless is still exactly the same, there are now cards that require + //true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the + //new type. keeping the old type intact for payment methods {1}{c} .... + int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT); + if (replaceArtifact) + { + _cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact); + _cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact); + } int result = ManaCost::add(_cost); for (int i = 0; i < Constants::NB_Colors; i++) { diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 55cf0b6b6..5bf16d833 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -419,7 +419,7 @@ void Rules::initGame(GameObserver *g, bool currentPlayerSet) initState.playerData[i].player->game->hand, initState.playerData[i].player->game->inPlay, initState.playerData[i].player->game->exile, - initState.playerData[i].player->game->reveal }; + initState.playerData[i].player->game->reveal }; for (int j = 0; j < 5; j++) { MTGGameZone * zone = playerZones[j]; diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 59a464dbb..908a7145b 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -156,11 +156,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta { zones[nbzones++] = MTGGameZone::ALL_ZONES; } - else if (zoneName.compare("reveal") == 0) - { - zones[nbzones++] = MTGGameZone::MY_REVEAL; - zones[nbzones++] = MTGGameZone::OPPONENT_REVEAL; - } + else if (zoneName.compare("reveal") == 0) + { + zones[nbzones++] = MTGGameZone::MY_REVEAL; + zones[nbzones++] = MTGGameZone::OPPONENT_REVEAL; + } else if (zoneName.compare("graveyard") == 0) { zones[nbzones++] = MTGGameZone::MY_GRAVEYARD; @@ -642,15 +642,15 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta } } - if (attribute.find("colorless") != string::npos) - { - attributefound = 1; - for (int cid = 1; cid < Constants::NB_Colors; cid++) - { - cd->SetExclusionColor(cid); - } - cd->mode = CardDescriptor::CD_OR; - } + if (attribute.find("colorless") != string::npos) + { + attributefound = 1; + for (int cid = 1; cid < Constants::NB_Colors; cid++) + { + cd->SetExclusionColor(cid); + } + cd->mode = CardDescriptor::CD_OR; + } if (attribute.find("chosencolor") != string::npos) { @@ -822,7 +822,7 @@ TargetChooser::TargetChooser(GameObserver *observer, MTGCardInstance * card, int TargetsList(), observer(observer) { forceTargetListReady = 0; - forceTargetListReadyByPlayer = 0; + forceTargetListReadyByPlayer = 0; source = card; targetter = card; maxtargets = _maxtargets; @@ -905,10 +905,10 @@ int TargetChooser::ForceTargetListReady() int TargetChooser::targetsReadyCheck() { - if (targetMin == false && !targets.size() && forceTargetListReadyByPlayer) - { - return TARGET_OK_FULL;//we have no min amount for targets and 0 targets is a valid amount player called for a forced finish. - } + if (targetMin == false && !targets.size() && forceTargetListReadyByPlayer) + { + return TARGET_OK_FULL;//we have no min amount for targets and 0 targets is a valid amount player called for a forced finish. + } if (!targets.size()) { return TARGET_NOK; diff --git a/projects/mtg/src/TargetsList.cpp b/projects/mtg/src/TargetsList.cpp index 54d4bad57..220f78015 100644 --- a/projects/mtg/src/TargetsList.cpp +++ b/projects/mtg/src/TargetsList.cpp @@ -20,15 +20,15 @@ int TargetsList::addTarget(Targetable * target) { if (!alreadyHasTarget(target)) { - + TargetChooser * tc = target->getObserver()->getCurrentTargetChooser(); if(!tc || (tc && tc->maxtargets == 1)) { - if (dynamic_cast(this)->maxtargets > int(getNbTargets())) - { - targets.push_back(target); - return 1; - } + if (dynamic_cast(this)->maxtargets > int(getNbTargets())) + { + targets.push_back(target); + return 1; + } //because this was originally coded with targets as an array //we have to add this conditional to insure that cards with single target effects //and abilities that seek the nextcardtarget still work correctly. diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 1273e77f8..bcf4041ad 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -123,7 +123,7 @@ WEventTarget::WEventTarget(MTGCardInstance * card,MTGCardInstance * source) : WEventCardUpdate(card),card(card),source(source) { card->cardistargetted = 1; - if(source) + if(source) source->cardistargetter = 1; }