diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index c19867861..8e74815b4 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -669,8 +669,15 @@ public: { WEventCardSacrifice * e = dynamic_cast (event); if (!e) return 0; - if (!tc->canTarget(e->card)) return 0; - + MTGCardInstance * check = e->cardAfter; + MTGGameZone * oldZone = e->cardAfter->currentZone; + check->currentZone = check->previousZone; + if (!tc->canTarget(check,true)) + { + check->currentZone = oldZone; + return 0; + } + check->currentZone = oldZone; return 1; } @@ -2809,6 +2816,11 @@ public: tokenReciever = ((MTGCardInstance*)target)->controller(); break; } + case TargetChooser::TARGETED_PLAYER: + { + tokenReciever = source->playerTarget; + break; + } default: tokenReciever = source->controller(); break; @@ -2865,6 +2877,95 @@ public: }; +//targetable abilities which are added to targeted players game. +class ATargetedAbilityCreator: public ActivatedAbility +{ +public: + string sabilities; + string name; + int who; + MTGCardInstance * myDummy; + Player * abilityReciever; + ATargetedAbilityCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, ManaCost * _cost,string _name, string abilityToAdd, int who = 0) : + ActivatedAbility(observer, _id, _source, _cost, 0),name(_name),sabilities(abilityToAdd), who(who) + { + } + + int resolve() + { + setAbilityOwner(); + myDummy = NEW MTGCardInstance(); + setAbilityOwner(); + myDummy->setObserver(abilityReciever->getObserver()); + myDummy->owner = abilityReciever; + vectormagictextlines = split(sabilities,'_'); + if(magictextlines.size()) + { + string newMagicText = ""; + for(unsigned int i = 0; i < magictextlines.size(); i++) + { + newMagicText.append(magictextlines[i]); + newMagicText.append("\n"); + } + myDummy->magicText = newMagicText; + } + else + myDummy->magicText = sabilities; + abilityReciever->game->garbage->addCard(myDummy); + Spell * spell = NEW Spell(game, myDummy); + spell->resolve(); + myDummy = spell->source; + spell->source->owner = abilityReciever; + delete spell; + return 1; + } + + void setAbilityOwner() + { + switch(who) + { + case TargetChooser::CONTROLLER: + abilityReciever = source->controller(); + break; + case TargetChooser::OPPONENT: + abilityReciever = source->controller()->opponent(); + break; + case TargetChooser::TARGET_CONTROLLER: + if(target) + { + abilityReciever = ((MTGCardInstance*)target)->controller(); + break; + } + case TargetChooser::TARGETED_PLAYER: + { + abilityReciever = source->playerTarget; + break; + } + default: + abilityReciever = source->controller()->opponent(); + break; + } + } + + const char * getMenuText() + { + if(name.size()) + return name.c_str(); + return "Ability"; + } + + ATargetedAbilityCreator * clone() const + { + ATargetedAbilityCreator * a = NEW ATargetedAbilityCreator(*this); + return a; + } + + ~ATargetedAbilityCreator() + { + } + +}; +/// //Foreach (plague rats...) class AForeach: public ListMaintainerAbility, public NestedAbility { diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index bfc6b13ed..6a680cd41 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -179,8 +179,9 @@ struct WEventCardBlocked : public WEventCardUpdate { //event when card is sacrificed. struct WEventCardSacrifice : public WEventCardUpdate { - WEventCardSacrifice(MTGCardInstance * card); - virtual Targetable * getTarget(int target); + MTGCardInstance * cardAfter; + WEventCardSacrifice(MTGCardInstance * card,MTGCardInstance * afterCard); + virtual Targetable * getTarget(int target); }; //event when card is discarded. diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index ea48af30e..4fca005df 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -292,7 +292,7 @@ Spell::~Spell() int Spell::resolve() { - if (!source->hasType(Subtypes::TYPE_INSTANT) && !source->hasType(Subtypes::TYPE_SORCERY)) + if (!source->hasType(Subtypes::TYPE_INSTANT) && !source->hasType(Subtypes::TYPE_SORCERY) && source->name.size()) { Player * p = source->controller(); int castMethod = source->castMethod; diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 2d4f24ed6..3a5a896b4 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1279,11 +1279,12 @@ int AASacrificeCard::resolve() if (_target) { Player * p = _target->controller(); - WEvent * e = NEW WEventCardSacrifice(_target); - game->receiveEvent(e); + MTGCardInstance * beforeCard = _target; p->game->putInGraveyard(_target); while(_target->next) _target = _target->next; + WEvent * e = NEW WEventCardSacrifice(beforeCard,_target); + game->receiveEvent(e); if(andAbility) { MTGAbility * andAbilityClone = andAbility->clone(); @@ -1619,6 +1620,7 @@ int AAFlip::resolve() if(flipStats.size()) { MTGCard * fcard = MTGCollection()->getCardByName(flipStats); + if(!fcard) return 0; MTGCardInstance * myFlip = NEW MTGCardInstance(fcard, _target->controller()->game); _target->name = myFlip->name; _target->colors = myFlip->colors; @@ -1629,6 +1631,7 @@ int AAFlip::resolve() for(unsigned int i = 0;i < _target->cardsAbilities.size();i++) { MTGAbility * a = dynamic_cast(_target->cardsAbilities[i]); + if(a) game->removeObserver(a); } _target->cardsAbilities.clear(); @@ -1714,7 +1717,7 @@ int AAFlip::testDestroy() const char * AAFlip::getMenuText() { string s = flipStats; - sprintf(menuText, "Transform into %s", s.c_str()); + sprintf(menuText, "Transform:%s", s.c_str()); return menuText; } @@ -4307,9 +4310,10 @@ void AVanishing::Update(float dt) } if (newPhase == MTG_PHASE_UPKEEP && timeLeft <= 0 && next == 0) { - WEvent * e = NEW WEventCardSacrifice(source); - game->receiveEvent(e); + MTGCardInstance * beforeCard = source; source->controller()->game->putInGraveyard(source); + WEvent * e = NEW WEventCardSacrifice(beforeCard,source); + game->receiveEvent(e); } } } diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 13888887a..ee3c466dd 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -257,7 +257,6 @@ void CardGui::Render() icon = game?game->getResourceManager()->GetQuad("c_red"):WResourceManager::Instance()->GetQuad("c_red"); else if (card->hasSubtype("island")) icon = game?game->getResourceManager()->GetQuad("c_blue"):WResourceManager::Instance()->GetQuad("c_blue"); - if (icon.get()) { icon->SetColor(ARGB(static_cast(actA),255,255,255)); diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index e50cf4438..f97126b30 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -588,10 +588,11 @@ int SacrificeCost::doPay() { if (target) { - WEvent * e = NEW WEventCardSacrifice(target); + MTGCardInstance * beforeCard = target; + target->controller()->game->putInGraveyard(target); + WEvent * e = NEW WEventCardSacrifice(beforeCard,target); GameObserver * game = target->owner->getObserver(); game->receiveEvent(e); - target->controller()->game->putInGraveyard(target); target = NULL; if (tc) tc->initTargets(); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 81d66f141..75fd8e610 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -810,10 +810,10 @@ void GameObserver::gameStateBasedEffects() { if (c->has(Constants::TREASON)) { - WEvent * e = NEW WEventCardSacrifice(c); - receiveEvent(e); - + MTGCardInstance * beforeCard = c; p->game->putInGraveyard(c); + WEvent * e = NEW WEventCardSacrifice(beforeCard,c); + receiveEvent(e); } if (c->has(Constants::UNEARTH)) { diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 1619e4cca..73c3a973d 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1009,6 +1009,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG s.erase(stypesStartIndex, real_end - stypesStartIndex); } + found = s.find("ability$!"); + if (found != string::npos && storedString.empty()) + { + size_t real_end = s.find("!$", found); + size_t sIndex = found + 9; + storedString.append(s.substr(sIndex, real_end - sIndex).c_str()); + s.erase(sIndex, real_end - sIndex); + } + vector splitTrigger = parseBetween(s, "@", ":"); if (splitTrigger.size()) { @@ -1754,6 +1763,17 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG if (s.find(" owner") != string::npos) who = TargetChooser::OWNER; + //ability creator the target has to do the ability. + if(s.find("ability$") != string::npos) + { + if (storedString.size()) + { + ATargetedAbilityCreator * abl = NEW ATargetedAbilityCreator(observer, id, card,target, NULL,newName, storedString, who); + abl->oneShot = 1; + storedString.clear(); + return abl; + } + } //livingweapon (used for token below) bool aLivingWeapon = (s.find("livingweapon") != string::npos); @@ -3090,7 +3110,7 @@ int AbilityFactory::getAbilities(vector * v, Spell * spell, MTGCar card->life = 2; card->toughness = 2; card->setColor(0,1); - card->name = ""; + card->name = "Morph"; card->types.clear(); string cre = "Creature"; card->setType(cre.c_str()); diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index c55f3a8b6..fb212138e 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1110,7 +1110,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0); spell->source->morphed = true; spell->source->isMorphed = true; - spell->source->name = ""; + spell->source->name = "Morph"; spell->source->power = 2; spell->source->toughness = 2; copy->morphed = true; diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index ab9f6db32..33ea9943e 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -93,8 +93,8 @@ WEventcardDraw::WEventcardDraw(Player * player, int nb_cards) : { } -WEventCardSacrifice::WEventCardSacrifice(MTGCardInstance * card) : - WEventCardUpdate(card) +WEventCardSacrifice::WEventCardSacrifice(MTGCardInstance * card, MTGCardInstance * after) : + WEventCardUpdate(card),cardAfter(after) { } @@ -233,7 +233,10 @@ Targetable * WEventCardAttackedAlone::getTarget(int target) Targetable * WEventCardSacrifice::getTarget(int target) { - if (target) return card; + if (target) + { + return cardAfter; + } return NULL; }