- 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:
wagic.the.homebrew@gmail.com
2009-07-25 14:57:27 +00:00
parent bfccf6d55a
commit 76d386be06
8 changed files with 147 additions and 56 deletions

View File

@@ -374,7 +374,7 @@ text=Flare deals 1 damage to target creature or player. Draw a card at the begin
id=2621
target=creature,player
auto=damage:1
auto=@next upkeep:draw:1
auto=@next upkeep:draw:1 controller
name=Flare
rarity=C
type=Instant
@@ -835,7 +835,7 @@ text=Target player discards a card. Draw a card at the beginning of the next
id=2471
target=player
auto=discard:1
auto=@next upkeep:draw:1
auto=@next upkeep:draw:1 controller
name=Mind Ravel
rarity=C
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
target=player
auto=deplete:1
auto=@next upkeep:draw:1
auto=@next upkeep:draw:1 controller
name=Ray of Erasure
rarity=C
type=Instant
@@ -1434,8 +1434,8 @@ id=2491
name=Touch of Death
target=player
auto=damage:1
auto=@next upkeep:draw:1
auto=life:1
auto=@next upkeep:draw:1 controller
auto=life:1 controller
rarity=C
type=Sorcery
mana={2}{B}

View File

@@ -1111,7 +1111,7 @@ text=Flare deals 1 damage to target creature or player. Draw a card at the begi
id=3447
name=Flare
auto=damage:1 target(creature,player)
auto=@next upkeep:draw:1
auto=@next upkeep:draw:1 controller
type=Instant
mana={2}{R}
rarity=C

View File

@@ -45,6 +45,7 @@ blessed_wine.txt
#blinking_spirit.txt
bloodfire_colossus.txt
bottle_gnomes.txt
bottle_gnomes2.txt
boggart_arsonists.txt
brass_man.txt
castle.txt

View File

@@ -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]

View File

