massive update, additions and changelog in first comment.
This commit is contained in:
@@ -60,6 +60,11 @@ public:
|
||||
intValue = target->equipment;
|
||||
}else if (s == "manacost"){
|
||||
intValue = target->getManaCost()->getConvertedCost();
|
||||
}else if (s == "sunburst"){
|
||||
intValue = 0;
|
||||
if(card && card->previous && card->previous->previous){
|
||||
intValue = card->previous->previous->sunburst;
|
||||
}
|
||||
}else if (s == "lifetotal"){
|
||||
intValue = target->controller()->life;
|
||||
}else if (s == "odcount"){
|
||||
@@ -188,11 +193,240 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardTappedformana:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
bool tap;
|
||||
TrCardTappedformana(int id, MTGCardInstance * source, TargetChooser * tc, bool tap = true):TriggeredAbility(id,source), tc(tc),tap(tap){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardTappedForMana * e = dynamic_cast<WEventCardTappedForMana *>(event);
|
||||
if (!e) return 0;
|
||||
if (e->before == e->after) return 0;
|
||||
if (e->after != tap) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrCardTappedformana(){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
|
||||
TrCardTappedformana * clone() const{
|
||||
TrCardTappedformana * a = NEW TrCardTappedformana(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardAttackedNotBlocked:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TrCardAttackedNotBlocked(int id, MTGCardInstance * source, TargetChooser * tc):TriggeredAbility(id,source), tc(tc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardAttackedNotBlocked * e = dynamic_cast<WEventCardAttackedNotBlocked *>(event);
|
||||
if (!e) return 0;
|
||||
if(e->card->didattacked < 1) return 0;
|
||||
if(e->card->blocked) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrCardAttackedNotBlocked(){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
|
||||
TrCardAttackedNotBlocked * clone() const{
|
||||
TrCardAttackedNotBlocked * a = NEW TrCardAttackedNotBlocked(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardAttackedBlocked:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TargetChooser * fromTc;
|
||||
TrCardAttackedBlocked(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL ):TriggeredAbility(id,source), tc(tc), fromTc(fromTc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardAttackedBlocked * e = dynamic_cast<WEventCardAttackedBlocked *>(event);
|
||||
if (!e) return 0;
|
||||
if(e->card->didattacked < 1) return 0;
|
||||
if(!e->card->blocked) return 0;
|
||||
if (fromTc && !fromTc->canTarget(e->card->getNextOpponent())) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrCardAttackedBlocked(){
|
||||
SAFE_DELETE(tc);
|
||||
SAFE_DELETE(fromTc);
|
||||
}
|
||||
|
||||
TrCardAttackedBlocked * clone() const{
|
||||
TrCardAttackedBlocked * a = NEW TrCardAttackedBlocked(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardAttacked:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TrCardAttacked(int id, MTGCardInstance * source, TargetChooser * tc):TriggeredAbility(id,source), tc(tc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardAttacked * e = dynamic_cast<WEventCardAttacked *>(event);
|
||||
if (!e) return 0;
|
||||
if(e->card->didattacked < 1) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrCardAttacked(){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
|
||||
TrCardAttacked * clone() const{
|
||||
TrCardAttacked * a = NEW TrCardAttacked(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardBlocked:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TargetChooser * fromTc;
|
||||
TrCardBlocked(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL):TriggeredAbility(id,source), tc(tc), fromTc(fromTc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardBlocked * e = dynamic_cast<WEventCardBlocked *>(event);
|
||||
if (!e) return 0;
|
||||
//if(e->card->didblocked < 1) return 0;
|
||||
if (fromTc && !fromTc->canTarget(e->card->getNextOpponent())) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrCardBlocked(){
|
||||
SAFE_DELETE(tc);
|
||||
SAFE_DELETE(fromTc);
|
||||
}
|
||||
|
||||
TrCardBlocked * clone() const{
|
||||
TrCardBlocked * a = NEW TrCardBlocked(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrcardDrawn:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TrcardDrawn(int id, MTGCardInstance * source, TargetChooser * tc):TriggeredAbility(id,source), tc(tc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventcardDraw * e = dynamic_cast<WEventcardDraw *>(event);
|
||||
if (!e) return 0;
|
||||
if (!tc->canTarget(e->player))return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrcardDrawn(){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
|
||||
TrcardDrawn * clone() const{
|
||||
TrcardDrawn * a = NEW TrcardDrawn(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardSacrificed:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TrCardSacrificed(int id, MTGCardInstance * source, TargetChooser * tc):TriggeredAbility(id,source), tc(tc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardSacrifice * e = dynamic_cast<WEventCardSacrifice *>(event);
|
||||
if (!e) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
~TrCardSacrificed(){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
|
||||
TrCardSacrificed * clone() const{
|
||||
TrCardSacrificed * a = NEW TrCardSacrificed(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrCardDiscarded:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TrCardDiscarded(int id, MTGCardInstance * source, TargetChooser * tc):TriggeredAbility(id,source), tc(tc){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
}
|
||||
int triggerOnEvent(WEvent * event){
|
||||
WEventCardDiscard * e = dynamic_cast<WEventCardDiscard *>(event);
|
||||
if (!e) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
return 1;
|
||||
}
|
||||
~TrCardDiscarded(){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
TrCardDiscarded * clone() const{
|
||||
TrCardDiscarded * a = NEW TrCardDiscarded(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class TrDamaged:public TriggeredAbility{
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
TargetChooser * fromTc;
|
||||
TrDamaged (int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL):TriggeredAbility(id,source), tc(tc), fromTc(fromTc){}
|
||||
int type;//this allows damagenoncombat and combatdamage to share this trigger
|
||||
TrDamaged (int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL,int type = 0):TriggeredAbility(id,source), tc(tc), fromTc(fromTc), type(type){}
|
||||
|
||||
int resolve(){
|
||||
return 0; //This is a trigger, this function should not be called
|
||||
@@ -203,6 +437,8 @@ public:
|
||||
if (!e) return 0;
|
||||
if(!tc->canTarget(e->damage->target)) return 0;
|
||||
if (fromTc && !fromTc->canTarget(e->damage->source)) return 0;
|
||||
if (type == 1 && e->damage->typeOfDamage != DAMAGE_COMBAT ) return 0;
|
||||
if (type == 2 && e->damage->typeOfDamage == DAMAGE_COMBAT ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -496,6 +732,102 @@ class AACopier:public ActivatedAbility{
|
||||
}
|
||||
};
|
||||
|
||||
//cloning...this makes a token thats a copy of the target.
|
||||
class AACloner:public ActivatedAbility{
|
||||
public:
|
||||
int who;
|
||||
string with;
|
||||
list<int>awith;
|
||||
list<int>colors;
|
||||
AACloner(int _id, MTGCardInstance * _source, MTGCardInstance * _target = NULL, ManaCost * _cost=NULL, int who = 0,string with =""):ActivatedAbility(_id,_source,_cost,0,0), who(who){
|
||||
target = _target;
|
||||
source = _source;
|
||||
|
||||
for (int j = 0; j < Constants::NB_BASIC_ABILITIES; j++){
|
||||
size_t found = with.find(Constants::MTGBasicAbilities[j]);
|
||||
if (found != string::npos){
|
||||
awith.push_back(j);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < Constants::MTG_NB_COLORS; j++){
|
||||
size_t found = with.find(Constants::MTGColorStrings[j]);
|
||||
if (found != string::npos){
|
||||
colors.push_back(j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if(_target && !_target->isToken){
|
||||
MTGCardInstance * myClone;
|
||||
MTGCard * clone = GameApp::collection->getCardById(_target->getId());
|
||||
myClone = NULL;
|
||||
if(who != 1) myClone = NEW MTGCardInstance(clone,source->controller()->game);
|
||||
if(who == 1) myClone = NEW MTGCardInstance(clone,source->controller()->opponent()->game);
|
||||
if(who != 1) source->controller()->game->temp->addCard(myClone);
|
||||
else source->controller()->opponent()->game->temp->addCard(myClone);
|
||||
Spell * spell = NEW Spell(myClone);
|
||||
spell->resolve();
|
||||
spell->source->isToken = 1;
|
||||
spell->source->fresh = 1;
|
||||
list<int>::iterator it;
|
||||
for ( it=awith.begin() ; it != awith.end(); it++ ){
|
||||
spell->source->basicAbilities[*it] = 1;
|
||||
}
|
||||
for ( it=colors.begin() ; it != colors.end(); it++ ){
|
||||
spell->source->setColor(*it);
|
||||
}
|
||||
delete spell;
|
||||
return 1;
|
||||
}
|
||||
if(_target && _target->isToken){
|
||||
MTGCardInstance * myClone;
|
||||
MTGCardInstance * clone = _target;
|
||||
myClone = NULL;
|
||||
if(who != 1) myClone = NEW MTGCardInstance(clone,source->controller()->game);
|
||||
if(who == 1) myClone = NEW MTGCardInstance(clone,source->controller()->opponent()->game);
|
||||
if(who != 1) source->controller()->game->temp->addCard(myClone);
|
||||
else source->controller()->opponent()->game->temp->addCard(myClone);
|
||||
Spell * spell = NEW Spell(myClone);
|
||||
spell->resolve();
|
||||
spell->source->isToken = 1;
|
||||
spell->source->fresh = 1;
|
||||
list<int>::iterator it;
|
||||
for ( it=awith.begin() ; it != awith.end(); it++ ){
|
||||
spell->source->basicAbilities[*it] = 1;
|
||||
}
|
||||
for ( it=colors.begin() ; it != colors.end(); it++ ){
|
||||
spell->source->setColor(*it);
|
||||
}
|
||||
delete spell;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * getMenuText(){
|
||||
if(who == 1) return "Clone For Opponent";
|
||||
return "Clone";
|
||||
}
|
||||
|
||||
virtual ostream& toString(ostream& out) const
|
||||
{
|
||||
out << "AACloner ::: with : ?" // << abilities
|
||||
<< " (";
|
||||
return ActivatedAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
|
||||
AACloner * clone() const{
|
||||
AACloner * a = NEW AACloner(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
~AACloner(){}
|
||||
};
|
||||
|
||||
class AAMover:public ActivatedAbility{
|
||||
public:
|
||||
string destination;
|
||||
@@ -652,6 +984,9 @@ class ACycle:public ActivatedAbility{
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
WEvent * e = NEW WEventCardDiscard(source);
|
||||
GameObserver * game = GameObserver::GetInstance();
|
||||
game->receiveEvent(e);
|
||||
source->controller()->game->putInGraveyard(source);
|
||||
source->controller()->game->drawFromLibrary();
|
||||
return 1;
|
||||
@@ -670,6 +1005,37 @@ class ACycle:public ActivatedAbility{
|
||||
|
||||
};
|
||||
|
||||
//ninjutsu
|
||||
|
||||
class ANinja:public ActivatedAbility{
|
||||
public:
|
||||
ANinja(int _id, MTGCardInstance * card,Targetable * _target):ActivatedAbility(_id, card){
|
||||
target = _target;
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
MTGCardInstance * copy = source->controller()->game->putInZone(source, source->controller()->game->hand, source->controller()->game->temp);
|
||||
Spell * spell = NEW Spell(copy);
|
||||
spell->resolve();
|
||||
MTGCardInstance * newcard = spell->source;
|
||||
newcard->summoningSickness = 0;
|
||||
newcard->tap();
|
||||
newcard->setAttacker(1);
|
||||
delete spell;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char * getMenuText(){
|
||||
return "Ninjutsu";
|
||||
}
|
||||
|
||||
ANinja * clone() const{
|
||||
ANinja * a = NEW ANinja(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Drawer, allows to draw a card for a cost:
|
||||
|
||||
@@ -845,16 +1211,18 @@ public:
|
||||
int tokenId;
|
||||
string name;
|
||||
WParsedInt * multiplier;
|
||||
ATokenCreator(int _id,MTGCardInstance * _source,ManaCost * _cost, int tokenId, int _doTap, WParsedInt * multiplier = NULL):ActivatedAbility(_id,_source,_cost,0,_doTap), tokenId(tokenId), multiplier(multiplier){
|
||||
int who;
|
||||
ATokenCreator(int _id,MTGCardInstance * _source,ManaCost * _cost, int tokenId, int _doTap, WParsedInt * multiplier = NULL,int who = 0):ActivatedAbility(_id,_source,_cost,0,_doTap), tokenId(tokenId), multiplier(multiplier), who(who){
|
||||
if(!multiplier) this->multiplier = NEW WParsedInt(1);
|
||||
MTGCard * card = GameApp::collection->getCardById(tokenId);
|
||||
if (card) name = card->data->getName();
|
||||
}
|
||||
|
||||
ATokenCreator(int _id,MTGCardInstance * _source,ManaCost * _cost, string sname, string stypes,int _power,int _toughness, string sabilities, int _doTap, WParsedInt * multiplier = NULL):ActivatedAbility(_id,_source,_cost,0,_doTap), multiplier(multiplier){
|
||||
ATokenCreator(int _id,MTGCardInstance * _source,ManaCost * _cost, string sname, string stypes,int _power,int _toughness, string sabilities, int _doTap, WParsedInt * multiplier = NULL,int who = 0):ActivatedAbility(_id,_source,_cost,0,_doTap), multiplier(multiplier),who(who){
|
||||
power = _power;
|
||||
toughness = _toughness;
|
||||
name = sname;
|
||||
who = who;
|
||||
tokenId = 0;
|
||||
if(!multiplier) this->multiplier = NEW WParsedInt(1);
|
||||
//TODO this is a copy/past of other code that's all around the place, everything should be in a dedicated parser class;
|
||||
@@ -864,7 +1232,7 @@ public:
|
||||
if (found != string::npos){
|
||||
abilities.push_back(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < Constants::MTG_NB_COLORS; j++){
|
||||
size_t found = sabilities.find(Constants::MTGColorStrings[j]);
|
||||
@@ -885,8 +1253,8 @@ public:
|
||||
types.push_back(id);
|
||||
s = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
for (int i = 0; i < multiplier->getValue(); ++i){
|
||||
@@ -907,11 +1275,22 @@ public:
|
||||
myToken->basicAbilities[*it] = 1;
|
||||
}
|
||||
}
|
||||
if(who == 0 || who != 1){
|
||||
source->controller()->game->temp->addCard(myToken);
|
||||
Spell * spell = NEW Spell(myToken);
|
||||
spell->resolve();
|
||||
spell->source->isToken = 1;
|
||||
spell->source->fresh = 1;
|
||||
delete spell;
|
||||
}else if (who == 1){
|
||||
source->controller()->opponent()->game->temp->addCard(myToken);
|
||||
Spell * spell = NEW Spell(myToken);
|
||||
spell->resolve();
|
||||
spell->source->owner = spell->source->controller();
|
||||
spell->source->isToken = 1;
|
||||
spell->source->fresh = 1;
|
||||
delete spell;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -929,6 +1308,7 @@ public:
|
||||
<< " ; power : " << power
|
||||
<< " ; toughness : " << toughness
|
||||
<< " ; name : " << name
|
||||
<< " ; who : " << who
|
||||
<< " (";
|
||||
return ActivatedAbility::toString(out) << ")";
|
||||
}
|
||||
@@ -1007,7 +1387,47 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class AASacDis:public ActivatedAbility{
|
||||
public:
|
||||
int sacrifice;
|
||||
AASacDis(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _sacrifice = 0, ManaCost * _cost=NULL):ActivatedAbility(_id,_source,_cost),sacrifice(_sacrifice){
|
||||
if (_target) target = _target;
|
||||
}
|
||||
int resolve(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
|
||||
if(_target){
|
||||
Player * p = _target->controller();
|
||||
Player * owner = _target->owner;
|
||||
if (sacrifice)
|
||||
{
|
||||
WEvent * e = NEW WEventCardSacrifice(_target);
|
||||
GameObserver * game = GameObserver::GetInstance();
|
||||
game->receiveEvent(e);
|
||||
p->game->putInGraveyard(_target);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
WEvent * e = NEW WEventCardDiscard(_target);
|
||||
GameObserver * game = GameObserver::GetInstance();
|
||||
game->receiveEvent(e);
|
||||
p->game->putInGraveyard(_target);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
const char * getMenuText(){
|
||||
if(sacrifice) return "Sacrifice";
|
||||
else return "Discard";
|
||||
}
|
||||
AASacDis * clone() const{
|
||||
AASacDis * a = NEW AASacDis(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
/*Changes one of the basic abilities of target
|
||||
source : spell
|
||||
@@ -2075,6 +2495,8 @@ public:
|
||||
a = NULL;
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
|
||||
|
||||
int removeFromGame(){
|
||||
return removeAbilityFromGame();
|
||||
}
|
||||
@@ -2093,8 +2515,8 @@ public:
|
||||
match = td->match(source);
|
||||
if (match > 0){
|
||||
addAbilityToGame();
|
||||
}else{
|
||||
removeAbilityFromGame();
|
||||
}else{
|
||||
removeAbilityFromGame();
|
||||
}
|
||||
if (ability->oneShot) a = NULL; //allows to call the effect several times
|
||||
return 1;
|
||||
@@ -2278,6 +2700,7 @@ AADamager(int _id, MTGCardInstance * _source, Targetable * _target, WParsedInt *
|
||||
|
||||
|
||||
};
|
||||
|
||||
//prevent next damage
|
||||
class AADamagePrevent:public ActivatedAbilityTP{
|
||||
public:
|
||||
@@ -2435,6 +2858,56 @@ class AAFrozen:public ActivatedAbility{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
/* switch power and toughness of target */
|
||||
class ATwist:public InstantAbility{
|
||||
public:
|
||||
int oldpower;
|
||||
int oldtoughness;
|
||||
ATwist(int _id, MTGCardInstance * _source, MTGCardInstance * _target): InstantAbility(_id, _source, _target){
|
||||
target = _target;
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if (_target){
|
||||
while (_target->next) _target=_target->next; //This is for cards such as rampant growth
|
||||
oldpower = _target->power;
|
||||
oldtoughness = _target->toughness;
|
||||
|
||||
_target->addToToughness(oldpower);
|
||||
_target->addToToughness(-oldtoughness);
|
||||
_target->power = oldtoughness;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int destroy(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if (_target){
|
||||
while (_target->next) _target=_target->next; //This is for cards such as rampant growth
|
||||
oldpower = _target->power;
|
||||
oldtoughness = _target->toughness;
|
||||
|
||||
_target->addToToughness(oldpower);
|
||||
_target->addToToughness(-oldtoughness);
|
||||
_target->power = oldtoughness;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char * getMenuText(){
|
||||
return "Switch";
|
||||
}
|
||||
ATwist * clone() const{
|
||||
ATwist * a = NEW ATwist(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
// Add life of gives damage if a given zone has more or less than [condition] cards at the beginning of [phase]
|
||||
//Ex : the rack, ivory tower...
|
||||
class ALifeZoneLink:public MTGAbility{
|
||||
@@ -2844,6 +3317,26 @@ public:
|
||||
return a;}
|
||||
~ATransformerFOREVER(){delete ability;
|
||||
}};
|
||||
//switch p/t ueot
|
||||
class ATwistUEOT: public InstantAbility{
|
||||
public:
|
||||
ATwist * ability;
|
||||
ATwistUEOT(int id, MTGCardInstance * source, MTGCardInstance * target):InstantAbility(id,source,target){
|
||||
ability = NEW ATwist(id,source,target);}
|
||||
int resolve(){
|
||||
ATwist * a = ability->clone();
|
||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1,source,(Damageable *)(this->target),a);
|
||||
wrapper->addToGame();
|
||||
return 1;}
|
||||
ATwistUEOT * clone() const{
|
||||
ATwistUEOT * a = NEW ATwistUEOT(*this);
|
||||
a->ability = this->ability->clone();
|
||||
a->isClone = 1;
|
||||
return a;}
|
||||
~ATwistUEOT(){
|
||||
delete ability;
|
||||
}};
|
||||
|
||||
//becomes ability
|
||||
//Adds types/abilities/P/T to a card (aura)
|
||||
class ABecomes:public MTGAbility{
|
||||
@@ -2971,8 +3464,9 @@ class APreventAllCombatDamage:public MTGAbility{
|
||||
public:
|
||||
string to, from;
|
||||
REDamagePrevention * re;
|
||||
int type;
|
||||
|
||||
APreventAllCombatDamage(int id,MTGCardInstance * source,string to,string from):MTGAbility(id,source),to(to),from(from){
|
||||
APreventAllCombatDamage(int id,MTGCardInstance * source,string to,string from,int type = 0):MTGAbility(id,source),to(to),from(from),type(type){
|
||||
re = NULL;
|
||||
}
|
||||
|
||||
@@ -2986,7 +3480,17 @@ class APreventAllCombatDamage:public MTGAbility{
|
||||
if (toTc) toTc->targetter = NULL;
|
||||
TargetChooser *fromTc = tcf.createTargetChooser(from,source,this);
|
||||
if (fromTc) fromTc->targetter = NULL;
|
||||
if(type != 1 && type != 2){//not adding this creates a memory leak.
|
||||
re = NEW REDamagePrevention (this, fromTc, toTc, -1, false, DAMAGE_COMBAT);
|
||||
}
|
||||
if(type == 1){
|
||||
re = NULL;
|
||||
re = NEW REDamagePrevention (this, fromTc, toTc, -1, false, DAMAGE_ALL_TYPES);
|
||||
}
|
||||
if(type == 2){
|
||||
re = NULL;
|
||||
re = NEW REDamagePrevention (this, fromTc, toTc, -1, false, DAMAGE_OTHER);
|
||||
}
|
||||
game->replacementEffects->add(re);
|
||||
return MTGAbility::addToGame();
|
||||
}
|
||||
@@ -3010,10 +3514,10 @@ class APreventAllCombatDamageUEOT: public InstantAbility{
|
||||
public:
|
||||
APreventAllCombatDamage * ability;
|
||||
vector<APreventAllCombatDamage *> clones;
|
||||
APreventAllCombatDamageUEOT(int id,MTGCardInstance * source,string to, string from):InstantAbility(id,source){
|
||||
ability = NEW APreventAllCombatDamage(id,source,to, from);
|
||||
int type;
|
||||
APreventAllCombatDamageUEOT(int id,MTGCardInstance * source,string to, string from,int type = 0):InstantAbility(id,source){
|
||||
ability = NEW APreventAllCombatDamage(id,source,to, from,type);
|
||||
}
|
||||
|
||||
|
||||
int resolve(){
|
||||
APreventAllCombatDamage * a = ability->clone();
|
||||
@@ -3022,8 +3526,6 @@ public:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int destroy(){
|
||||
for (size_t i = 0; i < clones.size(); ++i){
|
||||
clones[i]->forceDestroy = 0;
|
||||
@@ -3036,7 +3538,6 @@ public:
|
||||
return ability->getMenuText();
|
||||
}
|
||||
|
||||
|
||||
APreventAllCombatDamageUEOT * clone() const{
|
||||
APreventAllCombatDamageUEOT * a = NEW APreventAllCombatDamageUEOT(*this);
|
||||
a->ability = this->ability->clone();
|
||||
@@ -3672,7 +4173,7 @@ class AHypnoticSpecter:public MTGAbility{
|
||||
if (e->damage->source != source) return 0;
|
||||
Player * p = dynamic_cast<Player *>(e->damage->target);
|
||||
if (!p) return 0;
|
||||
p->game->discardRandom(p->game->hand);
|
||||
p->game->discardRandom(p->game->hand,source);
|
||||
return 1; //is this meant to return 0 or 1?
|
||||
}
|
||||
|
||||
@@ -4456,7 +4957,7 @@ class AARandomDiscarder:public ActivatedAbilityTP{
|
||||
player = (Player *) _target;
|
||||
}
|
||||
for (int i = 0; i < nbcards; i++){
|
||||
player->game->discardRandom(player->game->hand);
|
||||
player->game->discardRandom(player->game->hand,source);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -4562,6 +5063,98 @@ class ARampageAbility:public MTGAbility{
|
||||
}
|
||||
};
|
||||
|
||||
//flanking ability
|
||||
class AFlankerAbility:public MTGAbility{
|
||||
public:
|
||||
MTGCardInstance * opponents[20];
|
||||
int nbOpponents;
|
||||
AFlankerAbility(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){
|
||||
nbOpponents = 0;
|
||||
}
|
||||
int receiveEvent(WEvent * event) {
|
||||
if (dynamic_cast<WEventBlockersChosen*>(event)) {
|
||||
nbOpponents = 0;
|
||||
MTGCardInstance * opponent = source->getNextOpponent();
|
||||
while (opponent && !opponent->has(Constants::FLANKING) && game->currentlyActing() == source->controller()->opponent()){
|
||||
opponents[nbOpponents] = opponent;
|
||||
nbOpponents ++;
|
||||
opponent = source->getNextOpponent(opponent);
|
||||
}
|
||||
for (int i = 0; i < nbOpponents ; i++){
|
||||
opponents[i]->power -= 1;
|
||||
opponents[i]->addToToughness(-1);
|
||||
opponents[i]->flanked += 1;
|
||||
if(opponents[i]->life == 0){opponents[i]->setPower(0);}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual ostream& toString(ostream& out) const
|
||||
{
|
||||
out << "AFlankerAbility ::: opponents : " << opponents
|
||||
<< " ; nbOpponents : " << nbOpponents
|
||||
<< " (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
AFlankerAbility * clone() const{
|
||||
AFlankerAbility * a = NEW AFlankerAbility(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
//Bushido ability
|
||||
class ABushidoAbility:public MTGAbility{
|
||||
public:
|
||||
MTGCardInstance * opponents[20];
|
||||
int nbOpponents;
|
||||
int PowerModifier;
|
||||
int ToughnessModifier;
|
||||
|
||||
ABushidoAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier):MTGAbility(_id, _source){
|
||||
PowerModifier = _PowerModifier;
|
||||
ToughnessModifier = _ToughnessModifier;
|
||||
nbOpponents = 0;
|
||||
}
|
||||
int receiveEvent(WEvent * event) {
|
||||
if (dynamic_cast<WEventBlockersChosen*>(event)) {
|
||||
MTGCardInstance * opponent = source->getNextOpponent();
|
||||
if (!opponent) return 0;
|
||||
source->power += PowerModifier;
|
||||
source->addToToughness(ToughnessModifier);
|
||||
while (opponent){
|
||||
opponents[nbOpponents] = opponent;
|
||||
nbOpponents ++;
|
||||
opponent = source->getNextOpponent(opponent);
|
||||
}
|
||||
}
|
||||
else if (WEventPhaseChange* pe = dynamic_cast<WEventPhaseChange*>(event)) {
|
||||
if (Constants::MTG_PHASE_AFTER_EOT == pe->to->id && nbOpponents)
|
||||
{
|
||||
source->power -= PowerModifier;
|
||||
source->addToToughness(-ToughnessModifier);
|
||||
nbOpponents = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual ostream& toString(ostream& out) const
|
||||
{
|
||||
out << "ABushidoAbility ::: opponents : " << opponents
|
||||
<< " ; nbOpponents : " << nbOpponents
|
||||
<< " (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
ABushidoAbility * clone() const{
|
||||
ABushidoAbility * a = NEW ABushidoAbility(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
//Instant Steal control of a target
|
||||
class AInstantControlSteal: public InstantAbility{
|
||||
public:
|
||||
@@ -4583,7 +5176,7 @@ class AInstantControlSteal: public InstantAbility{
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual ostream& toString(ostream& out) const
|
||||
|
||||
Reference in New Issue
Block a user