diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index fb3fe681a..b10654c57 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2144,6 +2144,7 @@ public: card->power = 1; card->setToughness(1); card->setSubtype("creature"); + card->summoningSickness = 0; return 1; } @@ -4411,30 +4412,36 @@ public: attackedThisTurn = 1; } - void Update(float dt) - { - if (newPhase != currentPhase) + void Update(float dt) { - Player * controller = source->controller(); - if (newPhase == Constants::MTG_PHASE_COMBATDAMAGE && game->currentPlayer == controller) + if (newPhase != currentPhase) { - if (source->isAttacker()) + Player * controller = source->controller(); + if(newPhase == Constants::MTG_PHASE_ENDOFTURN) { - attackedThisTurn = 1; + if(!attackedThisTurn && game->currentPlayer == source->controller() && !source->fresh) + game->mLayers->stackLayer()->addDamage(source, controller, 2); } - } - else if (newPhase == Constants::MTG_PHASE_UNTAP) - { - if (game->currentPlayer != controller && !attackedThisTurn) + else if (newPhase == Constants::MTG_PHASE_UNTAP) { - game->mLayers->stackLayer()->addDamage(source, controller, 2); - } - else if (game->currentPlayer == controller) - { - attackedThisTurn = 0; + + if (game->currentPlayer == controller) + { + attackedThisTurn = 0; + } } } } + + int receiveEvent(WEvent * event) + { + WEventCardAttacked * attacked = dynamic_cast (event); + if (attacked && !attacked->card->didblocked && attacked->card == source) + { + attackedThisTurn = 1; + return 1; + } + return 0; } AErgRaiders * clone() const diff --git a/projects/mtg/include/ExtraCost.h b/projects/mtg/include/ExtraCost.h index f2d03f3d5..bb915138b 100644 --- a/projects/mtg/include/ExtraCost.h +++ b/projects/mtg/include/ExtraCost.h @@ -110,7 +110,24 @@ public: MillExileCost(TargetChooser *_tc = NULL); virtual int doPay(); }; - +//tap cost +class TapCost: public ExtraCost{ +public: + TapCost(); + virtual int isPaymentSet(); + virtual int canPay(); + virtual int doPay(); + virtual TapCost * clone() const; +}; +//untap cost +class UnTapCost: public ExtraCost{ +public: + UnTapCost(); + virtual int isPaymentSet(); + virtual int canPay(); + virtual int doPay(); + virtual UnTapCost * clone() const; +}; //tap other cost class TapTargetCost: public ExtraCost{ public: diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index 0187c6489..140625832 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -312,6 +312,79 @@ int MillExileCost::doPay() return 0; } +//Tap cost +TapCost * TapCost::clone() const +{ + TapCost * ec = NEW TapCost(*this); + return ec; +} + +TapCost::TapCost() : + ExtraCost("Tap") +{ +} + +int TapCost::isPaymentSet() +{ + if (source && (source->isTapped() || source->hasSummoningSickness())) + { + return 0; + } + return 1; +} + +int TapCost::canPay() +{ + return isPaymentSet(); +} + +int TapCost::doPay() +{ + MTGCardInstance * _source = (MTGCardInstance *) source; + if (_source) + { + _source->tap(); + return 1; + } + return 0; +} +//unTap cost +UnTapCost * UnTapCost::clone() const +{ + UnTapCost * ec = NEW UnTapCost(*this); + return ec; +} + +UnTapCost::UnTapCost() : + ExtraCost("UnTap") +{ +} + +int UnTapCost::isPaymentSet() +{ + if (source && !source->isTapped()) + { + return 0; + } + return 1; +} + +int UnTapCost::canPay() +{ + return isPaymentSet(); +} + +int UnTapCost::doPay() +{ + MTGCardInstance * _source = (MTGCardInstance *) source; + if (_source) + { + _source->untap(); + return 1; + } + return 0; +} + //Tap target cost TapTargetCost * TapTargetCost::clone() const { diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 5910ea85f..e19b32210 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -10,6 +10,7 @@ #include "MTGDeck.h" #include "Translate.h" #include "ThisDescriptor.h" +#include "ExtraCost.h" //const string kPreLordKeywords[] = { "foreach(", "lord(", "aslongas(", "teach(", "all(" }; const string kLordKeywords[] = { "lord(", "foreach(", "aslongas(", "teach(", "all(" }; @@ -815,8 +816,13 @@ int AbilityFactory::parseRestriction(string s) // When abilities encapsulate each other, gets the deepest one (it is the one likely to have the most relevant information) MTGAbility * AbilityFactory::getCoreAbility(MTGAbility * a) { - if (AForeach * fea = dynamic_cast(a)) - return fea->ability; + AForeach * fea = dynamic_cast(a); + if(fea) + return getCoreAbility(fea->ability); + + AAsLongAs * aea = dynamic_cast(a); + if(aea) + return getCoreAbility(aea->ability); GenericTargetAbility * gta = dynamic_cast (a); if (gta) @@ -4105,29 +4111,39 @@ int ActivatedAbility::reactToTargetClick(Targetable * object) int ActivatedAbility::activateAbility() { MTGAbility * fmp = NULL; - if(GenericActivatedAbility * gaa = dynamic_cast(this)) - { - AForeach * fea = dynamic_cast(gaa->ability); - if(fea) - fmp = fea->ability; - } + bool wasTappedForMana = false; //taking foreach manaproducers off the stack and sending tapped for mana events. - AManaProducer * amp = dynamic_cast (fmp); - if(amp) + AbilityFactory af; + fmp = af.getCoreAbility(this); + AManaProducer * amp = dynamic_cast (this); + AManaProducer * femp = dynamic_cast (fmp); + if((amp||femp) && cost && cost->extraCosts) { - needsTapping = amp->tap; + for(unsigned int i = 0; i < cost->extraCosts->costs.size();i++) + { + ExtraCost * tapper = dynamic_cast(cost->extraCosts->costs[i]); + if(tapper) + needsTapping = 1; + wasTappedForMana = true; + } } - if (needsTapping && source->isInPlay()) + else if(amp||femp) { - if (amp) + if(amp) + needsTapping = amp->tap; + else + needsTapping = femp->tap; + } + if (needsTapping && (source->isInPlay()|| wasTappedForMana)) + { + if (amp||femp) { GameObserver *g = GameObserver::GetInstance(); WEvent * e = NEW WEventCardTappedForMana(source, 0, 1); g->receiveEvent(e); } - source->tap(); } - if (amp) + if (amp||femp) { counters++; if(sideEffect && usesBeforeSideEffects.size()) @@ -4137,8 +4153,6 @@ int ActivatedAbility::activateAbility() this->resolve(); return 1; } - if (needsTapping && source->isInPlay()) - source->tap(); counters++; if(sideEffect && usesBeforeSideEffects.size()) { diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index bdedfd83e..bf2cb2310 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -397,7 +397,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) } ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); - int payResult = player->getManaPool()->pay(cost); + int payResult = player->getManaPool()->pay(card->getManaCost()); card->getManaCost()->doPayExtra(); ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 2b84975ab..ef44f56fb 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -93,7 +93,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan case 't': //Tap if (value == "t") { - //default Tap is handled outside of Manacost + manaCost->addExtraCost(NEW TapCost); } else { @@ -153,6 +153,11 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan manaCost->addExtraCost(NEW LifeorManaCost(NULL,manaType)); break; } + case 'q': + { + manaCost->addExtraCost(NEW UnTapCost); + break; + } case 'c': //Counters { size_t counter_start = value.find("(");