Laurent - Added draw/token to the foreach parser (allow to sligthly reduce the number of lines in MTGAbility.cpp and also add few cards to different cards.dat.)

NOTE that all these additions to the foreach parser are only available for the "inplay" area... "countcards" will need to be updated in order to have thing such as graveyard or hand to be taken into consideration (but when it will be done cards such as Spontaneous Generation - MRQ, could be added)
Also updated (tentatively) the "cantbeblockedby" in the parser it still does not work...ARG... but I can feel that I'm not far away from the solution...
We need also to go through some of the cards.dat to be sure we are not missing any possible addition ...
This commit is contained in:
wagic.laurent
2009-06-29 11:11:41 +00:00
parent 0218680ae0
commit 6097b1282b
14 changed files with 99 additions and 93 deletions
+1 -1
View File
@@ -701,7 +701,7 @@ mana={3}{U}{U}
text=Elven Riders can't be blocked except by Walls and/or creatures with flying. text=Elven Riders can't be blocked except by Walls and/or creatures with flying.
id=135266 id=135266
name=Elven Riders name=Elven Riders
auto=cantbeblockedby(creature[-flying]) auto=cantbeblockedby(creature[-flying],-walls)
rarity=U rarity=U
color=Green color=Green
type=Creature type=Creature
+12
View File
@@ -291,6 +291,18 @@ type=Instant
mana={2}{R} mana={2}{R}
[/card] [/card]
[card] [card]
text=When Regal Force comes into play, draw a card for each green creature you control.
id=147373
name=Regal Force
auto=foreach(creature[green]|myinplay)draw:1
rarity=R
type=Creature
mana={4}{G}{G}{G}
power=5
subtype=Elemental
toughness=5
[/card]
[card]
text=Wither (This deals damage to creatures in the form of -1/-1 counters.) Persist (When this creature is put into a graveyard from play, if it had no -1/-1 counters on it, return it to play under its owner's control with a -1/-1 counter on it.) text=Wither (This deals damage to creatures in the form of -1/-1 counters.) Persist (When this creature is put into a graveyard from play, if it had no -1/-1 counters on it, return it to play under its owner's control with a -1/-1 counter on it.)
abilities=wither,persist abilities=wither,persist
id=158902 id=158902
-11
View File
@@ -1042,17 +1042,6 @@ mana={2}{W}
subtype=Aura subtype=Aura
[/card] [/card]
[card] [card]
text=When Regal Force comes into play, draw a card for each green creature you control.
id=147373
name=Regal Force
rarity=R
type=Creature
mana={4}{G}{G}{G}
power=5
subtype=Elemental
toughness=5
[/card]
[card]
text=Rekindled Flame deals 4 damage to target creature or player. At the beginning of your upkeep, if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand. text=Rekindled Flame deals 4 damage to target creature or player. At the beginning of your upkeep, if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand.
target=creature,player target=creature,player
id=158108 id=158108
+13 -1
View File
@@ -72,6 +72,8 @@ mana={3}
[card] [card]
text={W}, Sacrifice an enchantment: Destroy target enchantment. {3}{U}{U}: Counter target enchantment spell. text={W}, Sacrifice an enchantment: Destroy target enchantment. {3}{U}{U}: Counter target enchantment spell.
id=2663 id=2663
auto={W}{S(Enchantment|myinplay)}:destroy target(enchantment)
auto={3}{U}{U}:fizzle target(enchantment|stack)
name=Arenson's Aura name=Arenson's Aura
rarity=C rarity=C
type=Enchantment type=Enchantment
@@ -170,6 +172,8 @@ mana={1}
[card] [card]
text=Untap all white creatures you control. Whenever a creature blocks this turn, it gets +0/+1 until end of turn. text=Untap all white creatures you control. Whenever a creature blocks this turn, it gets +0/+1 until end of turn.
id=2665 id=2665
auto=untap all(creature[white]|myinplay)
auto=lord(creature[blocking])0/1
name=Battle Cry name=Battle Cry
rarity=U rarity=U
type=Instant type=Instant
@@ -187,6 +191,9 @@ subtype=Aura
[card] [card]
text=Enchant creature Enchanted creature can't be blocked by black creatures. Enchanted creature gets +2/+2 as long as an opponent controls a black permanent. text=Enchant creature Enchanted creature can't be blocked by black creatures. Enchanted creature gets +2/+2 as long as an opponent controls a black permanent.
id=2666 id=2666
target=creature
auto=cantbeblockedby(creature[black])
auto=aslongas(*[black]|opponentinplay)2/2
name=Black Scarab name=Black Scarab
rarity=U rarity=U
type=Enchantment type=Enchantment
@@ -216,6 +223,9 @@ mana={G}{G}
[card] [card]
text=Enchant creature Enchanted creature can't be blocked by blue creatures. Enchanted creature gets +2/+2 as long as an opponent controls a blue permanent. text=Enchant creature Enchanted creature can't be blocked by blue creatures. Enchanted creature gets +2/+2 as long as an opponent controls a blue permanent.
id=2669 id=2669
target=creature
auto=cantbeblockedby(creature[blue])
auto=aslongas(*[blue]|opponentinplay)2/2
name=Blue Scarab name=Blue Scarab
rarity=U rarity=U
type=Enchantment type=Enchantment
@@ -390,6 +400,8 @@ mana={2}
[card] [card]
text=When Curse of Marit Lage comes into play, tap all Islands. Islands don't untap during their controllers' untap steps. text=When Curse of Marit Lage comes into play, tap all Islands. Islands don't untap during their controllers' untap steps.
id=2617 id=2617
auto=tap all(island)
auto=lord(island)doesntuntap
name=Curse of Marit Lage name=Curse of Marit Lage
rarity=R rarity=R
type=Enchantment type=Enchantment
@@ -622,7 +634,7 @@ text=Foul Familiar can't block. {B}, Pay 1 life: Return Foul Familiar to its
id=2450 id=2450
name=Foul Familiar name=Foul Familiar
abilities=cantblock abilities=cantblock
auto={B} auto={B}:moveto(ownerhand) && damage:1 && controller
rarity=C rarity=C
type=Creature type=Creature
mana={2}{B} mana={2}{B}
+1 -1
View File
@@ -460,7 +460,7 @@ type=Enchantment
[card] [card]
text=Target creature gets +0/+X until end of turn, where X is its converted mana cost. text=Target creature gets +0/+X until end of turn, where X is its converted mana cost.
id=1614 id=1614
taget=creature target=creature
name=Great Defender name=Great Defender
rarity=U rarity=U
type=Instant type=Instant
+1
View File
@@ -128,6 +128,7 @@ toughness=1
text=Put a 1/1 green Elf Warrior creature token into play for each Elf you control. text=Put a 1/1 green Elf Warrior creature token into play for each Elf you control.
id=139676 id=139676
name=Elvish Promenade name=Elvish Promenade
auto=foreach(elf|myinplay)token(Elf Warrior,creature Elf Warrior,1/1,green)
rarity=U rarity=U
type=Sorcery type=Sorcery
mana={3}{G} mana={3}{G}
+9
View File
@@ -214,6 +214,15 @@ toughness=1
abilities=flying,cloud abilities=flying,cloud
[/card] [/card]
[card] [card]
text=Draw a card for each creature you control.
id=19739
auto=foreach(creature|myinplay)draw:1
name=Collective Unconscious
rarity=R
type=Sorcery
mana={4}{G}{G}
[/card]
[card]
text=Counter target spell. text=Counter target spell.
target=*|stack target=*|stack
auto=fizzle auto=fizzle
-8
View File
@@ -412,14 +412,6 @@ type=Enchantment
mana={2}{U}{U} mana={2}{U}{U}
[/card] [/card]
[card] [card]
text=Draw a card for each creature you control.
id=19739
name=Collective Unconscious
rarity=R
type=Sorcery
mana={4}{G}{G}
[/card]
[card]
text=Nonartifact creatures get +2/+2 as long as they all share a color. text=Nonartifact creatures get +2/+2 as long as they all share a color.
id=19665 id=19665
name=Common Cause name=Common Cause
+10 -1
View File
@@ -1195,7 +1195,7 @@ toughness=4
text=Spitting Earth deals damage equal to the number of Mountains you control to target creature. text=Spitting Earth deals damage equal to the number of Mountains you control to target creature.
id=4362 id=4362
target=creature target=creature
alias=136509 auto=foreach(moutain|myinplay)damage:1
name=Spitting Earth name=Spitting Earth
rarity=C rarity=C
type=Sorcery type=Sorcery
@@ -1297,6 +1297,15 @@ mana={2}{U}
type=Sorcery type=Sorcery
[/card] [/card]
[card] [card]
text=Draw a card for each tapped creature target opponent controls.
id=4279
name=Theft of Dreams
auto=foreach(creature[tapped]|opponentinplay)draw:1
rarity=U
type=Sorcery
mana={2}{U}
[/card]
[card]
text=Put target creature on top of its owner's library. text=Put target creature on top of its owner's library.
target=creature target=creature
auto=moveTo(ownerLibrary) auto=moveTo(ownerLibrary)
-8
View File
@@ -539,14 +539,6 @@ type=Sorcery
mana={1}{W} mana={1}{W}
[/card] [/card]
[card] [card]
text=Draw a card for each tapped creature target opponent controls.
id=4279
name=Theft of Dreams
rarity=U
type=Sorcery
mana={2}{U}
[/card]
[card]
text=Whenever Thing from the Deep attacks, sacrifice it unless you sacrifice an Island. text=Whenever Thing from the Deep attacks, sacrifice it unless you sacrifice an Island.
id=4280 id=4280
name=Thing from the Deep name=Thing from the Deep
+1
View File
@@ -286,6 +286,7 @@ subtype=Aura
text=Draw a card for each Island you control. text=Draw a card for each Island you control.
id=87978 id=87978
name=Flow of Ideas name=Flow of Ideas
auto=foreach(island|myinplay)draw:1
rarity=U rarity=U
type=Sorcery type=Sorcery
mana={5}{U} mana={5}{U}
+2 -1
View File
@@ -306,7 +306,7 @@ mana={2R}{2R}{2R}
[card] [card]
text=Draw a card for each Island you control. text=Draw a card for each Island you control.
id=158692 id=158692
alias=87978 auto=foreach(island|myinplay)draw:1
name=Flow of Ideas name=Flow of Ideas
rarity=U rarity=U
type=Sorcery type=Sorcery
@@ -443,6 +443,7 @@ toughness=1
text=Put a 2/2 green Wolf creature token into play for each Forest you control. text=Put a 2/2 green Wolf creature token into play for each Forest you control.
id=153996 id=153996
name=Howl of the Night Pack name=Howl of the Night Pack
auto=foreach(forest|myinplay)token(Wolf,creature wolf,2/2,green)
rarity=U rarity=U
type=Sorcery type=Sorcery
mana={6}{G} mana={6}{G}
+1
View File
@@ -234,6 +234,7 @@ class AbilityFactory{
int moveAll(TargetChooser * tc, string destinationZone); int moveAll(TargetChooser * tc, string destinationZone);
int damageAll(TargetChooser * tc, int damage); int damageAll(TargetChooser * tc, int damage);
int TapAll(TargetChooser * tc); int TapAll(TargetChooser * tc);
int CantBlock(TargetChooser * tc);
int UntapAll(TargetChooser * tc); int UntapAll(TargetChooser * tc);
void addAbilities(int _id, Spell * spell); void addAbilities(int _id, Spell * spell);
}; };
+48 -61
View File
@@ -50,6 +50,19 @@ int AbilityFactory::destroyAllInPlay(TargetChooser * tc, int bury){
return 1; return 1;
} }
int AbilityFactory::CantBlock(TargetChooser * tc){
GameObserver * g = GameObserver::GetInstance();
MTGCardInstance * source = tc->source;
for (int j = g->opponent()->game->inPlay->nb_cards-1; j >=0 ; j--){
MTGCardInstance * current = g->opponent()->game->inPlay->cards[j];
if (tc->canTarget(current)){
current->canBlock(source);
return 0;
}
}
return 1;
}
int AbilityFactory::damageAll(TargetChooser * tc, int damage){ int AbilityFactory::damageAll(TargetChooser * tc, int damage){
MTGCardInstance * source = tc->source; MTGCardInstance * source = tc->source;
tc->source = NULL; // This is to prevent protection from... as objects that destroy all do not actually target tc->source = NULL; // This is to prevent protection from... as objects that destroy all do not actually target
@@ -84,6 +97,8 @@ int AbilityFactory::moveAll(TargetChooser * tc, string destinationZone){
} }
int AbilityFactory::TapAll(TargetChooser * tc){ int AbilityFactory::TapAll(TargetChooser * tc){
MTGCardInstance * source = tc->source; MTGCardInstance * source = tc->source;
tc->source = NULL; // This is to prevent protection from... tc->source = NULL; // This is to prevent protection from...
@@ -443,7 +458,15 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
int multiplier = 1; int multiplier = 1;
found = s.find("*"); found = s.find("*");
if (found != string::npos)multiplier = atoi(s.substr(found+1).c_str()); if (found != string::npos)multiplier = atoi(s.substr(found+1).c_str());
if(cost || doTap){ if (lordType == PARSER_FOREACH){
int nbtoken = countCards(lordTargets);
ATokenCreator * tok = NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap);
for (int i=0; i < nbtoken; i++){
tok->resolve();
}
delete tok;
}else{
if(cost || doTap){
game->addObserver(NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap)); game->addObserver(NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap));
}else{ }else{
ATokenCreator * tok = NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap); ATokenCreator * tok = NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap);
@@ -451,7 +474,8 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
tok->resolve(); tok->resolve();
} }
delete tok; delete tok;
} }
}
result++; result++;
continue; continue;
} }
@@ -699,6 +723,10 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
dryModeResult = BAKA_EFFECT_GOOD; dryModeResult = BAKA_EFFECT_GOOD;
break; break;
} }
if (lordType == PARSER_FOREACH){
int multiplier = countCards(lordTargets);
game->mLayers->stackLayer()->addDraw(card->controller(),multiplier);;
}else{
if (trigger){ if (trigger){
DrawEvent * action = NEW DrawEvent(card->controller(),nbcards); DrawEvent * action = NEW DrawEvent(card->controller(),nbcards);
game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action)); game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action));
@@ -710,12 +738,13 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
game->mLayers->stackLayer()->addDraw(card->controller(),nbcards); game->mLayers->stackLayer()->addDraw(card->controller(),nbcards);
}else{ }else{
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap)); game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
} }
} }
} }
}
result++; result++;
continue; continue;
} }
//Deplete //Deplete
found = s.find("deplete:"); found = s.find("deplete:");
@@ -748,31 +777,20 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
} }
result++; result++;
continue; continue;
} }
//CannotBeBlockedBy //CannotBeBlockedBy
found = s.find("cantbeblockedby("); found = s.find("cantbeblockedby(");
if (found != string::npos){ if (found != string::npos){
int end = s.find(")",found+1); int end = s.find(")",found);
string starget = s.substr(found + 18,end - found - 18); string starget = s.substr(16, end - 16);
TargetChooserFactory tcf; TargetChooserFactory tcf;
tc = tcf.createTargetChooser(starget,card); tc = tcf.createTargetChooser(starget,card);
if (dryMode){ CantBlock(tc);
dryModeResult = BAKA_EFFECT_GOOD; result++;
break; continue;
} }
for (int i = 0; i < 2 ; i++){
for (int j = game->players[i]->game->inPlay->nb_cards-1; j >=0 ; j--){
MTGCardInstance * current = game->players[i]->game->inPlay->cards[j];
if (tc->canTarget(current)){
MTGCardInstance * canBlock = tc->source;
current->canBlock();
}
}
}
result++;
continue;
}
@@ -830,9 +848,9 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
dryModeResult = BAKA_EFFECT_GOOD; dryModeResult = BAKA_EFFECT_GOOD;
}else{ }else{
dryModeResult = BAKA_EFFECT_BAD; dryModeResult = BAKA_EFFECT_BAD;
} }
break; break;
} }
int MaxOpponent = atoi(s.substr(end+1,end+2).c_str()); int MaxOpponent = atoi(s.substr(end+1,end+2).c_str());
if(tc){ if(tc){
//TODO?? //TODO??
@@ -1080,10 +1098,8 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
} }
case 1094: //Ank Of Mishra case 1094: //Ank Of Mishra
{ {
// AAnkhOfMishra * ability = NEW AAnkhOfMishra(_id,card);
// game->addObserver(ability);
game->addObserver (NEW ALifeModifierPutinplay(_id,card,"land",-2,2,1)); game->addObserver (NEW ALifeModifierPutinplay(_id,card,"land",-2,2,1));
break; break;
} }
case 1095: //Armageddon clock case 1095: //Armageddon clock
{ {
@@ -1091,14 +1107,12 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
game->addObserver(ability); game->addObserver(ability);
break; break;
} }
case 1096: //Basalt Monolith case 1096: //Basalt Monolith
{ {
int cost[] = {Constants::MTG_COLOR_ARTIFACT, 3}; int cost[] = {Constants::MTG_COLOR_ARTIFACT, 3};
AManaProducer * ability = NEW AManaProducer(_id, card, NEW ManaCost(cost,1)); AManaProducer * ability = NEW AManaProducer(_id, card, NEW ManaCost(cost,1));
AUntapManaBlocker * ability2 = NEW AUntapManaBlocker(_id+1, 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)); AUnBlocker * ability3 = NEW AUnBlocker(_id+1, card,card, NEW ManaCost(cost,1));
game->addObserver(ability); game->addObserver(ability);
game->addObserver(ability2); game->addObserver(ability2);
game->addObserver(ability3); game->addObserver(ability3);
@@ -2116,16 +2130,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
//--- addon shm--- //--- addon shm---
case 153996: // Howl of the Night Pack
{
int x = card->controller()->game->inPlay->countByType("Forest");
ATokenCreator * tok = NEW ATokenCreator(id,card,NEW ManaCost(),"Wolf","Creature Wolf",2,2,"green",0);
for (int i=0; i < x-1; i++){
tok->resolve();
}
break;
}
case 147427: // Poison the Well case 147427: // Poison the Well
{ {
card->target->controller()->life-=2; card->target->controller()->life-=2;
@@ -2175,24 +2179,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
break; break;
} }
// --- addon Lorwynn---
case 139676: // Elvish Promenade
{
int x = card->controller()->game->inPlay->countByType("Elf");
ATokenCreator * tok = NEW ATokenCreator(id,card,NEW ManaCost(),"Elf Warrior","creature Elf Warrior",1,1,"green",0);
for (int i=0; i < x-1; i++){
tok->resolve();
}
break;
}
// --- addon Ravnica--- // --- addon Ravnica---
case 87978: // Flow of Ideas
{
int nbcards = card->controller()->game->inPlay->countByType("Island");
game->mLayers->stackLayer()->addDraw(card->controller(),nbcards);
break;
}
case 89114: //Psychic Drain case 89114: //Psychic Drain
{ {