@@ -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:
class AADrawer:public ActivatedAbility{
class AADrawer:public ActivatedAbilityTP{
public:
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(){
game->mLayers->stackLayer()->addDraw(source->controller(),nbcards);
game->mLayers->stackLayer()->resolve();
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();
}
return 1;
}
@@ -335,16 +367,20 @@ class AADrawer:public ActivatedAbility{
};
/*Gives life to target controller*/
class AALifer:public ActivatedAbility{
class AALifer:public ActivatedAbilityTP{
public:
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){
target = _target;
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){
}
int resolve(){
MTGCardInstance * _target = (MTGCardInstance *) target;
_target->controller()->life+=life;
Damageable * _target = (Damageable *) getTarget();
if (_target){
if (_target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
_target = ((MTGCardInstance *)_target)->controller();
}
_target->life+=life;
}
return 1;
}
@@ -1615,21 +1651,18 @@ class AForeach:public ListMaintainerAbility{
};
class AADamager:public ActivatedAbility{
class AADamager:public ActivatedAbilityTP{
public:
int damage;
int who;
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;
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){
aType = MTGAbility::DAMAGER;
}
int resolve(){
if(target){
Damageable * _target = (Damageable *)target;
if (who ==1){
_target = ((MTGCardInstance *) target)->controller();
}
Damageable * _target = (Damageable *) getTarget();
game->mLayers->stackLayer()->addDamage(source,_target, damage);
game->mLayers->stackLayer()->resolve();
return 1;
@@ -3678,19 +3711,25 @@ ALavaborn * clone() const{
//Generic Millstone
class AADepleter:public ActivatedAbility{
class AADepleter:public ActivatedAbilityTP{
public:
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){
target = _target;
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){
}
int resolve(){
Player * player = (Player *) target;
if (!player) return 0;
MTGLibrary * library = player->game->library;
for (int i = 0; i < nbcards; i++){
if (library->nb_cards)
player->game->putInZone(library->cards[library->nb_cards-1],library, player->game->graveyard);
Targetable * _target = getTarget();
Player * player;
if (_target){
if (_target->typeAsTarget() == TARGET_CARD){
player = ((MTGCardInstance *)_target)->controller();
}else{
player = (Player *) _target;
}
MTGLibrary * library = player->game->library;
for (int i = 0; i < nbcards; i++){
if (library->nb_cards)
player->game->putInZone(library->cards[library->nb_cards-1],library, player->game->graveyard);
}
}
return 1;
}
@@ -3708,18 +3747,24 @@ class AADepleter:public ActivatedAbility{
//Random Discard
class AARandomDiscarder:public ActivatedAbility{
class AARandomDiscarder:public ActivatedAbilityTP{
public:
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){
target = _target;
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){
}
int resolve(){
Player * player = (Player *) target;
if (!player) return 0;
for (int i = 0; i < nbcards; i++){
player->game->discardRandom(player->game->hand);
}
Targetable * _target = getTarget();
Player * player;
if (_target){
if (_target->typeAsTarget() == TARGET_CARD){
player = ((MTGCardInstance *)_target)->controller();
}else{
player = (Player *) _target;
}
for (int i = 0; i < nbcards; i++){
player->game->discardRandom(player->game->hand);
}
}
return 1;
}

View File

@@ -27,6 +27,14 @@ class TargetChooser: public TargetsList {
int forceTargetListReady;
public:
enum{
UNSET = 0,
OPPONENT = -1,
CONTROLLER = 1,
TARGET_CONTROLLER = 2
};
TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1);
MTGCardInstance * source;

View File

@@ -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
found = s.find("damage");
if (found != string::npos){
@@ -392,9 +398,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
Damageable * d = NULL;
if (spell) d = spell->getNextDamageableTarget();
int who = 0;
if (s.find("controller") != string::npos) who=1;
MTGAbility * a = NEW AADamager(id,card,d, damage, NULL, who);
MTGAbility * a = NEW AADamager(id,card,d, damage, NULL, 0, who);
a->oneShot = 1;
return a;
}
@@ -412,7 +416,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
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;
return a;
}
@@ -429,7 +435,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
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;
return a;
}
@@ -445,9 +453,10 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
}else{
nbcards = atoi(s.substr(start+1).c_str());
}
Player * player = NULL;
if (spell) player = spell->getNextPlayerTarget();
MTGAbility * a = NEW AADepleter(id,card,player,nbcards);
Targetable * t = NULL;
if (spell) t = spell->getNextPlayerTarget();
MTGAbility * a = NEW AADepleter(id,card,t,nbcards,NULL,0,who);
a->oneShot = 1;
return a;
}
@@ -477,10 +486,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
nbcards = atoi(s.substr(start+1).c_str());
}
Player * player = NULL;
if (spell) player = spell->getNextPlayerTarget();
if (!player) player = GameObserver::GetInstance()->currentlyActing();
MTGAbility * a = NEW AARandomDiscarder (id, card, player,nbcards);
Targetable * t = NULL;
if (spell) t = spell->getNextPlayerTarget();
MTGAbility * a = NEW AARandomDiscarder (id, card, t,nbcards,NULL,0,who);
a->oneShot = 1;
return a;
}

View File

@@ -59,6 +59,12 @@ MTGPlayerCards::~MTGPlayerCards(){
void MTGPlayerCards::setOwner(Player * 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){
@@ -122,12 +128,13 @@ MTGCardInstance * MTGPlayerCards::putInPlay(MTGCardInstance * card){
MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){
MTGCardInstance * copy = NULL;
MTGGraveyard * grave = card->owner->game->graveyard;
if (inPlay->hasCard(card)){
copy = putInZone(card,inPlay, graveyard);
copy = putInZone(card,inPlay, grave);
}else if (stack->hasCard(card)){
copy = putInZone(card,stack, graveyard);
copy = putInZone(card,stack, grave);
}else{
copy = putInZone(card,hand, graveyard);
copy = putInZone(card,hand, grave);
}
return copy;
@@ -223,7 +230,7 @@ MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card, int createCopy
if (card->isToken){ //TODO better than this ?
return card;
}
card->lastController = card->controller();
//card->lastController = card->controller();
if (createCopy) {
copy = NEW MTGCardInstance(card->model,card->owner->game);
copy->previous = card;
@@ -285,6 +292,7 @@ void MTGGameZone::addCard(MTGCardInstance * card){
cards.push_back(card);
nb_cards++;
cardsMap[card] = 1;
card->lastController = this->owner;
}