- Trying to add generic classes for Triggered abilities. PLEASE DO NOT USE THESE RIGHT NOW, Not Tested AT ALL !
This commit is contained in:
wagic.the.homebrew
2008-11-12 14:38:30 +00:00
parent c97dd1f260
commit a418e10c47
6 changed files with 5003 additions and 5024 deletions
-1
View File
@@ -29,7 +29,6 @@ class ActionElement: public JGuiObject{
int newPhase; int newPhase;
int modal; int modal;
int waitingForAnswer; int waitingForAnswer;
void RenderMessageBackground(float y0, int height);
int getActivity(); int getActivity();
virtual void Update(float dt){}; virtual void Update(float dt){};
virtual void Render(){}; virtual void Render(){};
File diff suppressed because it is too large Load Diff
+88 -13
View File
@@ -20,18 +20,12 @@ using std::string;
using std::map; using std::map;
//Two stupid variables used to give a hint to the AI:
// Should I cast a spell on an ennemy or friendly unit ?
#define BAKA_EFFECT_GOOD 10 #define BAKA_EFFECT_GOOD 10
#define BAKA_EFFECT_BAD 11 #define BAKA_EFFECT_BAD 11
class AbilityFactory{
private:
int destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury = 0);
int destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury = 0);
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
public:
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
void addAbilities(int _id, Spell * spell);
};
class MTGAbility: public ActionElement{ class MTGAbility: public ActionElement{
protected: protected:
@@ -67,7 +61,7 @@ class TriggeredAbility:public MTGAbility{
class ActivatedAbility:public MTGAbility{ class ActivatedAbility:public MTGAbility{
public: public:
ManaCost * cost; ManaCost * cost;
int playerturnonly; int playerturnonly;
int needsTapping; int needsTapping;
@@ -80,7 +74,7 @@ class ActivatedAbility:public MTGAbility{
}; };
class TargetAbility:public ActivatedAbility{ class TargetAbility:public ActivatedAbility{
public: public:
TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
virtual void Update(float dt); virtual void Update(float dt);
@@ -90,7 +84,7 @@ class TargetAbility:public ActivatedAbility{
}; };
class InstantAbility:public MTGAbility{ class InstantAbility:public MTGAbility{
public: public:
int init; int init;
virtual void Update(float dt); virtual void Update(float dt);
virtual int testDestroy(); virtual int testDestroy();
@@ -101,7 +95,7 @@ class InstantAbility:public MTGAbility{
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */ /* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
class ListMaintainerAbility:public MTGAbility{ class ListMaintainerAbility:public MTGAbility{
public: public:
map<MTGCardInstance *,bool> cards; map<MTGCardInstance *,bool> cards;
ListMaintainerAbility(int _id):MTGAbility(_id,NULL){}; ListMaintainerAbility(int _id):MTGAbility(_id,NULL){};
ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){}; ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){};
@@ -113,6 +107,87 @@ class ListMaintainerAbility:public MTGAbility{
virtual int destroy(); virtual int destroy();
}; };
/* An attempt to globalize triggered abilities as much as possible */
class MTGAbilityBasicFeatures{
public:
Damageable * target;
GameObserver * game;
MTGCardInstance * source;
MTGAbilityBasicFeatures();
MTGAbilityBasicFeatures(MTGCardInstance * _source, Damageable * _target = NULL);
void init(MTGCardInstance * _source, Damageable * _target = NULL);
};
class Trigger:public MTGAbilityBasicFeatures{
public:
virtual int trigger()=0;
virtual int testDestroy(){return 0;};
};
class TriggerAtPhase:public Trigger{
public:
int currentPhase, newPhase;
int phaseId;
TriggerAtPhase(int _phaseId);
virtual int trigger();
};
class TriggerNextPhase:public TriggerAtPhase{
public:
int destroyActivated;
TriggerNextPhase(int _phaseId);
virtual int testDestroy();
};
class TriggeredEvent:public MTGAbilityBasicFeatures{
public:
virtual int resolve()=0;
};
class DrawEvent:public TriggeredEvent{
public:
Player * player;
int nbcards;
DrawEvent(Player * _player, int _nbcards);
int resolve();
};
class DestroyCondition:public MTGAbilityBasicFeatures{
public:
virtual int testDestroy();
};
class GenericTriggeredAbility:public TriggeredAbility{
public:
Trigger * t;
TriggeredEvent * te;
DestroyCondition * dc;
GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc = NULL, Damageable * _target = NULL);
virtual int trigger();
virtual int resolve();
virtual int testDestroy();
~GenericTriggeredAbility();
};
/* Ability Factory */
class AbilityFactory{
private:
int destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury = 0);
int destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury = 0);
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
Trigger * parseTrigger(string magicText);
public:
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
void addAbilities(int _id, Spell * spell);
};
#include "MTGCardInstance.h" #include "MTGCardInstance.h"
#endif #endif
+57 -43
View File
@@ -93,50 +93,46 @@ static int _b[7] = {20, 0, 140,15, 50,255,128};
#define MOUNTAINHOME 33 #define MOUNTAINHOME 33
#define SWAMPHOME 34 #define SWAMPHOME 34
#define PLAINSHOME 35 #define PLAINSHOME 35
#define FLANKING 36
#define RAMPAGE1 37
#define NB_BASIC_ABILITIES 38 #define NB_BASIC_ABILITIES 36
static const char * MTGBasicAbilities[] = { static const char * MTGBasicAbilities[] = {
"trample", "trample",
"forestwalk", "forestwalk",
"islandwalk", "islandwalk",
"mountainwalk", "mountainwalk",
"swampwalk", "swampwalk",
"plainwalk", "plainwalk",
"flying", "flying",
"first strike", "first strike",
"double strike", "double strike",
"fear", "fear",
"flash", "flash",
"haste", "haste",
"lifelink", "lifelink",
"reach", "reach",
"shroud", "shroud",
"vigilance", "vigilance",
"defender", "defender",
"banding", "banding",
"protection from green", "protection from green",
"protection from blue", "protection from blue",
"protection from red", "protection from red",
"protection from black", "protection from black",
"protection from white", "protection from white",
"unblockable", "unblockable",
"wither", "wither",
"persist", "persist",
"retrace", "retrace",
"exalted", "exalted",
"legendary", "legendary",
"shadow", "shadow",
"reachshadow", "reachshadow",
"foresthome", "foresthome",
"islandhome", "islandhome",
"moutainhome", "moutainhome",
"swamphome", "swamphome",
"plainshome", "plainshome"
"flanking",
"rampage",
}; };
@@ -152,7 +148,7 @@ static const char * MTGBasicAbilities[] = {
static const char *MTGPhaseNames[] = static const char *MTGPhaseNames[] =
{ {
"---", "---",
"Untap", "Untap",
"Upkeep", "Upkeep",
@@ -167,7 +163,25 @@ static const char *MTGPhaseNames[] =
"End of turn", "End of turn",
"cleanup", "cleanup",
"---" "---"
}; };
static const char *MTGPhaseCodeNames[] =
{
"beginofturn",
"untap",
"upkeep",
"draw",
"firstmain",
"combatbegins",
"attackers",
"blockers",
"combatdamage",
"combatends",
"secondmain",
"endofturn",
"cleanup",
"beforenextturn"
};
-25
View File
@@ -12,31 +12,6 @@ ActionElement::ActionElement(int id):JGuiObject(id){
tc = NULL; tc = NULL;
} }
/*
void ActionElement::RenderMessageBackground(float y0, int _height){
float height = _height;
PIXEL_TYPE colors_up[] =
{
ARGB(0,255,255,255),
ARGB(0,255,255,255),
ARGB(128,255,255,255),
ARGB(128,255,255,255)
};
PIXEL_TYPE colors_down[] =
{
ARGB(128,255,255,255),
ARGB(128,255,255,255),
ARGB(0,255,255,255),
ARGB(0,255,255,255)
};
JRenderer * renderer = JRenderer::GetInstance();
renderer->FillRect(0,y0,SCREEN_WIDTH,height/2,colors_up);
renderer->FillRect(0,y0+height/2,SCREEN_WIDTH,height/2,colors_down);
// mEngine->DrawLine(0,y0,SCREEN_WIDTH,y0,ARGB(128,255,255,255));
// mEngine->DrawLine(0,y0+height,SCREEN_WIDTH,y0+height,ARGB(128,255,255,255));
}*/
int ActionElement::getActivity(){ int ActionElement::getActivity(){
+155 -115
View File
@@ -50,7 +50,26 @@ int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone
return 1; return 1;
} }
//Some basic functionnalities that can be added automatically in the text file
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 AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
int dryMode = 0; int dryMode = 0;
if (!spell) dryMode = 1; if (!spell) dryMode = 1;
@@ -60,7 +79,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
if (!target) target = card; if (!target) target = card;
string magicText = card->magicText; string magicText = card->magicText;
if (card->alias && magicText.size() == 0){ if (card->alias && magicText.size() == 0){
//An awful way to gat access to the aliasedcard //An awful way to get access to the aliasedcard
magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText; magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText;
} }
string s; string s;
@@ -89,6 +108,13 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
int doTap = 0; int doTap = 0;
string lordType = ""; 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 ? //Tap in the cost ?
if (s.find("{t}") != string::npos) doTap = 1; if (s.find("{t}") != string::npos) doTap = 1;
@@ -154,17 +180,6 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
result++; result++;
continue; continue;
} }
//Tentative Destroyall not working char is not compatible with string variable
//found = s.find("destroyall(");
//if (found != string::npos){
// if (dryMode) return BAKA_EFFECT_GOOD;
// unsigned int end = s.find(")", found+11);
// if (end != string::npos){
// string type = s.substr(found+11,end-found-11).c_str();
// destroyAllFromTypeInPlay(type.c_str(), card);
// result++;
// continue;
//}
//Regeneration //Regeneration
found = s.find("}:regenerate"); found = s.find("}:regenerate");
@@ -211,10 +226,6 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
continue; continue;
} }
//Summon
//Reveal Take Target and put in in hand (should be also able to target hand since some card needs you to reveal a card in your hand
//Damage //Damage
found = s.find("damage"); found = s.find("damage");
if (found != string::npos){ if (found != string::npos){
@@ -266,7 +277,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
} }
//Draw //Draw
found = s.find("draw"); found = s.find("draw:");
if (found != string::npos){ if (found != string::npos){
unsigned int start = s.find(":",found); unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start); unsigned int end = s.find(" ",start);
@@ -278,6 +289,10 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
nbcards = atoi(s.substr(start+1).c_str()); nbcards = atoi(s.substr(start+1).c_str());
} }
if (dryMode) return BAKA_EFFECT_GOOD; 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){ if (tc){
//TODO ? //TODO ?
}else{ }else{
@@ -288,6 +303,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap)); game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
} }
} }
}
result++; result++;
continue; continue;
} }
@@ -450,7 +466,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
case 106525: //Ascendant Evincar case 106525: //Ascendant Evincar
{ {
game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1)); game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1));
game->addObserver(NEW AColorLord(_id, card,0,MTG_COLOR_BLACK,-1,-1)); game->addObserver(NEW AColorLord(_id + 1, card,0,MTG_COLOR_BLACK,-1,-1));
break; break;
} }
@@ -975,6 +991,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
MTGPlayerCards * zones = card->target->controller()->game; MTGPlayerCards * zones = card->target->controller()->game;
zones->putInZone(card->target,zones->inPlay,zones->hand); zones->putInZone(card->target,zones->inPlay,zones->hand);
break; break;
} }
case 1235: //Aspect of Wolf case 1235: //Aspect of Wolf
{ {
@@ -1270,78 +1287,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
break; break;
} }
//Addons ICE-AGE Cards
// Addons ALA
case 175114: // Master of Etherium
{
game->addObserver(NEW ACreaturePowerToughnessModifierForAllTypeControlled(_id,card,"artifact"));
break;
}
case 174989: // Wild Nacatl
{
game->addObserver(NEW AGenericKirdApe(_id,card,"plains",1,1));
game->addObserver(NEW AGenericKirdApe(_id,card,"moutain",1,1));
break;
}
//Addons The Dark
case 1797: //Inferno does 6 damage to all players and all creatures.
{
for (int i = 0; i < 2 ; i++){
game->mLayers->stackLayer()->addDamage(card, game->players[i], 6);
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, 6);
}
}
}
break;
}
case 1773 : //People of the Woods
{
game->addObserver(NEW APeopleOfTheWoods(_id, card));
break;
}
case 1818: //Tivadar's Crusade
{
destroyAllFromTypeInPlay("goblin", card);
break;
}
//Addons Legends
case 1470: //Acid Rain
{
destroyAllFromTypeInPlay("forest", card);
break;
}
case 1427: //Abomination
{
game->addObserver(NEW AAbomination(_id,card));
break;
}
case 1533: //Livingplane
{
game->addObserver(NEW AConvertLandToCreatures(id, card, "land"));
break;
}
case 1607: //Divine Offering
{
card->target->controller()->game->putInGraveyard(card->target);
game->currentlyActing()->life+= card->target->getManaCost()->getConvertedCost();
break;
}
case 1625: //Lifeblood
{
game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island"));
break;
}
//Addons ICE-AGE Cards
case 2631: //Jokulhaups case 2631: //Jokulhaups
{ {
destroyAllFromTypeInPlay("artifact", card); destroyAllFromTypeInPlay("artifact", card);
@@ -1470,12 +1416,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
if (card->basicAbilities[PLAINSHOME]){ if (card->basicAbilities[PLAINSHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains")); game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains"));
} }
// New Abilities Flanking and Rampage
if (card->basicAbilities [RAMPAGE1]){
game->addObserver (NEW ARampageAbility(_id, card, 1, 1));
}
//Instants are put in the graveyard automatically if that's not already done //Instants are put in the graveyard automatically if that's not already done
if (!putSourceInGraveyard){ if (!putSourceInGraveyard){
if (card->hasType("instant") || card->hasType("sorcery")){ if (card->hasType("instant") || card->hasType("sorcery")){
@@ -1489,13 +1429,13 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
} }
MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){ MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){
game = GameObserver::GetInstance();; game = GameObserver::GetInstance();
source = card; source = card;
target = card; target = card;
} }
MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){ MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){
game = GameObserver::GetInstance();; game = GameObserver::GetInstance();
source = _source; source = _source;
target = _target; target = _target;
} }
@@ -1632,44 +1572,44 @@ void TriggeredAbility::Update(float dt){
// //
InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){ InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){
init = 0; init = 0;
for (int i = 0; i < 2; i++){ for (int i = 0; i < 2; i++){
if(game->players[i]->game->inPlay->hasCard(source)){ if(game->players[i]->game->inPlay->hasCard(source)){
game->players[i]->game->putInGraveyard(source); game->players[i]->game->putInGraveyard(source);
} }
} }
} }
void InstantAbility::Update(float dt){ void InstantAbility::Update(float dt){
if (!init){ if (!init){
init = resolve(); init = resolve();
} }
} }
InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){ InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){
init = 0; init = 0;
for (int i = 0; i < 2; i++){ for (int i = 0; i < 2; i++){
if(game->players[i]->game->inPlay->hasCard(source)){ if(game->players[i]->game->inPlay->hasCard(source)){
game->players[i]->game->putInGraveyard(source); game->players[i]->game->putInGraveyard(source);
} }
} }
} }
//Instant abilities last generally until the end of the turn //Instant abilities last generally until the end of the turn
int InstantAbility::testDestroy(){ int InstantAbility::testDestroy(){
int newPhase = game->getCurrentGamePhase(); int newPhase = game->getCurrentGamePhase();
if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1; if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1;
currentPhase = newPhase; currentPhase = newPhase;
return 0; return 0;
} }
void ListMaintainerAbility::Update(float dt){ void ListMaintainerAbility::Update(float dt){
map<MTGCardInstance *,bool>::iterator it=cards.begin(); map<MTGCardInstance *,bool>::iterator it=cards.begin();
while(it != cards.end()){ while(it != cards.end()){
MTGCardInstance * card = (*it).first; MTGCardInstance * card = (*it).first;
@@ -1688,7 +1628,7 @@ void ListMaintainerAbility::Update(float dt){
} }
if (doDelete || !canBeInList(card)){ if (doDelete || !canBeInList(card)){
#if defined (WIN32) || defined (LINUX) #if defined (WIN32) || defined (LINUX)
OutputDebugString("DELETE FRO LISTMAINTAINER\n"); OutputDebugString("DELETE FRO LISTMAINTAINER\n");
#endif #endif
cards.erase(card); cards.erase(card);
removed(card); removed(card);
@@ -1709,10 +1649,10 @@ void ListMaintainerAbility::Update(float dt){
} }
} }
} }
} }
//Destroy the spell -> remove all targets //Destroy the spell -> remove all targets
int ListMaintainerAbility::destroy(){ int ListMaintainerAbility::destroy(){
map<MTGCardInstance *,bool>::iterator it; map<MTGCardInstance *,bool>::iterator it;
for ( it=cards.begin() ; it != cards.end(); it++ ){ for ( it=cards.begin() ; it != cards.end(); it++ ){
@@ -1720,4 +1660,104 @@ int ListMaintainerAbility::destroy(){
} }
cards.clear(); cards.clear();
return 1; 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);
}