Erwan
- fixed a bug with bottle gnomes (would give life to opponent even if you steal control) - huge update for abilities life,draw,damage,deplete,discard in the parser. This breaks some cards (so we need to fix them) but allows more flexibility in the future. See my post on the forum
This commit is contained in:
@@ -374,7 +374,7 @@ text=Flare deals 1 damage to target creature or player. Draw a card at the begin
|
|||||||
id=2621
|
id=2621
|
||||||
target=creature,player
|
target=creature,player
|
||||||
auto=damage:1
|
auto=damage:1
|
||||||
auto=@next upkeep:draw:1
|
auto=@next upkeep:draw:1 controller
|
||||||
name=Flare
|
name=Flare
|
||||||
rarity=C
|
rarity=C
|
||||||
type=Instant
|
type=Instant
|
||||||
@@ -835,7 +835,7 @@ text=Target player discards a card. Draw a card at the beginning of the next
|
|||||||
id=2471
|
id=2471
|
||||||
target=player
|
target=player
|
||||||
auto=discard:1
|
auto=discard:1
|
||||||
auto=@next upkeep:draw:1
|
auto=@next upkeep:draw:1 controller
|
||||||
name=Mind Ravel
|
name=Mind Ravel
|
||||||
rarity=C
|
rarity=C
|
||||||
type=Sorcery
|
type=Sorcery
|
||||||
@@ -1096,7 +1096,7 @@ text=Target player puts the top card of his or her library into his or her grave
|
|||||||
id=2529
|
id=2529
|
||||||
target=player
|
target=player
|
||||||
auto=deplete:1
|
auto=deplete:1
|
||||||
auto=@next upkeep:draw:1
|
auto=@next upkeep:draw:1 controller
|
||||||
name=Ray of Erasure
|
name=Ray of Erasure
|
||||||
rarity=C
|
rarity=C
|
||||||
type=Instant
|
type=Instant
|
||||||
@@ -1434,8 +1434,8 @@ id=2491
|
|||||||
name=Touch of Death
|
name=Touch of Death
|
||||||
target=player
|
target=player
|
||||||
auto=damage:1
|
auto=damage:1
|
||||||
auto=@next upkeep:draw:1
|
auto=@next upkeep:draw:1 controller
|
||||||
auto=life:1
|
auto=life:1 controller
|
||||||
rarity=C
|
rarity=C
|
||||||
type=Sorcery
|
type=Sorcery
|
||||||
mana={2}{B}
|
mana={2}{B}
|
||||||
|
|||||||
@@ -1111,7 +1111,7 @@ text=Flare deals 1 damage to target creature or player. Draw a card at the begi
|
|||||||
id=3447
|
id=3447
|
||||||
name=Flare
|
name=Flare
|
||||||
auto=damage:1 target(creature,player)
|
auto=damage:1 target(creature,player)
|
||||||
auto=@next upkeep:draw:1
|
auto=@next upkeep:draw:1 controller
|
||||||
type=Instant
|
type=Instant
|
||||||
mana={2}{R}
|
mana={2}{R}
|
||||||
rarity=C
|
rarity=C
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ blessed_wine.txt
|
|||||||
#blinking_spirit.txt
|
#blinking_spirit.txt
|
||||||
bloodfire_colossus.txt
|
bloodfire_colossus.txt
|
||||||
bottle_gnomes.txt
|
bottle_gnomes.txt
|
||||||
|
bottle_gnomes2.txt
|
||||||
boggart_arsonists.txt
|
boggart_arsonists.txt
|
||||||
brass_man.txt
|
brass_man.txt
|
||||||
castle.txt
|
castle.txt
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#Bug: Bug: taking control of bottle gnomes, then sacrificing them: opponent gets life
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
hand:persuasion
|
||||||
|
manapool:{3}{U}{U}
|
||||||
|
[PLAYER2]
|
||||||
|
inplay:bottle gnomes
|
||||||
|
[DO]
|
||||||
|
persuasion
|
||||||
|
bottle gnomes
|
||||||
|
bottle gnomes
|
||||||
|
[ASSERT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
graveyard:persuasion
|
||||||
|
manapool:{0}
|
||||||
|
life:23
|
||||||
|
[PLAYER2]
|
||||||
|
graveyard:bottle gnomes
|
||||||
|
[END]
|
||||||
@@ -307,18 +307,50 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ActivatedAbilityTP:public ActivatedAbility{
|
||||||
|
public:
|
||||||
|
int who;
|
||||||
|
ActivatedAbilityTP(int id, MTGCardInstance * card, Targetable * _target = NULL, ManaCost * cost=NULL, int doTap = 0, int who = TargetChooser::UNSET):ActivatedAbility(id,card,cost,0,doTap),who(who){
|
||||||
|
if (_target) target = _target;
|
||||||
|
}
|
||||||
|
|
||||||
|
Targetable * getTarget(){
|
||||||
|
switch(who){
|
||||||
|
case TargetChooser::TARGET_CONTROLLER:
|
||||||
|
if (target) return ((MTGCardInstance *)target)->controller();
|
||||||
|
return NULL;
|
||||||
|
case TargetChooser::CONTROLLER:
|
||||||
|
return source->controller();
|
||||||
|
case TargetChooser::OPPONENT:
|
||||||
|
return source->controller()->opponent();
|
||||||
|
default:
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//Drawer, allows to draw a card for a cost:
|
//Drawer, allows to draw a card for a cost:
|
||||||
|
|
||||||
class AADrawer:public ActivatedAbility{
|
class AADrawer:public ActivatedAbilityTP{
|
||||||
public:
|
public:
|
||||||
int nbcards;
|
int nbcards;
|
||||||
AADrawer(int _id, MTGCardInstance * card,ManaCost * _cost, int _nbcards = 1, int _tap = 0):ActivatedAbility(_id, card,_cost,0,_tap),nbcards(_nbcards){
|
AADrawer(int _id, MTGCardInstance * card,Targetable * _target,ManaCost * _cost, int _nbcards = 1, int _tap = 0, int who=TargetChooser::UNSET):ActivatedAbilityTP(_id, card,_target,_cost,_tap,who),nbcards(_nbcards){
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve(){
|
int resolve(){
|
||||||
game->mLayers->stackLayer()->addDraw(source->controller(),nbcards);
|
Targetable * _target = getTarget();
|
||||||
|
Player * player;
|
||||||
|
if (_target){
|
||||||
|
if (_target->typeAsTarget() == TARGET_CARD){
|
||||||
|
player = ((MTGCardInstance *)_target)->controller();
|
||||||
|
}else{
|
||||||
|
player = (Player *) _target;
|
||||||
|
}
|
||||||
|
game->mLayers->stackLayer()->addDraw(player,nbcards);
|
||||||
game->mLayers->stackLayer()->resolve();
|
game->mLayers->stackLayer()->resolve();
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,16 +367,20 @@ class AADrawer:public ActivatedAbility{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*Gives life to target controller*/
|
/*Gives life to target controller*/
|
||||||
class AALifer:public ActivatedAbility{
|
class AALifer:public ActivatedAbilityTP{
|
||||||
public:
|
public:
|
||||||
int life;
|
int life;
|
||||||
AALifer(int _id, MTGCardInstance * card, MTGCardInstance * _target, int life, ManaCost * _cost = NULL, int _tap = 0):ActivatedAbility(_id, card,_cost,0,_tap),life(life){
|
AALifer(int _id, MTGCardInstance * card, Targetable * _target, int life, ManaCost * _cost = NULL, int _tap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id, card,_target,_cost,_tap,who),life(life){
|
||||||
target = _target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve(){
|
int resolve(){
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
Damageable * _target = (Damageable *) getTarget();
|
||||||
_target->controller()->life+=life;
|
if (_target){
|
||||||
|
if (_target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
|
||||||
|
_target = ((MTGCardInstance *)_target)->controller();
|
||||||
|
}
|
||||||
|
_target->life+=life;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1615,21 +1651,18 @@ class AForeach:public ListMaintainerAbility{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class AADamager:public ActivatedAbility{
|
|
||||||
|
|
||||||
|
class AADamager:public ActivatedAbilityTP{
|
||||||
public:
|
public:
|
||||||
int damage;
|
int damage;
|
||||||
int who;
|
AADamager(int _id, MTGCardInstance * _source, Targetable * _target, int _damage = 0, ManaCost * _cost=NULL, int doTap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id,_source,_target,_cost,doTap,who),damage(_damage){
|
||||||
AADamager(int _id, MTGCardInstance * _source, Damageable * _target, int _damage = 0, ManaCost * _cost=NULL, int who=0):ActivatedAbility(_id,_source,_cost),damage(_damage),who(who){
|
|
||||||
if (_target) target = _target;
|
|
||||||
aType = MTGAbility::DAMAGER;
|
aType = MTGAbility::DAMAGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve(){
|
int resolve(){
|
||||||
if(target){
|
if(target){
|
||||||
Damageable * _target = (Damageable *)target;
|
Damageable * _target = (Damageable *) getTarget();
|
||||||
if (who ==1){
|
|
||||||
_target = ((MTGCardInstance *) target)->controller();
|
|
||||||
}
|
|
||||||
game->mLayers->stackLayer()->addDamage(source,_target, damage);
|
game->mLayers->stackLayer()->addDamage(source,_target, damage);
|
||||||
game->mLayers->stackLayer()->resolve();
|
game->mLayers->stackLayer()->resolve();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3678,20 +3711,26 @@ ALavaborn * clone() const{
|
|||||||
|
|
||||||
|
|
||||||
//Generic Millstone
|
//Generic Millstone
|
||||||
class AADepleter:public ActivatedAbility{
|
class AADepleter:public ActivatedAbilityTP{
|
||||||
public:
|
public:
|
||||||
int nbcards;
|
int nbcards;
|
||||||
AADepleter(int _id, MTGCardInstance * card, Player * _target, int nbcards = 1, ManaCost * _cost=NULL, int _tap = 0):ActivatedAbility(_id,card, _cost,0,_tap),nbcards(nbcards){
|
AADepleter(int _id, MTGCardInstance * card, Targetable * _target, int nbcards = 1, ManaCost * _cost=NULL, int _tap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id,card, _target,_cost,_tap,who),nbcards(nbcards){
|
||||||
target = _target;
|
|
||||||
}
|
}
|
||||||
int resolve(){
|
int resolve(){
|
||||||
Player * player = (Player *) target;
|
Targetable * _target = getTarget();
|
||||||
if (!player) return 0;
|
Player * player;
|
||||||
|
if (_target){
|
||||||
|
if (_target->typeAsTarget() == TARGET_CARD){
|
||||||
|
player = ((MTGCardInstance *)_target)->controller();
|
||||||
|
}else{
|
||||||
|
player = (Player *) _target;
|
||||||
|
}
|
||||||
MTGLibrary * library = player->game->library;
|
MTGLibrary * library = player->game->library;
|
||||||
for (int i = 0; i < nbcards; i++){
|
for (int i = 0; i < nbcards; i++){
|
||||||
if (library->nb_cards)
|
if (library->nb_cards)
|
||||||
player->game->putInZone(library->cards[library->nb_cards-1],library, player->game->graveyard);
|
player->game->putInZone(library->cards[library->nb_cards-1],library, player->game->graveyard);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3708,18 +3747,24 @@ class AADepleter:public ActivatedAbility{
|
|||||||
|
|
||||||
|
|
||||||
//Random Discard
|
//Random Discard
|
||||||
class AARandomDiscarder:public ActivatedAbility{
|
class AARandomDiscarder:public ActivatedAbilityTP{
|
||||||
public:
|
public:
|
||||||
int nbcards;
|
int nbcards;
|
||||||
AARandomDiscarder(int _id, MTGCardInstance * card, Player * _target, int nbcards = 1, ManaCost * _cost=NULL, int _tap = 0):ActivatedAbility(_id,card, _cost,0,_tap),nbcards(nbcards){
|
AARandomDiscarder(int _id, MTGCardInstance * card, Targetable * _target, int nbcards = 1, ManaCost * _cost=NULL, int _tap = 0,int who=TargetChooser::UNSET):ActivatedAbilityTP(_id,card, _target,_cost,_tap,who),nbcards(nbcards){
|
||||||
target = _target;
|
|
||||||
}
|
}
|
||||||
int resolve(){
|
int resolve(){
|
||||||
Player * player = (Player *) target;
|
Targetable * _target = getTarget();
|
||||||
if (!player) return 0;
|
Player * player;
|
||||||
|
if (_target){
|
||||||
|
if (_target->typeAsTarget() == TARGET_CARD){
|
||||||
|
player = ((MTGCardInstance *)_target)->controller();
|
||||||
|
}else{
|
||||||
|
player = (Player *) _target;
|
||||||
|
}
|
||||||
for (int i = 0; i < nbcards; i++){
|
for (int i = 0; i < nbcards; i++){
|
||||||
player->game->discardRandom(player->game->hand);
|
player->game->discardRandom(player->game->hand);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ class TargetChooser: public TargetsList {
|
|||||||
int forceTargetListReady;
|
int forceTargetListReady;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum{
|
||||||
|
UNSET = 0,
|
||||||
|
OPPONENT = -1,
|
||||||
|
CONTROLLER = 1,
|
||||||
|
TARGET_CONTROLLER = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1);
|
TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1);
|
||||||
|
|
||||||
MTGCardInstance * source;
|
MTGCardInstance * source;
|
||||||
|
|||||||
@@ -377,6 +377,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int who = TargetChooser::UNSET;
|
||||||
|
if (s.find(" controller") != string::npos) who=TargetChooser::CONTROLLER;
|
||||||
|
if (s.find(" opponent") != string::npos) who=TargetChooser::OPPONENT;
|
||||||
|
if (s.find(" targetcontroller") != string::npos) who=TargetChooser::TARGET_CONTROLLER;
|
||||||
|
|
||||||
//Damage
|
//Damage
|
||||||
found = s.find("damage");
|
found = s.find("damage");
|
||||||
if (found != string::npos){
|
if (found != string::npos){
|
||||||
@@ -392,9 +398,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
|
|
||||||
Damageable * d = NULL;
|
Damageable * d = NULL;
|
||||||
if (spell) d = spell->getNextDamageableTarget();
|
if (spell) d = spell->getNextDamageableTarget();
|
||||||
int who = 0;
|
MTGAbility * a = NEW AADamager(id,card,d, damage, NULL, 0, who);
|
||||||
if (s.find("controller") != string::npos) who=1;
|
|
||||||
MTGAbility * a = NEW AADamager(id,card,d, damage, NULL, who);
|
|
||||||
a->oneShot = 1;
|
a->oneShot = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -412,7 +416,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
life = atoi(s.substr(start+1).c_str());
|
life = atoi(s.substr(start+1).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
MTGAbility * a = NEW AALifer(id,card,card,life);
|
Damageable * d = NULL;
|
||||||
|
if (spell) d = spell->getNextPlayerTarget();
|
||||||
|
MTGAbility * a = NEW AALifer(id,card,d,life,NULL,0,who);
|
||||||
a->oneShot = 1;
|
a->oneShot = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -429,7 +435,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
nbcards = atoi(s.substr(start+1).c_str());
|
nbcards = atoi(s.substr(start+1).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
MTGAbility * a = NEW AADrawer(id,card,NULL,nbcards);
|
Targetable * t = NULL;
|
||||||
|
if (spell) t = spell->getNextPlayerTarget();
|
||||||
|
MTGAbility * a = NEW AADrawer(id,card,t,NULL,nbcards,0,who);
|
||||||
a->oneShot = 1;
|
a->oneShot = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -445,9 +453,10 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
}else{
|
}else{
|
||||||
nbcards = atoi(s.substr(start+1).c_str());
|
nbcards = atoi(s.substr(start+1).c_str());
|
||||||
}
|
}
|
||||||
Player * player = NULL;
|
|
||||||
if (spell) player = spell->getNextPlayerTarget();
|
Targetable * t = NULL;
|
||||||
MTGAbility * a = NEW AADepleter(id,card,player,nbcards);
|
if (spell) t = spell->getNextPlayerTarget();
|
||||||
|
MTGAbility * a = NEW AADepleter(id,card,t,nbcards,NULL,0,who);
|
||||||
a->oneShot = 1;
|
a->oneShot = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -477,10 +486,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
nbcards = atoi(s.substr(start+1).c_str());
|
nbcards = atoi(s.substr(start+1).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Player * player = NULL;
|
Targetable * t = NULL;
|
||||||
if (spell) player = spell->getNextPlayerTarget();
|
if (spell) t = spell->getNextPlayerTarget();
|
||||||
if (!player) player = GameObserver::GetInstance()->currentlyActing();
|
MTGAbility * a = NEW AARandomDiscarder (id, card, t,nbcards,NULL,0,who);
|
||||||
MTGAbility * a = NEW AARandomDiscarder (id, card, player,nbcards);
|
|
||||||
a->oneShot = 1;
|
a->oneShot = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ MTGPlayerCards::~MTGPlayerCards(){
|
|||||||
|
|
||||||
void MTGPlayerCards::setOwner(Player * player){
|
void MTGPlayerCards::setOwner(Player * player){
|
||||||
library->setOwner(player);
|
library->setOwner(player);
|
||||||
|
graveyard->setOwner(player);
|
||||||
|
hand->setOwner(player);
|
||||||
|
inPlay->setOwner(player);
|
||||||
|
removedFromGame->setOwner(player);
|
||||||
|
stack->setOwner(player);
|
||||||
|
garbage->setOwner(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTGPlayerCards::initGame(int shuffle, int draw){
|
void MTGPlayerCards::initGame(int shuffle, int draw){
|
||||||
@@ -122,12 +128,13 @@ MTGCardInstance * MTGPlayerCards::putInPlay(MTGCardInstance * card){
|
|||||||
|
|
||||||
MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){
|
MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){
|
||||||
MTGCardInstance * copy = NULL;
|
MTGCardInstance * copy = NULL;
|
||||||
|
MTGGraveyard * grave = card->owner->game->graveyard;
|
||||||
if (inPlay->hasCard(card)){
|
if (inPlay->hasCard(card)){
|
||||||
copy = putInZone(card,inPlay, graveyard);
|
copy = putInZone(card,inPlay, grave);
|
||||||
}else if (stack->hasCard(card)){
|
}else if (stack->hasCard(card)){
|
||||||
copy = putInZone(card,stack, graveyard);
|
copy = putInZone(card,stack, grave);
|
||||||
}else{
|
}else{
|
||||||
copy = putInZone(card,hand, graveyard);
|
copy = putInZone(card,hand, grave);
|
||||||
}
|
}
|
||||||
return copy;
|
return copy;
|
||||||
|
|
||||||
@@ -223,7 +230,7 @@ MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card, int createCopy
|
|||||||
if (card->isToken){ //TODO better than this ?
|
if (card->isToken){ //TODO better than this ?
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
card->lastController = card->controller();
|
//card->lastController = card->controller();
|
||||||
if (createCopy) {
|
if (createCopy) {
|
||||||
copy = NEW MTGCardInstance(card->model,card->owner->game);
|
copy = NEW MTGCardInstance(card->model,card->owner->game);
|
||||||
copy->previous = card;
|
copy->previous = card;
|
||||||
@@ -285,6 +292,7 @@ void MTGGameZone::addCard(MTGCardInstance * card){
|
|||||||
cards.push_back(card);
|
cards.push_back(card);
|
||||||
nb_cards++;
|
nb_cards++;
|
||||||
cardsMap[card] = 1;
|
cardsMap[card] = 1;
|
||||||
|
card->lastController = this->owner;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user