diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 2da07339a..f388e9257 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -26,6 +26,17 @@ using std::map; // // Misc classes // +class MTGEventText: public MTGAbility +{ +public: + int textAlpha; + string text; + void Update(float dt); + void Render(); + MTGEventText(GameObserver* observer, int _id,MTGCardInstance * card, string text); + virtual MTGEventText * clone() const; +}; + class WParsedInt { public: @@ -41,6 +52,8 @@ public: private: void init(string s, Spell * spell, MTGCardInstance * card) { + if(!s.size()) + return; if(!card) return; MTGCardInstance * target = card->target; @@ -91,6 +104,10 @@ private: if(intValue < 0) intValue = 0; } + else if (s == "castx") + { + intValue = card->castX; + } else if (s == "gear") { intValue = target->equipment; @@ -135,6 +152,97 @@ private: } SAFE_DELETE(tc); } + else if (s.find("counter{") != string::npos) + { + intValue = 0; + vectorcounterName = parseBetween(s,"counter{","}"); + if(counterName.size()) + { + AbilityFactory abf(target->getObserver()); + Counter * counter = abf.parseCounter(counterName[1], NULL); + if(counter && target->counters && target->counters->hasCounter(counter->name.c_str(),counter->power,counter->toughness)) + { + Counter * targetCounter = target->counters->hasCounter(counter->name.c_str(), counter->power, counter->toughness); + intValue = targetCounter->nb; + } + SAFE_DELETE(counter); + } + } + else if (s.find("convertedcost:") != string::npos || s.find("power:") != string::npos || s.find("toughness:") != string::npos) + { + bool powerCheck = false; + bool toughnessCheck = false; + bool costCheck = false; + intValue = 0; + vectorconvertedType = parseBetween(s,"convertedcost:",":"); + if(convertedType.size()) + costCheck = true; + else + { + convertedType = parseBetween(s,"power:",":"); + if(convertedType.size()) + powerCheck = true; + else + { + convertedType = parseBetween(s,"toughness:",":"); + if(convertedType.size()) + toughnessCheck = true; + } + } + if(!convertedType.size()) + return; + bool high = false; + int highest = 0; + int lowest = 5000; + if(convertedType[1].find("highest") != string::npos) + high = true; + + string theType = convertedType[2]; + size_t zoned = theType.find(":"); + if(zoned == string::npos) + { + theType.append("|mybattlefield"); + } + else + { + replace(theType.begin(), theType.end(), ':', '|'); + } + TargetChooserFactory tf(card->getObserver()); + TargetChooser * tc = tf.createTargetChooser(theType.c_str(),NULL); + int check = 0; + for (int i = 0; i < 2; i++) + { + Player * p = card->getObserver()->players[i]; + MTGGameZone * zones[] = { p->game->battlefield, p->game->graveyard, p->game->hand, p->game->library }; + for (int k = 0; k < 4; k++) + { + MTGGameZone * zone = zones[k]; + if(tc->targetsZone(zone,target)) + { + for(unsigned int w = 0;w < zone->cards.size();++w) + { + MTGCardInstance * cCard = zone->cards[w]; + if(tc->canTarget(cCard)) + { + if(costCheck) + check = cCard->getManaCost()->getConvertedCost(); + if(powerCheck) + check = cCard->power; + if(toughnessCheck) + check = cCard->toughness; + + check > highest?highest = check:highest = highest; + check <= lowest?lowest = check:lowest = lowest; + } + } + } + } + } + if(lowest == 5000) + lowest = 0; + SAFE_DELETE(tc); + intValue = high?highest:lowest; + } else if (s == "sunburst") { intValue = 0; @@ -147,6 +255,14 @@ private: { intValue = target->controller()->life; } + else if (s == "highestlifetotal") + { + intValue = target->controller()->life <= target->controller()->opponent()->life? target->controller()->opponent()->life:target->controller()->life; + } + else if (s == "lowestlifetotal") + { + intValue = target->controller()->life <= target->controller()->opponent()->life? target->controller()->life:target->controller()->opponent()->life; + } else if (s == "thatmuch") { //the value that much is a variable to be used with triggered abilities. @@ -884,7 +1000,7 @@ public: }; //if/ifnot Cond then EFFECT -class IfThenAbility: public ActivatedAbility +class IfThenAbility: public InstantAbility { public: MTGAbility * delayedAbility; @@ -1067,37 +1183,45 @@ public: class AABuryCard: public ActivatedAbility { public: + MTGAbility * andAbility; AABuryCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target); int resolve(); const char * getMenuText(); AABuryCard * clone() const; + ~AABuryCard(); }; class AADestroyCard: public ActivatedAbility { public: + MTGAbility * andAbility; AADestroyCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target); int resolve(); const char * getMenuText(); AADestroyCard * clone() const; + ~AADestroyCard(); }; class AASacrificeCard: public ActivatedAbility { public: + MTGAbility * andAbility; AASacrificeCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target); int resolve(); const char * getMenuText(); AASacrificeCard * clone() const; + ~AASacrificeCard(); }; class AADiscardCard: public ActivatedAbility { public: + MTGAbility * andAbility; AADiscardCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target); int resolve(); const char * getMenuText(); AADiscardCard * clone() const; + ~AADiscardCard(); }; /* Generic Target Ability */ @@ -1110,8 +1234,9 @@ public: int counters; MTGGameZone * activeZone; string newName; + string tcString; - GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "", int restrictions = 0, MTGGameZone * dest = NULL); + GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "", int restrictions = 0, MTGGameZone * dest = NULL,string tcString =""); const char * getMenuText(); ~GenericTargetAbility(); GenericTargetAbility * clone() const; @@ -1775,6 +1900,49 @@ public: } }; +//this generic ability assumes that what is added will take care of its own removel. +class GenericAbilityMod: public InstantAbility, public NestedAbility +{ +public: + GenericAbilityMod(GameObserver* observer, int _id, MTGCardInstance * _source, Damageable * _target, MTGAbility * ability) : + InstantAbility(observer, _id, _source,_target), NestedAbility(ability) + { + ability->target = _target; + } + + int addToGame() + { + InstantAbility::addToGame(); + return 1; + } + + int resolve() + { + MTGAbility * toAdd = ability->clone(); + toAdd->forceDestroy = -1; + toAdd->target = target; + toAdd->addToGame(); + return 1; + } + + const char * getMenuText() + { + return ability->getMenuText(); + } + + GenericAbilityMod * clone() const + { + GenericAbilityMod * a = NEW GenericAbilityMod(*this); + a->ability = ability->clone(); + return a; + } + + ~GenericAbilityMod() + { + SAFE_DELETE(ability); + } +}; + //Circle of Protections class ACircleOfProtection: public TargetAbility { @@ -2987,6 +3155,7 @@ class AADamager: public ActivatedAbilityTP { public: string d; + bool redirected; AADamager(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, string d, ManaCost * _cost = NULL, int who = TargetChooser::UNSET); @@ -5035,7 +5204,7 @@ public: target = copy; source->target = copy; copy->summoningSickness = 0; - } + } return 1; } diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 1ea069a25..31c1d5a34 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -54,6 +54,7 @@ public: MTGGameZone * currentZone; Pos* view; int X; + int castX; int alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE + 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 */ @@ -118,6 +119,7 @@ public: Counters * counters; const string getDisplayName() const; MTGCardInstance * target; + Player * playerTarget; vector backupTargets; diff --git a/projects/mtg/include/TargetsList.h b/projects/mtg/include/TargetsList.h index cf4d4c88a..f1f6f1cd5 100644 --- a/projects/mtg/include/TargetsList.h +++ b/projects/mtg/include/TargetsList.h @@ -32,6 +32,14 @@ public: Spell * getNextSpellTarget(Spell * previous = 0); Damage * getNextDamageTarget(Damage * previous = 0); Targetable * getNextTarget(Targetable * previous = 0); + vector getTargetsFrom() + { + return targets; + } + void setTargetsTo(vectortargetTo) + { + targets = targetTo; + } void initTargets() { targets.clear(); diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index b8250b642..64e218cf1 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -38,10 +38,10 @@ int ActionLayer::removeFromGame(ActionElement * e) AbilityFactory af(observer); MTGAbility * a = dynamic_cast(e); - if (a != NULL) { - AManaProducer * manaObject = dynamic_cast(af.getCoreAbility(a)); + MTGAbility * toCheck = af.getCoreAbility(a); + AManaProducer * manaObject = dynamic_cast(toCheck); if(manaObject) { for (size_t i = 0; i < manaObjects.size(); i++) @@ -53,7 +53,6 @@ int ActionLayer::removeFromGame(ActionElement * e) } mObjects.erase(mObjects.begin() + i); return 1; - } bool ActionLayer::moveToGarbage(ActionElement * e) @@ -71,7 +70,7 @@ void ActionLayer::cleanGarbage() { for (size_t i = 0; i < garbage.size(); ++i) { - delete (garbage[i]); + SAFE_DELETE(garbage[i]); } garbage.clear(); } diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 6a7d349ce..f89932b26 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -3,6 +3,45 @@ #include "Translate.h" #include + +//display a text animation, this is not a real ability. +MTGEventText::MTGEventText(GameObserver* observer, int _id, MTGCardInstance * card, string textToShow) : +MTGAbility(observer, _id,card) +{ + textAlpha = 255; + text = textToShow; +} + +void MTGEventText::Update(float dt) +{ + if (textAlpha) + { + textAlpha -= static_cast (200 * dt); + if (textAlpha < 0) + { + textAlpha = 0; + this->forceDestroy = 1; + } + } + MTGAbility::Update(dt); +} + +void MTGEventText::Render() +{ + if (!textAlpha) + return; + WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT); + mFont->SetScale(2 - (float) textAlpha / 130); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(text.c_str(), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, JGETEXT_CENTER); +} + +MTGEventText * MTGEventText::clone() const +{ + return NEW MTGEventText(*this); +} + +//////////////////////// //Activated Abilities //Generic Activated Abilities @@ -17,9 +56,9 @@ GenericActivatedAbility::GenericActivatedAbility(GameObserver* observer, string int GenericActivatedAbility::resolve() { //Note: I've seen a similar block in some other MTGAbility, can this be refactored . - source->X = 0; if (abilityCost) { + source->X = 0; ManaCost * diff = abilityCost->Diff(getCost()); source->X = diff->hasX(); SAFE_DELETE(diff); @@ -704,6 +743,7 @@ AABuryCard::AABuryCard(GameObserver* observer, int _id, MTGCardInstance * _sourc ActivatedAbility(observer, _id, _source) { target = _target; + andAbility = NULL; } int AABuryCard::resolve() @@ -711,7 +751,24 @@ int AABuryCard::resolve() MTGCardInstance * _target = (MTGCardInstance *) target; if (_target) { - return _target->bury(); + _target->bury(); + while(_target->next) + _target = _target->next; + if(andAbility) + { + MTGAbility * andAbilityClone = andAbility->clone(); + andAbilityClone->target = _target; + if(andAbility->oneShot) + { + andAbilityClone->resolve(); + SAFE_DELETE(andAbilityClone); + } + else + { + andAbilityClone->addToGame(); + } + } + return 1; } return 0; } @@ -723,7 +780,15 @@ const char * AABuryCard::getMenuText() AABuryCard * AABuryCard::clone() const { - return NEW AABuryCard(*this); + AABuryCard * a = NEW AABuryCard(*this); + if(andAbility) + a->andAbility = andAbility->clone(); + return a; +} + +AABuryCard::~AABuryCard() +{ + SAFE_DELETE(andAbility); } // Destroy @@ -732,6 +797,7 @@ AADestroyCard::AADestroyCard(GameObserver* observer, int _id, MTGCardInstance * ActivatedAbility(observer, _id, _source) { target = _target; + andAbility = NULL; } int AADestroyCard::resolve() @@ -739,7 +805,24 @@ int AADestroyCard::resolve() MTGCardInstance * _target = (MTGCardInstance *) target; if (_target) { - return _target->destroy(); + _target->destroy(); + while(_target->next) + _target = _target->next; + if(andAbility) + { + MTGAbility * andAbilityClone = andAbility->clone(); + andAbilityClone->target = _target; + if(andAbility->oneShot) + { + andAbilityClone->resolve(); + SAFE_DELETE(andAbilityClone); + } + else + { + andAbilityClone->addToGame(); + } + } + return 1; } return 0; } @@ -751,14 +834,22 @@ const char * AADestroyCard::getMenuText() AADestroyCard * AADestroyCard::clone() const { - return NEW AADestroyCard(*this); -} + AADestroyCard * a = NEW AADestroyCard(*this); + if(andAbility) + a->andAbility = andAbility->clone(); + return a; +} +AADestroyCard::~AADestroyCard() +{ + SAFE_DELETE(andAbility); +} // Sacrifice AASacrificeCard::AASacrificeCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target) : ActivatedAbility(observer, _id, _source) { target = _target; + andAbility = NULL; } int AASacrificeCard::resolve() @@ -770,6 +861,22 @@ int AASacrificeCard::resolve() WEvent * e = NEW WEventCardSacrifice(_target); game->receiveEvent(e); p->game->putInGraveyard(_target); + while(_target->next) + _target = _target->next; + if(andAbility) + { + MTGAbility * andAbilityClone = andAbility->clone(); + andAbilityClone->target = _target; + if(andAbility->oneShot) + { + andAbilityClone->resolve(); + SAFE_DELETE(andAbilityClone); + } + else + { + andAbilityClone->addToGame(); + } + } return 1; } return 0; @@ -782,15 +889,22 @@ const char * AASacrificeCard::getMenuText() AASacrificeCard * AASacrificeCard::clone() const { - return NEW AASacrificeCard(*this); + AASacrificeCard * a = NEW AASacrificeCard(*this); + if(andAbility) + a->andAbility = andAbility->clone(); + return a; +} +AASacrificeCard::~AASacrificeCard() +{ + SAFE_DELETE(andAbility); } - // Discard AADiscardCard::AADiscardCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target) : ActivatedAbility(observer, _id, _source) { target = _target; + andAbility = NULL; } int AADiscardCard::resolve() @@ -802,6 +916,22 @@ int AADiscardCard::resolve() WEvent * e = NEW WEventCardDiscard(_target); game->receiveEvent(e); p->game->putInGraveyard(_target); + while(_target->next) + _target = _target->next; + if(andAbility) + { + MTGAbility * andAbilityClone = andAbility->clone(); + andAbilityClone->target = _target; + if(andAbility->oneShot) + { + andAbilityClone->resolve(); + SAFE_DELETE(andAbilityClone); + } + else + { + andAbilityClone->addToGame(); + } + } return 1; } return 0; @@ -814,9 +944,15 @@ const char * AADiscardCard::getMenuText() AADiscardCard * AADiscardCard::clone() const { - return NEW AADiscardCard(*this); + AADiscardCard * a = NEW AADiscardCard(*this); + if(andAbility) + a->andAbility = andAbility->clone(); + return a; +} +AADiscardCard::~AADiscardCard() +{ + SAFE_DELETE(andAbility); } - AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, string nbcardsStr, int who) : ActivatedAbilityTP(observer, _id, card, _target, _cost, who), nbcardsStr(nbcardsStr) @@ -995,7 +1131,11 @@ int AAMorph::resolve() else { a->addToGame(); - _target->cardsAbilities.push_back(a); + MayAbility * dontAdd = dynamic_cast(a); + if(!dontAdd) + { + _target->cardsAbilities.push_back(a); + } } } } @@ -1087,7 +1227,11 @@ int AAFlip::resolve() else { a->addToGame(); - _target->cardsAbilities.push_back(a); + MayAbility * dontAdd = dynamic_cast(a); + if(!dontAdd) + { + _target->cardsAbilities.push_back(a); + } } } } @@ -1724,6 +1868,8 @@ int AACloner::resolve() spell->resolve(); spell->source->isToken = 1; spell->source->fresh = 1; + spell->source->model = spell->source; + spell->source->model->data = spell->source; if(_target->isToken) { spell->source->power = _target->origpower; @@ -1930,6 +2076,8 @@ int AAMover::resolve() } } p->game->putInZone(_target, fromZone, destZone); + while(_target->next) + _target = _target->next; if(andAbility) { MTGAbility * andAbilityClone = andAbility->clone(); @@ -2401,7 +2549,7 @@ ANewAffinity * ANewAffinity::clone() const //IfThenEffect IfThenAbility::IfThenAbility(GameObserver* observer, int _id, MTGAbility * delayedAbility, MTGCardInstance * _source, Targetable * _target, int type,string Cond) : -ActivatedAbility(observer, _id, _source),delayedAbility(delayedAbility), type(type),Cond(Cond) +InstantAbility(observer, _id, _source),delayedAbility(delayedAbility), type(type),Cond(Cond) { target = _target; } @@ -2508,9 +2656,9 @@ int MayAbility::testDestroy() if (game->mLayers->actionLayer()->getIndexOf(mClone) != -1) return 0; if(game->currentPlayer == source->controller() && game->isInterrupting == source->controller() && dynamic_cast(AbilityFactory::getCoreAbility(ability))) - //if its my turn, and im interrupting myself(why?) then set interrupting to previous interrupter if the ability was a manaability - //special case since they don't use the stack. - game->mLayers->stackLayer()->setIsInterrupting(previousInterrupter, false); + //if its my turn, and im interrupting myself(why?) then set interrupting to previous interrupter if the ability was a manaability + //special case since they don't use the stack. + game->mLayers->stackLayer()->setIsInterrupting(previousInterrupter, false); return 1; } @@ -2611,6 +2759,7 @@ int MenuAbility::testDestroy() return 0; if (game->mLayers->actionLayer()->getIndexOf(mClone) != -1) return 0; + return 1; } @@ -2629,14 +2778,17 @@ int MenuAbility::reactToChoiceClick(Targetable * object,int choice,int control) if(choice == i) mClone = abilities[choice]->clone(); else - abilities[i]->clone();//all get cloned for clean up purposes. + SAFE_DELETE(abilities[i]); + //else + // abilities[i]->clone();//all get cloned for clean up purposes. EDIT:removed, cause memleaks. } if(!mClone) return 0; mClone->target = abilities[choice]->target; mClone->oneShot = true; mClone->forceDestroy = 1; - mClone->resolve(); + mClone->canBeInterrupted = false; + mClone->resolve(); SAFE_DELETE(mClone); if (source->controller() == game->isInterrupting) game->mLayers->stackLayer()->cancelInterruptOffer(ActionStack::DONT_INTERRUPT, false); @@ -2765,11 +2917,10 @@ MultiAbility::~MultiAbility() abilities.clear(); } - //Generic Target Ability GenericTargetAbility::GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, - ManaCost * _cost, string limit,MTGAbility * sideEffects,string usesBeforeSideEffects, int restrictions, MTGGameZone * dest) : - TargetAbility(observer, _id, _source, _tc, _cost, restrictions, castRestriction), limit(limit), activeZone(dest),newName(newName) + ManaCost * _cost, string limit,MTGAbility * sideEffects,string usesBeforeSideEffects, int restrictions, MTGGameZone * dest,string _tcString) : + TargetAbility(observer, _id, _source, _tc, _cost, restrictions, castRestriction), limit(limit), activeZone(dest),newName(newName),tcString(_tcString) { ability = a; MTGAbility * core = AbilityFactory::getCoreAbility(a); @@ -2789,7 +2940,6 @@ const char * GenericTargetAbility::getMenuText() MTGAbility * core = AbilityFactory::getCoreAbility(ability); if (AAMover * move = dynamic_cast(core)) return (move->getMenuText(tc)); - return ability->getMenuText(); } @@ -2811,6 +2961,15 @@ int GenericTargetAbility::isReactingToClick(MTGCardInstance * card, ManaCost * m } if (limitPerTurn && counters >= limitPerTurn) return 0; + if(tcString.size() && !tc->targetListSet()) + { + TargetChooser * current = this->getActionTc(); + TargetChooserFactory tcf(game); + TargetChooser *refreshed = tcf.createTargetChooser(tcString, source, this); + refreshed->setTargetsTo(current->getTargetsFrom()); + this->setActionTC(refreshed); + SAFE_DELETE(current); + } return TargetAbility::isReactingToClick(card, mana); } @@ -2977,15 +3136,15 @@ ATransformer::ATransformer(GameObserver* observer, int id, MTGCardInstance * sou removeTypes = (stypes.find("removetypes") != string::npos); if (stypes.find("allsubtypes") != string::npos || stypes.find("removecreaturesubtypes") != string::npos) - { + { const vector values = MTGAllCards::getValuesById(); for (size_t i = 0; i removeType(*it); - } - else if(_target->hasSubtype(*it)) - { - //we generally don't want to give a creature type creature again - //all it does is create a sloppy mess of the subtype line on alternative quads - //also creates instances where a card gained a type from an ability like this one - //then loses the type through another ability, when this effect is destroyed the creature regains - //the type, which is wrong. - dontremove.push_back(*it); - } - else - { - _target->addType(*it); - } + + if(removeCreatureSubtypes) + { + _target->removeType(*it); + } + else if(_target->hasSubtype(*it)) + { + //we generally don't want to give a creature type creature again + //all it does is create a sloppy mess of the subtype line on alternative quads + //also creates instances where a card gained a type from an ability like this one + //then loses the type through another ability, when this effect is destroyed the creature regains + //the type, which is wrong. + dontremove.push_back(*it); + } + else + { + _target->addType(*it); + } } } for (it = colors.begin(); it != colors.end(); it++) @@ -3226,6 +3386,7 @@ int ATransformer::destroy() if(newAbilities[_target].at(i)) { newAbilities[_target].at(i)->forceDestroy = 1; + newAbilities[_target].at(i)->removeFromGame(); } } if (newAbilities.find(_target) != newAbilities.end()) @@ -3233,11 +3394,12 @@ int ATransformer::destroy() newAbilities.erase(_target); } } - if (remove) + if (remove || removeCreatureSubtypes) { for (it = oldtypes.begin(); it != oldtypes.end(); it++) { - _target->addType(*it); + if(!_target->hasSubtype(*it)) + _target->addType(*it); } } //in the case that we removed or added types to a card, so that it retains its original name when the effect is removed. @@ -3294,6 +3456,7 @@ ATransformerInstant::~ATransformerInstant() { SAFE_DELETE(ability); } + //P/t ueot PTInstant::PTInstant(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, WParsedPT * wppt,string s,bool nonstatic) : InstantAbility(observer, id, source, target), wppt(wppt),s(s),nonstatic(nonstatic) @@ -3325,7 +3488,6 @@ PTInstant::~PTInstant() { SAFE_DELETE(ability); } - // ASwapPTUEOT ASwapPTUEOT::ASwapPTUEOT(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target) : InstantAbility(observer, id, source, target) @@ -3682,7 +3844,12 @@ AUpkeep::AUpkeep(GameObserver* observer, int _id, MTGCardInstance * card, MTGAbi { paidThisTurn = 0; aType = MTGAbility::UPCOST; - backupMana = NEW ManaCost(this->getCost()); + if(Cumulative) + { + backupMana = NEW ManaCost(); + backupMana->copy(this->getCost()); + backupMana->addExtraCosts(this->getCost()->extraCosts); + } } int AUpkeep::receiveEvent(WEvent * event) @@ -3705,7 +3872,7 @@ void AUpkeep::Update(float dt) // once: 0 means always go off, 1 means go off only once, 2 means go off only once and already has. if (newPhase != currentPhase && source->controller() == game->currentPlayer && once < 2) { - if (newPhase == MTG_PHASE_UNTAP) + if (newPhase == MTG_PHASE_BEFORE_BEGIN) { paidThisTurn = 0; } @@ -3770,8 +3937,11 @@ AUpkeep * AUpkeep::clone() const AUpkeep::~AUpkeep() { + if(Cumulative) + { + SAFE_DELETE(backupMana); + } SAFE_DELETE(ability); - SAFE_DELETE(backupMana); } //A Phase based Action diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 4d814cd95..39e0f0abd 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -37,6 +37,8 @@ CardPrimitive::CardPrimitive() CardPrimitive::CardPrimitive(CardPrimitive * source) { + if(!source) + return; basicAbilities = source->basicAbilities; for (size_t i = 0; i < source->types.size(); ++i) @@ -215,6 +217,7 @@ void CardPrimitive::setSubtype(const string& value) break; } } + int id = MTGAllCards::add(value, parentType); addType(id); } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 5218fcaa2..b36f5de50 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -162,6 +162,7 @@ void MTGCardInstance::initMTGCI() thatmuch = 0; flanked = 0; target = NULL; + playerTarget = NULL; type_as_damageable = DAMAGEABLE_MTGCARDINSTANCE; banding = NULL; owner = NULL; diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index d1dc26d24..36893dd0d 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -29,14 +29,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta found = s.find("targetedplayer"); if (found == 0) { - if(card && card->backupTargets.size()) - { - Player * pTarget = dynamic_cast(card->backupTargets[0]); + Player * pTarget = card->playerTarget; if (ability) pTarget = dynamic_cast(ability->target); if(pTarget) return NEW PlayerTargetChooser(observer, card, 1, pTarget); - } }; found = s.find("opponent");