Files
wagic/projects/mtg/src/MTGAbility.cpp
wagic.the.homebrew a418e10c47 Erwan
- Trying to add generic classes for Triggered abilities. PLEASE DO NOT USE THESE RIGHT NOW, Not Tested AT ALL !
2008-11-12 14:38:30 +00:00

1764 lines
47 KiB
C++

#include "../include/debug.h"
#include "../include/MTGAbility.h"
#include "../include/ManaCost.h"
#include "../include/MTGGameZones.h"
#include "../include/AllAbilities.h"
#include "../include/Damage.h"
#include "../include/TargetChooser.h"
#include "../include/CardGui.h"
#include "../include/MTGDeck.h"
int AbilityFactory::destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury){
GameObserver * game = GameObserver::GetInstance();
for (int i = 0; i < 2 ; i++){
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (current->hasType(type)){
if (bury){
game->players[i]->game->putInGraveyard(current);
}else{
game->mLayers->stackLayer()->addPutInGraveyard(current);
}
}
}
}
return 1;
}
int AbilityFactory::destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury){
GameObserver * game = GameObserver::GetInstance();
for (int i = 0; i < 2 ; i++){
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (current->hasColor(color)){
if (bury){
game->players[i]->game->putInGraveyard(current);
}else{
game->mLayers->stackLayer()->addPutInGraveyard(current);
}
}
}
}
return 1;
}
int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p){
Spell * spell = NEW Spell(card);
p->game->putInZone(card, zone, p->game->stack);
spell->resolve();
delete spell;
return 1;
}
Trigger * AbilityFactory::parseTrigger(string magicText){
int found = magicText.find("@");
if (found == string::npos) return NULL;
//Next Time...
found = magicText.find("next");
if (found != string::npos){
for (int i = 0; i < NB_MTG_PHASES; i++){
found = magicText.find(MTGPhaseCodeNames[i]);
if (found != string::npos){
return NEW TriggerNextPhase(i);
}
}
}
return NULL;
}
//Some basic functionalities that can be added automatically in the text file
int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
int dryMode = 0;
if (!spell) dryMode = 1;
GameObserver * game = GameObserver::GetInstance();
if (!card) card = spell->source;
MTGCardInstance * target = card->target;
if (!target) target = card;
string magicText = card->magicText;
if (card->alias && magicText.size() == 0){
//An awful way to get access to the aliasedcard
magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText;
}
string s;
int size = magicText.size();
if (size == 0) return 0;
unsigned int found;
int result = id;
while (magicText.size()){
found = magicText.find("\n");
if (found != string::npos){
s = magicText.substr(0,found);
magicText = magicText.substr(found+1);
}else{
s = magicText;
magicText = "";
}
#if defined (WIN32) || defined (LINUX)
char buf[4096];
sprintf(buf, "AUTO ACTION: %s\n", s.c_str());
OutputDebugString(buf);
#endif
TargetChooser * tc = NULL;
int doTap = 0;
string lordType = "";
Trigger * trigger = parseTrigger(s);
//Dirty way to remove the trigger text (could get in the way)
if (trigger){
found = s.find(":");
s = s.substr(found+1);
}
//Tap in the cost ?
if (s.find("{t}") != string::npos) doTap = 1;
//Target Abilities
found = s.find("target(");
if (found != string::npos){
int end = s.find(")");
string target = s.substr(found + 7,end - found - 7);
TargetChooserFactory tcf;
tc = tcf.createTargetChooser(target, card);
}
//Lord
found = s.find("lord(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
unsigned int end = s.find(")", found+5);
if (end != string::npos){
lordType = s.substr(found+5,end-found-5).c_str();
}
}
//Champion. Very basic, needs to be improved !
found = s.find("champion(name:");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
unsigned int end = s.find(")", found+14);
if (end != string::npos){
string type = s.substr(found+14,end-found-14).c_str();
game->addObserver(NEW APlagueRats(id,card,type.c_str()));
result++;
continue;
}
}
//Untapper (Ley Druid...)
found = s.find("untap");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s);
if (tc){
game->addObserver(NEW AUntaper(id, card, cost, tc));
}else{
target->tapped = 0;
}
result++;
continue;
}
//Tapper (icy manipulator)
found = s.find("tap");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s);
if (tc){
game->addObserver(NEW ATapper(id, card, cost, tc));
}else{
target->tapped = 1;
}
result++;
continue;
}
//Regeneration
found = s.find("}:regenerate");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s);
if (lordType.size() > 0){
game->addObserver(NEW ALord(id,card,lordType.c_str(),0,0,-1,cost));
}else{
if (tc){
//TODO
}else{
game->addObserver(NEW AStandardRegenerate(id, card, target, cost));
//TODO death ward !
}
}
result++;
continue;
}
//Bury
found = s.find("bury");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ABurier(id, card,tc));
}else{
target->controller()->game->putInGraveyard(target);
}
result++;
continue;
}
//Destroy
found = s.find("destroy");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ADestroyer(id, card,tc));
}else{
game->mLayers->stackLayer()->addPutInGraveyard(target);
}
result++;
continue;
}
//Damage
found = s.find("damage");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int damage;
ManaCost * cost = ManaCost::parseManaCost(s);
if (end != string::npos){
damage = atoi(s.substr(start+1,end-start-1).c_str());
}else{
damage = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ADamager(id, card, cost, damage, tc,doTap));
}else{
delete cost;
game->mLayers->stackLayer()->addDamage(card,spell->getNextDamageableTarget(), damage);
}
result++;
continue;
}
//gain/lose life
found = s.find("life");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int life;
ManaCost * cost = ManaCost::parseManaCost(s);
if (end != string::npos){
life = atoi(s.substr(start+1,end-start-1).c_str());
}else{
life = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_GOOD;
if (tc){
//TODO ?
}else{
if (cost->getConvertedCost() == 0 && !doTap){
delete cost;
card->controller()->life+=life;
}else{
//TODO;
}
}
result++;
continue;
}
//Draw
found = s.find("draw:");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int nbcards;
ManaCost * cost = ManaCost::parseManaCost(s);
if (end != string::npos){
nbcards = atoi(s.substr(start+1,end-start-1).c_str());
}else{
nbcards = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_GOOD;
if (trigger){
DrawEvent * action = NEW DrawEvent(card->controller(),nbcards);
game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action));
}else{
if (tc){
//TODO ?
}else{
if (cost->getConvertedCost() == 0){
delete cost;
game->mLayers->stackLayer()->addDraw(card->controller(),nbcards);
}else{
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
}
}
}
result++;
continue;
}
//Change Power/Toughness
found = s.find("/");
if (found != string::npos){
unsigned int start = s.find(":");
if (start == string::npos) start = -1;
int power = atoi(s.substr(start+1,size-found).c_str());
unsigned int end = s.find(" ",start);
int toughness;
if (end != string::npos){
toughness = atoi(s.substr(found+1,end-found-1).c_str());
}else{
toughness = atoi(s.substr(found+1).c_str());
}
if (dryMode){
if (power >=0 && toughness >= 0 ) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}
int limit = 0;
unsigned int limit_str = s.find("limit:");
if (limit_str != string::npos){
limit = atoi(s.substr(limit_str+6).c_str());
}
ManaCost * cost = ManaCost::parseManaCost(s);
if (lordType.size() > 0){
game->addObserver(NEW ALord(id,card,lordType.c_str(),power,toughness));
}else{
if(tc){
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc));
}else{
if (cost->getConvertedCost() == 0){
delete cost;
if(card->hasType("enchantment")){
game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness));
}else{
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness));
}
}else{
game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit));
}
}
}
result++;
continue;
}
//Mana Producer
found = s.find("add");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s.substr(0,found));
ManaCost * output = ManaCost::parseManaCost(s.substr(found));
if (cost->getConvertedCost()){
game->addObserver(NEW AManaProducer(id, target, output, cost));
}else{
delete cost;
if (doTap){
game->addObserver(NEW AManaProducer(id, target, output));
}else{
card->controller()->getManaPool()->add(output);
delete output;
}
}
result++;
continue;
}
//Gain/loose Ability
for (int j = 0; j < NB_BASIC_ABILITIES; j++){
found = s.find(MTGBasicAbilities[j]);
if (found!= string::npos){
int modifier = 1;
if (found > 0 && s[found-1] == '-') modifier = 0;
if (dryMode){
if (j == DEFENDER){
if (modifier == 1) return BAKA_EFFECT_BAD;
return BAKA_EFFECT_GOOD;
}else{
if (modifier == 1) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}
}
ManaCost * cost = ManaCost::parseManaCost(s);
if (lordType.size() > 0){
game->addObserver(NEW ALord(id,card,lordType.c_str(),0,0,j));
}else{
if (tc){
game->addObserver(NEW ABasicAbilityModifierUntilEOT(id, card, j, cost,tc, modifier));
}else{
if (cost->getConvertedCost() == 0){
delete cost;
if(card->hasType("enchantment")){
game->addObserver(NEW ABasicAbilityModifier(id, card,target, j,modifier));
}else{
game->addObserver(NEW AInstantBasicAbilityModifierUntilEOT(id, card,target, j,modifier));
}
}else{
game->addObserver(NEW ABasicAbilityAuraModifierUntilEOT(id, card,target, cost,j,modifier));
}
}
}
result++;
continue;
}
}
}
return result;
}
void AbilityFactory::addAbilities(int _id, Spell * spell){
MTGCardInstance * card = spell->source;
if (spell->cursor==1) card->target = spell->getNextCardTarget();
_id = magicText(_id, spell);
int putSourceInGraveyard = 0; //For spells that are not already InstantAbilities;
GameObserver * game = GameObserver::GetInstance();
int id = card->model->getId();
if (card->alias) id = card->alias;
switch (id){
case 1092: //Aladdin's lamp
{
AAladdinsLamp * ability = NEW AAladdinsLamp(_id, card);
game->addObserver(ability);
break;
}
case 130550: //Ancestor's chosen
{
int life = card->controller()->game->graveyard->nb_cards;
card->controller()->life+= life;
break;
}
case 1190: //Animate Artifact
{
int x = card->target->getManaCost()->getConvertedCost();
game->addObserver(NEW AConvertToCreatureAura(_id, card,card->target,x,x));
break;
}
case 1094: //Ank Of Mishra
{
AAnkhOfMishra * ability = NEW AAnkhOfMishra(_id,card);
game->addObserver(ability);
break;
}
case 1095: //Armageddon clock
{
AArmageddonClock * ability = NEW AArmageddonClock(_id,card);
game->addObserver(ability);
break;
}
case 106525: //Ascendant Evincar
{
game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1));
game->addObserver(NEW AColorLord(_id + 1, card,0,MTG_COLOR_BLACK,-1,-1));
break;
}
case 1096: //Basalt Monolith
{
int cost[] = {MTG_COLOR_ARTIFACT, 3};
AManaProducer * ability = NEW AManaProducer(_id, card, NEW ManaCost(cost,1));
AUntapManaBlocker * ability2 = NEW AUntapManaBlocker(_id+1, card, NEW ManaCost(cost,1));
AUnBlocker * ability3 = NEW AUnBlocker(_id+1, card,card, NEW ManaCost(cost,1));
game->addObserver(ability);
game->addObserver(ability2);
game->addObserver(ability3);
break;
}
case 1097: //Black Vise
{
game->addObserver( NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, 4));
break;
}
case 1191: //Blue Elemental Blast
{
if (card->target){
card->target->controller()->game->putInGraveyard(card->target);
}else{
Spell * starget = spell->getNextSpellTarget();
game->mLayers->stackLayer()->Fizzle(starget);
}
break;
}
case 1099: //Brass Man
{
int cost[] = {MTG_COLOR_ARTIFACT, 1};
game->addObserver(NEW AUntapManaBlocker(_id, card, NEW ManaCost(cost,1)));
break;
}
case 1237: //Channel
{
game->addObserver(NEW AChannel(_id, card));
break;
}
case 1282: //Chaoslace
{
if (card->target){
card->target->setColor(MTG_COLOR_RED, 1);
}else{
Spell * starget = spell->getNextSpellTarget();
starget->source->setColor(MTG_COLOR_RED, 1);
}
break;
}
case 1335: //Circle of protection : black
{
game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_BLACK));
break;
}
case 1336: //Circle of protection : blue
{
game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_BLUE));
break;
}
case 1337: //Circle of protection : green
{
game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_GREEN));
break;
}
case 1338: //Circle of protection : red
{
game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_RED));
break;
}
case 1339: //Circle of protection : white
{
game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_WHITE));
break;
}
case 1101: //clockwork Beast
{
game->addObserver(NEW AClockworkBeast(_id,card));
break;
}
case 1102: //Conservator
{
game->addObserver(NEW AConservator(_id,card));
break;
}
case 1196: //Counterspell
{
Spell * starget = spell->getNextSpellTarget();
if (starget) game->mLayers->stackLayer()->Fizzle(starget);
break;
}
case 1197: //Creature Bond
{
game->addObserver(NEW ACreatureBond(_id,card, card->target));
break;
}
case 1103: //Crystal Rod
{
int cost[] = {MTG_COLOR_BLUE, 1};
ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_WHITE,NEW ManaCost(cost,1) , 1);
game->addObserver(ability);
break;
}
case 1151: //Deathgrip
{
int _cost[] = {MTG_COLOR_BLACK, 2};
game->addObserver(NEW ASpellCounterEnchantment(_id, card, NEW ManaCost(_cost, 1),MTG_COLOR_GREEN));
break;
}
case 1152: //Deathlace
{
if (card->target){
card->target->setColor(MTG_COLOR_BLACK, 1);
}else{
Spell * starget = spell->getNextSpellTarget();
starget->source->setColor(MTG_COLOR_BLACK, 1);
}
break;
}
case 1105: //dingus Egg
{
ADingusEgg * ability = NEW ADingusEgg(_id,card);
game->addObserver(ability);
break;
}
case 1106: //Disrupting Scepter
{
ADisruptingScepter * ability = NEW ADisruptingScepter(_id,card);
game->addObserver(ability);
break;
}
case 1284: //Dragon Whelp
{
game->addObserver(NEW ADragonWhelp(_id,card));
break;
}
case 1108: //Ebony Horse
{
AEbonyHorse * ability = NEW AEbonyHorse(_id,card);
game->addObserver(ability);
break;
}
case 1345: //Farmstead
{
game->addObserver(NEW AFarmstead(_id, card,card->target));
break;
}
case 1291: //Fireball
{
int x = spell->cost->getConvertedCost() - 1; //TODO BETTER
game->addObserver(NEW AFireball(_id, card,spell, x));
break;
}
case 1245: //Force of Nature
{
game->addObserver(NEW AForceOfNature(_id,card));
break;
}
case 1110: //Glasses Of Urza
{
AGlassesOfUrza * ability = NEW AGlassesOfUrza(_id,card);
game->addObserver(ability);
break;
}
case 1112: //Howling Mine
{
game->addObserver(NEW AHowlingMine(_id, card));
break;
}
case 1252: //Instill Energy
{
game->addObserver(NEW AUntaperOnceDuringTurn(_id, card, card->target, NEW ManaCost()));
break;
}
case 1113: //Iron Star
{
int cost[] = {MTG_COLOR_ARTIFACT, 1};
ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_RED,NEW ManaCost(cost,1) , 1);
game->addObserver(ability);
break;
}
case 1351: // Island Sancturay
{
game->addObserver(NEW AIslandSanctuary(_id, card));
break;
}
case 1114: //Ivory cup
{
int cost[] = {MTG_COLOR_ARTIFACT, 1};
ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_WHITE,NEW ManaCost(cost,1) , 1);
game->addObserver(ability);
break;
}
case 1115: //Ivory Tower
{
game->addObserver(NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, 4, 1, 1));
break;
}
case 1117: //Jandors Ring
{
game->addObserver(NEW AJandorsRing( _id, card));
break;
}
case 1121: //Kormus Bell
{
game->addObserver(NEW AConvertLandToCreatures(id, card, "swamp"));
break;
}
case 1254: //Kudzu
{
game->addObserver(NEW AKudzu(id, card, card->target));
break;
}
case 1256: //LifeForce
{
int _cost[] = {MTG_COLOR_GREEN, 2};
game->addObserver(NEW ASpellCounterEnchantment(_id, card, NEW ManaCost(_cost, 1),MTG_COLOR_BLACK));
break;
}
case 1257: //Lifelace
{
if (card->target){
card->target->setColor(MTG_COLOR_GREEN, 1);
}else{
Spell * starget = spell->getNextSpellTarget();
starget->source->setColor(MTG_COLOR_GREEN, 1);
}
break;
}
case 1205: //Lifetap
{
game->addObserver(NEW AGiveLifeForTappedType(_id, card, "forest"));
break;
}
case 1259: //Living lands
{
game->addObserver(NEW AConvertLandToCreatures(id, card, "forest"));
break;
}
case 1124: //Mana Vault
{
int output[] = {MTG_COLOR_ARTIFACT, 3};
game->addObserver(NEW AManaProducer(_id,card,NEW ManaCost(output,1)));
int cost[] = {MTG_COLOR_ARTIFACT, 4};
game->addObserver(NEW AUntapManaBlocker(_id+1, card, NEW ManaCost(cost,1)));
game->addObserver(NEW ARegularLifeModifierAura(_id+2, card, card, MTG_PHASE_DRAW, -1, 1));
break;
}
case 1126:// Millstone
{
game->addObserver( NEW AMillstone(_id ,card));
break;
}
case 1215: //Power Leak
{
game->addObserver( NEW APowerLeak(_id ,card, card->target));
break;
}
case 1311: //Power Surge
{
game->addObserver( NEW APowerSurge(_id ,card));
break;
}
case 1358: //Purelace
{
if (card->target){
card->target->setColor(MTG_COLOR_WHITE, 1);
}else{
Spell * starget = spell->getNextSpellTarget();
starget->source->setColor(MTG_COLOR_WHITE, 1);
}
break;
}
case 1312: //Red Elemental Blast
{
if (card->target){
card->target->controller()->game->putInGraveyard(card->target);
}else{
Spell * starget = spell->getNextSpellTarget();
game->mLayers->stackLayer()->Fizzle(starget);
}
break;
}
case 1136: //Soul Net
{
game->addObserver( NEW ASoulNet(_id ,card));
break;
}
case 1139: //The Rack
{
game->addObserver( NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, -3));
break;
}
case 1140: //Throne of bones
{
int cost[] = {MTG_COLOR_ARTIFACT, 1};
ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_BLACK,NEW ManaCost(cost,1) , 1);
game->addObserver(ability);
break;
}
case 1142: //Wooden Sphere
{
int cost[] = {MTG_COLOR_ARTIFACT, 1};
ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_GREEN,NEW ManaCost(cost,1) , 1);
game->addObserver(ability);
break;
}
case 1143: //Animate Dead
{
game->addObserver(NEW AAnimateDead(_id, card, card->target));
break;
}
case 1144: //Bad moon
{
game->addObserver(NEW ABadMoon(_id,card));
break;
}
case 1148 : //Cursed lands
{
game->addObserver(NEW AWanderlust(_id, card, card->target));
break;
}
case 1156: //Drain Life
{
Damageable * target = spell->getNextDamageableTarget();
int x = spell->cost->getConvertedCost() - 2; //TODO Fix that !!! + X should be only black mana, that needs to be checked !
game->mLayers->stackLayer()->addDamage(card, target, x);
if (target->life < x) x = target->life;
game->currentlyActing()->life+=x;
break;
}
case 1159: //Erg Raiders
{
AErgRaiders* ability = NEW AErgRaiders(_id, card);
game->addObserver(ability);
break;
}
case 1164: //Howl from beyond
{
int x = spell->cost->getConvertedCost() - 1; //TODO, this is not enough, Spells shouls have a function like "xCost" because the spell might cost more than expected to launch
AInstantPowerToughnessModifierUntilEOT * ability = NEW AInstantPowerToughnessModifierUntilEOT( _id, card, card->target, x, 0);
game->addObserver(ability);
break;
}
case 1202: //Hurkyl's Recall
{
Player * player = spell->getNextPlayerTarget();
if (player){
for (int i = 0; i < 2; i++){
MTGInPlay * inplay = game->players[i]->game->inPlay;
for (int j= inplay->nb_cards -1 ; j >=0 ; j--){
MTGCardInstance * card = inplay->cards[j];
if (card->owner == player && card->hasType("artifact")){
player->game->putInZone(card, inplay, player->game->hand);
}
}
}
}
break;
}
case 1165: //Hypnotic Specter
{
game->addObserver(NEW AHypnoticSpecter( _id, card));
break;
}
case 1258: //Living Artifact
{
game->addObserver(NEW ALivingArtifact( _id, card, card->target));
break;
}
case 1166: //Lord Of The Pit
{
game->addObserver(NEW ALordOfThePit( _id, card));
break;
}
case 1209: //Mana Short
{
Player * player = spell->getNextPlayerTarget();
if (player){
MTGInPlay * inplay = player->game->inPlay;
for (int i = 0; i < inplay->nb_cards; i++){
MTGCardInstance * current = inplay->cards[i];
if (current->hasType("land")) current->tapped = 1;
}
player->getManaPool()->init();
}
break;
}
case 1167: //Mind Twist
{
int xCost = spell->cost->getConvertedCost() - 1;
for (int i = 0; i < xCost; i++){
game->opponent()->game->discardRandom(game->opponent()->game->hand);
}
break;
}
case 1170: //Nightmare
{
game->addObserver(NEW ANightmare(_id, card));
break;
}
case 1171: //Paralysis
{
int cost[] = {MTG_COLOR_ARTIFACT, 4};
game->addObserver(NEW AUntapManaBlocker(_id, card,card->target, NEW ManaCost(cost,1)));
card->target->tapped = 1;
break;
}
case 1172: //Pestilence
{
game->addObserver(NEW APestilence(_id, card));
break;
}
/*case 1173: //Plague Rats
{
game->addObserver(NEW APlagueRats(_id, card, "Plague Rats"));
break;
}
*/
case 1174: //Raise Dead
{
MTGPlayerCards * zones = game->currentlyActing()->game;
zones->putInZone(card->target,zones->graveyard,zones->hand);
}
case 1176: //Sacrifice
{
ASacrifice * ability = NEW ASacrifice(_id, card, card->target);
game->addObserver(ability);
break;
}
case 1224: //Spell Blast
{
int x = spell->cost->getConvertedCost() - 1;
Spell * starget = spell->getNextSpellTarget();
if (starget){
if (starget->cost->getConvertedCost() <= x) game->mLayers->stackLayer()->Fizzle(starget);
}
break;
}
case 1185: //Warp Artifact
{
game->addObserver(NEW ARegularLifeModifierAura(_id, card, card->target, MTG_PHASE_UPKEEP, -1));
break;
}
case 1192: //BrainGeyser
{
Player * player = ((Player * )spell->targets[0]);
int x = spell->cost->getConvertedCost() - 2;
for (int i = 0; i < x ; i++){
player->game->drawFromLibrary();
}
break;
}
case 1194: //Control Magic
{
game->addObserver(NEW ATakeControlAura(_id, card, card->target));
break;
}
case 1200 : //Feedback
{
game->addObserver(NEW AWanderlust(_id, card, card->target));
break;
}
case 129601: //Icy Manipulator
{
int cost[] = {MTG_COLOR_ARTIFACT, 1};
TypeTargetChooser * tc = new TypeTargetChooser("artifact",card);
tc->addType("land");
tc->addType("creature");
game->addObserver(NEW ATapper(_id,card,NEW ManaCost(cost, 1),tc));
break;
}
case 1203: //Island Fish
{
int cost[] = {MTG_COLOR_BLUE, 3};
game->addObserver(NEW AUntapManaBlocker(_id, card, NEW ManaCost(cost,1)));
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island"));
break;
}
case 1214: //Pirate Ship
{
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island"));
game->addObserver(NEW ADamager(_id+1, card, NEW ManaCost(), 1));
break;
}
case 1218: //Psychic Venom
{
game->addObserver(NEW APsychicVenom(_id, card, card->target));
break;
}
case 1220: //Sea Serpent
{
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island"));
break;
}
case 1315: //Sedge Troll
{
game->addObserver( NEW ASedgeTroll(_id, card));
break;
}
case 1221: //Serendib Efreet
{
game->addObserver( NEW ASerendibEfreet(_id, card));
break;
}
case 1226: //Steal Artifact
{
game->addObserver( NEW AControlStealAura(_id, card, card->target));
break;
}
case 1228: //Unstable mutation
{
game->addObserver(NEW APowerToughnessModifier(_id, card, card->target, 3, 3));
game->addObserver(NEW APowerToughnessModifierRegularCounter(_id, card, card->target, MTG_PHASE_UPKEEP, -1, -1));
break;
}
case 1229: //Unsummon
{
MTGPlayerCards * zones = card->target->controller()->game;
zones->putInZone(card->target,zones->inPlay,zones->hand);
break;
}
case 1235: //Aspect of Wolf
{
game->addObserver(NEW AAspectOfWolf(_id, card, card->target));
break;
}
case 1236: //Birds of Paradise
{
for (int i = MTG_COLOR_GREEN; i <= MTG_COLOR_WHITE; i++){
int output[]={i,1};
game->addObserver(NEW AManaProducer(_id + i, card, NEW ManaCost(output,1)));
}
break;
}
case 1240: //Crumble
{
card->target->controller()->game->putInGraveyard(card->target);
card->target->controller()->life+= card->target->getManaCost()->getConvertedCost();
break;
}
case 1251: //Hurricane
{
int x = spell->cost->getConvertedCost() - 1;
for (int i = 0; i < 2 ; i++){
game->mLayers->stackLayer()->addDamage(card, game->players[i], x);
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (current->basicAbilities[FLYING] && current->isACreature()){
game->mLayers->stackLayer()->addDamage(card, current, x);
}
}
}
break;
}
case 1262: //Regeneration
{
int cost[] = {MTG_COLOR_GREEN, 1};
game->addObserver(NEW AStandardRegenerate(_id,card,card->target,NEW ManaCost(cost,1)));
break;
}
case 1263: //Regrowth
{
MTGPlayerCards * zones = game->currentlyActing()->game;
zones->putInZone(card->target,zones->graveyard,zones->hand);
break;
}
case 1266: //stream of life
{
int x = spell->cost->getConvertedCost() - 1; //TODO Improve that !
spell->getNextPlayerTarget()->life += x;
break;
}
case 1270: //tranquility
{
destroyAllFromTypeInPlay("enchantment", card);
break;
}
case 1271: //Tsunami
{
destroyAllFromTypeInPlay("island", card);
break;
}
case 1231: //Volcanic Eruption
{
int x = spell->cost->getConvertedCost() - 3;
int _x = x;
MTGCardInstance * target = spell->getNextCardTarget();
while(target && _x){
game->mLayers->stackLayer()->addPutInGraveyard(target);
_x--;
target = spell->getNextCardTarget(target);
}
x-=_x;
for (int i = 0; i < 2 ; i++){
game->mLayers->stackLayer()->addDamage(card, game->players[i], x);
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (current->isACreature()){
game->mLayers->stackLayer()->addDamage(card, current, x);
}
}
}
break;
}
case 1278: //Web
{
game->addObserver(NEW APowerToughnessModifier(_id, card, card->target, 0,2));
game->addObserver(NEW ABasicAbilityModifier(_id + 1, card, card->target, REACH));
break;
}
case 1280: //Atog
{
game->addObserver(NEW AAtog(_id, card));
break;
}
case 1285: //Dwarven Warriors{
{
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
tc->maxpower = 2;
game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, UNBLOCKABLE, NULL,tc));
break;
}
case 1288: //EarthBind
{
game->addObserver(NEW AEarthbind(_id, card, card->target));
break;
}
case 1289: //earthquake
{
int x = spell->cost->getConvertedCost() - 1;
for (int i = 0; i < 2 ; i++){
game->mLayers->stackLayer()->addDamage(card, game->players[i], x);
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (!current->basicAbilities[FLYING] && current->isACreature()){
game->mLayers->stackLayer()->addDamage(card, current, x);
}
}
}
break;
}
case 1344: //Eye for an Eye
{
Damage * damage = spell->getNextDamageTarget();
if (damage){
game->mLayers->stackLayer()->addDamage(card,damage->source->controller(),damage->damage);
}
break;
}
case 1243: //Fastbond
{
game->addObserver(NEW AFastbond(_id, card));
break;
}
case 1293: //FlashFires
{
destroyAllFromTypeInPlay("plains", card);
break;
}
case 1301: // Keldon Warlord
{
game->addObserver(NEW AKeldonWarlord(_id, card));
break;
}
case 1302: //Kird Ape
{
game->addObserver(NEW AKirdApe(_id, card));
break;
}
case 1309: //Orcish Artillery
{
game->addObserver(NEW AOrcishArtillery(_id, card));
break;
}
case 1310: //Orcish Oriflame
{
game->addObserver(NEW AOrcishOriflame(_id, card));
break;
}
case 1317: //ShatterStorm
{
destroyAllFromTypeInPlay("artifact", card, 1);
break;
}
case 1326: //Wheel of fortune
{
for (int i = 0; i < 2; i++){
MTGLibrary * library = game->players[i]->game->library;
MTGHand * hand = game->players[i]->game->hand;
for (int j = hand->nb_cards-1; j>=0; j--){
game->players[i]->game->putInGraveyard(hand->cards[j]);
}
for(int j = 0; j < 7; j++){
game->players[i]->game->drawFromLibrary();
}
}
break;
}
case 1328: //Armageddon
{
destroyAllFromTypeInPlay("land", card);
break;
}
case 1331: //Black Ward
{
game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_BLACK));
break;
}
case 1333: //Blue Ward
{
game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_BLUE));
break;
}
case 1334: //Castle
{
game->addObserver(NEW ACastle(_id,card));
break;
}
case 1238: //Cockatrice
{
game->addObserver(NEW AOldSchoolDeathtouch(_id,card));
break;
}
case 1341: //Crusade:
{
game->addObserver(NEW ABadMoon(_id,card, MTG_COLOR_WHITE));
break;
}
case 1346: //Green Ward
{
game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_GREEN));
break;
}
case 1352: //Karma
{
game->addObserver(NEW AKarma(_id, card));
break;
}
case 1355: //Northern Paladin
{
game->addObserver(NEW ANorthernPaladin(_id, card));
break;
}
case 1359: //Red Ward
{
game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_RED));
break;
}
case 1360: //Resurrection
{
Player * p = card->controller();
AbilityFactory af;
af.putInPlayFromZone(card->target, p->game->graveyard, p);
break;
}
case 1362: //Reverse polarity
{
ActionStack * as = game->mLayers->stackLayer();
Player * controller = card->controller();
Damage * current = ((Damage *)as->getNext(NULL,ACTION_SPELL, RESOLVED_OK));
while(current){
if (current->target == controller && current->source->hasType("artifact")){
controller->life+= current->damage * 2;
}
current = ((Damage *)as->getNext(current,ACTION_SPELL, RESOLVED_OK));
}
break;
}
case 1225: //Stasis
{
game->addObserver(NEW AStasis(_id, card));
break;
}
case 1367: //Sword to Plowshares
{
card->target->controller()->life+= card->target->power;
card->target->controller()->game->inPlay->removeCard(card->target);
break;
}
case 1182: //Terror
{
if (card->target->hasColor(MTG_COLOR_BLACK) || card->target->hasSubtype("artifact")){
}else{
card->target->controller()->game->putInGraveyard(card->target);
}
break;
}
case 1267: //Thicket Basilic
{
game->addObserver(NEW AOldSchoolDeathtouch(_id,card));
break;
}
case 1227: //Toughtlace
{
if (card->target){
card->target->setColor(MTG_COLOR_BLUE, 1);
}else{
Spell * starget = spell->getNextSpellTarget();
starget->source->setColor(MTG_COLOR_BLUE, 1);
}
break;
}
case 1371: //White Ward
{
game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_WHITE));
break;
}
case 1372: //Wrath of God
{
destroyAllFromTypeInPlay("creature", card); //TODO -> bury !!!
break;
}
//Addons ICE-AGE Cards
case 2631: //Jokulhaups
{
destroyAllFromTypeInPlay("artifact", card);
destroyAllFromTypeInPlay("creature", card);
destroyAllFromTypeInPlay("land", card);
break;
}
case 2650: //Pyroclasm Need to be improved copied from hurricane with does 0 dammage to player and does 2 dammage to each creature
{
int x = 2;
for (int i = 0; i < 2 ; i++){
game->mLayers->stackLayer()->addDamage(card, game->players[i], 0);// To be removed ?
for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (current->isACreature()){
game->mLayers->stackLayer()->addDamage(card, current, x);
}
}
}
break;
}
case 2660: //Word of Blasting
{
card->target->controller()->game->putInGraveyard(card->target);
card->target->controller()->life-= card->target->getManaCost()->getConvertedCost();
break;
}
case 2443: //Dark Banishing
{
if (card->target->hasColor(MTG_COLOR_BLACK)){
}else{
card->target->controller()->game->putInGraveyard(card->target);
}
break;
}
case 2593: //Thoughtleech
{
game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island"));
break;
}
case 2484: //Songs of the Damned
{
int mana = card->controller()->game->graveyard->countByType("creature");
game->currentlyActing()->getManaPool()->add(MTG_COLOR_BLACK, mana);
break;
}
case 2606: //Anarchy
{
destroyAllFromColorInPlay(MTG_COLOR_WHITE, card);
break;
}
case 2474: //Minion of Leshrac
{
game->addObserver(NEW AMinionofLeshrac( _id, card));
break;
}
case 2421: //Shield of the Age
{
game->addObserver(NEW AShieldOfTheAge( _id, card));
break;
}
case 2487: //Spoil of Evil
{
int mana_cr = game->opponent()->game->graveyard->countByType("creature");
int mana_ar = game->opponent()->game->graveyard->countByType("artifact");
int spoil = mana_ar + mana_cr;
game->currentlyActing()->getManaPool()->add(MTG_COLOR_ARTIFACT, spoil);
game->currentlyActing()->life+= spoil;
break;
}
case 2435: //Whalebone Glider
{
int cost[] = {MTG_COLOR_ARTIFACT,2};
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
tc->maxpower = 3;
game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, FLYING, NEW ManaCost(cost,1),tc));
break;
}
case 2393: //Aegis of the Meek work but work also for 0/1 creatures... :D
{
int cost[] = {MTG_COLOR_ARTIFACT,1};
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
tc->maxpower = 1;
tc->maxtoughness =1;
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, 1,2, NEW ManaCost(cost,1),tc));
break;
}
case 2703: // Lost Order of Jarkeld
{
game->addObserver(NEW ALostOrderofJarkeld(_id, card));
break;
}
default:
break;
}
if (card->basicAbilities[LIFELINK]){
ALifeLink * ability = NEW ALifeLink(_id, card);
game->addObserver(ability);
}
for (int i=PROTECTIONGREEN; i <= PROTECTIONWHITE; i++){
if (card->basicAbilities[i]){
game->addObserver(NEW AProtectionFrom(_id, card, card, i - PROTECTIONGREEN + MTG_COLOR_GREEN));
}
}
if (card->basicAbilities[EXALTED]){
game->addObserver(NEW AExalted(_id, card));
}
// Tested works the first r10 did not function because of the mistake in the array of the definition
if (card->basicAbilities[FORESTHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "forest"));
}
if (card->basicAbilities[ISLANDHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island"));
}
if (card->basicAbilities[MOUNTAINHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card,"moutain"));
}
if (card->basicAbilities[SWAMPHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card,"swamp"));
}
if (card->basicAbilities[PLAINSHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains"));
}
//Instants are put in the graveyard automatically if that's not already done
if (!putSourceInGraveyard){
if (card->hasType("instant") || card->hasType("sorcery")){
putSourceInGraveyard = 1;
}
}
if (putSourceInGraveyard == 1){
MTGPlayerCards * zones = card->controller()->game;
zones->putInGraveyard(card);
}
}
MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){
game = GameObserver::GetInstance();
source = card;
target = card;
}
MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){
game = GameObserver::GetInstance();
source = _source;
target = _target;
}
MTGAbility::~MTGAbility(){
}
//returns 1 if this ability needs to be removed from the list of active abilities
int MTGAbility::testDestroy(){
if (!game->isInPlay(source)){
return 1;
}
if (target && !game->isInPlay((MTGCardInstance *)target)){
source->controller()->game->putInGraveyard(source);//TODO put this in a better place ???
return 1;
}
return 0;
}
int MTGAbility::fireAbility(){
game->mLayers->stackLayer()->addAbility(this);
return 1;
}
//
ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _cost, int _playerturnonly,int tap):MTGAbility(id,card), cost(_cost), playerturnonly(_playerturnonly), needsTapping(tap){
}
int ActivatedAbility::isReactingToClick(MTGCardInstance * card){
Player * player = game->currentPlayer;
if (!playerturnonly) player = game->currentlyActing();
if (card == source && (!cost || player->getManaPool()->canAfford(cost)) && source->controller()==player && (!needsTapping || (!source->isTapped() && !source->hasSummoningSickness())) && player==game->currentlyActing())
return 1;
return 0;
}
int ActivatedAbility::reactToClick(MTGCardInstance * card){
if (!isReactingToClick(card)) return 0;
if (needsTapping) source->tapped = 1;
if (cost) game->currentlyActing()->getManaPool()->pay(cost);
fireAbility();
return 1;
}
int ActivatedAbility::reactToTargetClick(Targetable * object){
if (!isReactingToTargetClick(object)) return 0;
if (needsTapping) source->tapped = 1;
if (cost) game->currentlyActing()->getManaPool()->pay(cost);
fireAbility();
return 1;
}
ActivatedAbility::~ActivatedAbility(){
if (cost) delete cost;
}
//
TargetAbility::TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){
tc = _tc;
}
TargetAbility::TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){
tc = NULL;
}
void TargetAbility::Update(float dt){
JGE * mEngine = JGE::GetInstance();
if (waitingForAnswer){
if(mEngine->GetButtonClick(PSP_CTRL_CROSS)){
waitingForAnswer = 0;
}else if(tc->targetsReadyCheck() == TARGET_OK_FULL){
waitingForAnswer = 0;
ActivatedAbility::reactToClick(source);
}
}
}
int TargetAbility::reactToTargetClick(Targetable * object){
if (object->typeAsTarget() == TARGET_CARD) return reactToClick((MTGCardInstance *)object);
if (waitingForAnswer){
tc->toggleTarget(object);
return 1;
}
return 0;
}
int TargetAbility::reactToClick(MTGCardInstance * card){
if (!waitingForAnswer) {
if (isReactingToClick(card)){
waitingForAnswer = 1;
tc->initTargets();
}
}else{
if (card == source){
if (tc->targetsReadyCheck() == TARGET_OK){
waitingForAnswer = 0;
ActivatedAbility::reactToClick(source);
}
}else{
tc->toggleTarget(card);
}
}
return 1;
}
void TargetAbility::Render(){
//TODO
}
//
TriggeredAbility::TriggeredAbility(int id, MTGCardInstance * card, Damageable * _target):MTGAbility(id,card, _target){
}
TriggeredAbility::TriggeredAbility(int id, MTGCardInstance * card):MTGAbility(id,card){
}
void TriggeredAbility::Update(float dt){
if (trigger()) fireAbility();
}
//
InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){
init = 0;
for (int i = 0; i < 2; i++){
if(game->players[i]->game->inPlay->hasCard(source)){
game->players[i]->game->putInGraveyard(source);
}
}
}
void InstantAbility::Update(float dt){
if (!init){
init = resolve();
}
}
InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){
init = 0;
for (int i = 0; i < 2; i++){
if(game->players[i]->game->inPlay->hasCard(source)){
game->players[i]->game->putInGraveyard(source);
}
}
}
//Instant abilities last generally until the end of the turn
int InstantAbility::testDestroy(){
int newPhase = game->getCurrentGamePhase();
if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1;
currentPhase = newPhase;
return 0;
}
void ListMaintainerAbility::Update(float dt){
map<MTGCardInstance *,bool>::iterator it=cards.begin();
while(it != cards.end()){
MTGCardInstance * card = (*it).first;
it++;
int doDelete = 1;
for (int i = 0; i < 2; i++){
Player * p = game->players[i];
MTGGameZone * zones[] = {p->game->inPlay};
for (int k = 0; k < 1; k++){
MTGGameZone * zone = zones[k];
if (zone->hasCard(card)){
doDelete = 0;
break;
}
}
}
if (doDelete || !canBeInList(card)){
#if defined (WIN32) || defined (LINUX)
OutputDebugString("DELETE FRO LISTMAINTAINER\n");
#endif
cards.erase(card);
removed(card);
}
}
for (int i = 0; i < 2; i++){
Player * p = game->players[i];
MTGGameZone * zones[] = {p->game->inPlay};
for (int k = 0; k < 1; k++){
MTGGameZone * zone = zones[k];
for (int j = 0; j < zone->nb_cards; j++){
if (canBeInList(zone->cards[j])){
if(cards.find(zone->cards[j]) == cards.end()){
cards[zone->cards[j]] = true;
added(zone->cards[j]);
}
}
}
}
}
}
//Destroy the spell -> remove all targets
int ListMaintainerAbility::destroy(){
map<MTGCardInstance *,bool>::iterator it;
for ( it=cards.begin() ; it != cards.end(); it++ ){
removed((*it).first);
}
cards.clear();
return 1;
}
/* An attempt to globalize triggered abilities as much as possible */
MTGAbilityBasicFeatures::MTGAbilityBasicFeatures(){
game = GameObserver::GetInstance();
}
MTGAbilityBasicFeatures::MTGAbilityBasicFeatures(MTGCardInstance * _source, Damageable * _target):source(_source),target(_target){
if (!target) target = source;
game = GameObserver::GetInstance();
}
void MTGAbilityBasicFeatures::init(MTGCardInstance * _source, Damageable * _target){
source = source;
target=_target;
if (!target) target = source;
}
TriggerAtPhase::TriggerAtPhase(int _phaseId):Trigger(),phaseId(_phaseId){
currentPhase = game->getCurrentGamePhase();
newPhase = -1;
}
int TriggerAtPhase::trigger(){
int result = 0;
newPhase = game->getCurrentGamePhase();
if (currentPhase != newPhase && newPhase == phaseId){
result = 1;
}
currentPhase = newPhase;
return result;
}
TriggerNextPhase::TriggerNextPhase(int _phaseId):TriggerAtPhase(_phaseId){
destroyActivated = 0;
}
int TriggerNextPhase::testDestroy(){
if (newPhase <= phaseId) destroyActivated = 1;
if ( newPhase > phaseId && destroyActivated){
return 1;
}
return 0;
}
DrawEvent::DrawEvent(Player * _player, int _nbcards):TriggeredEvent(),player(_player),nbcards(_nbcards){
}
int DrawEvent::resolve(){
game->mLayers->stackLayer()->addDraw(player,nbcards);
return nbcards;
}
int DestroyCondition::testDestroy(){
if (!game->isInPlay(source)){
return 1;
}
if (target && !game->isInPlay((MTGCardInstance *)target)){
source->controller()->game->putInGraveyard(source);//TODO put this in a better place ???
return 1;
}
return 0;
}
GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc , Damageable * _target ): TriggeredAbility(id, _source,_target){
if (!target) target = source;
t = _t;
te = _te;
dc = _dc;
t->init(_source,_target);
te->init(_source,_target);
if (dc) dc->init(_source,_target);
}
int GenericTriggeredAbility::trigger(){
return t->trigger();
}
int GenericTriggeredAbility::resolve(){
return te->resolve();
}
int GenericTriggeredAbility::testDestroy(){
if (dc) return dc->testDestroy();
return t->testDestroy();
}
GenericTriggeredAbility::~GenericTriggeredAbility(){
delete t;
delete te;
SAFE_DELETE(dc);
}