- Parser: Added possibility to add multiple abilities for one cost, using keyword && (see Ardakar wastes in 10E). Currently only works with mana and damage
- Added a dozen new cards
- Improved testing suite : new keyword "choice" to select an item in the abilities popup menu
This commit is contained in:
wagic.the.homebrew
2009-01-18 06:42:59 +00:00
parent e978a7d168
commit 9e314720e9
15 changed files with 723 additions and 546 deletions

View File

@@ -101,6 +101,17 @@ subtype=Angel
toughness=3
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {W} or {U} to your mana pool. Adarkar Wastes deals 1 damage to you.
auto={T}:Add {1}
auto={T}:Add {W} && Damage 1 controller
auto={T}:Add {B} && Damage 1 controller
id=129458
name=Adarkar Wastes
rarity=R
color=Land
type=Land
[/card]
[card]
text=Flying (This creature can't be blocked except by creatures with flying or reach.) Other black creatures get +1/+1. Nonblack creatures get -1/-1.
abilities=Legendary, flying
auto=lord(creature[black]) 1/1
@@ -127,6 +138,17 @@ type=Sorcery
mana={2}{B}
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {R} or {W} to your mana pool. Battlefield Forge deals 1 damage to you.
id=129479
auto={T}:Add {1}
auto={T}:Add {R} && Damage 1 controller
auto={T}:Add {W} && Damage 1 controller
name=Battlefield Forge
rarity=R
color=Land
type=Land
[/card]
[card]
text=Flash (You may play this spell any time you could play an instant.) First strike (This creature deals combat damage before creatures without first strike.)
abilities=flash,first strike
id=136279
@@ -189,6 +211,28 @@ type=Instant
mana={U}{U}
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {G} or {W} to your mana pool. Brushland deals 1 damage to you.
auto={T}:Add {1}
auto={T}:Add {G} && Damage 1 controller
auto={T}:Add {W} && Damage 1 controller
id=129496
name=Brushland
rarity=R
color=Land
type=Land
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {W} or {B} to your mana pool. Caves of Koilos deals 1 damage to you.
auto={T}:Add {1}
auto={T}:Add {W} && Damage 1 controller
auto={T}:Add {B} && Damage 1 controller
id=129497
name=Caves of Koilos
rarity=R
color=Land
type=Land
[/card]
[card]
text=Counter target spell.
alias=1196
id=129882
@@ -809,6 +853,17 @@ subtype=Human Barbarian
toughness=1
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {R} or {G} to your mana pool. Karplusan Forest deals 1 damage to you.
auto={T}:Add {1}
auto={T}:Add {R} && Damage 1 controller
auto={T}:Add {G} && Damage 1 controller
id=129614
name=Karplusan Forest
rarity=R
color=Land
type=Land
[/card]
[card]
text=When Kavu Climber comes into play, draw a card.
id=129511
name=Kavu Climber
@@ -859,6 +914,17 @@ subtype=Elf Druid
toughness=1
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {B} or {G} to your mana pool. Llanowar Wastes deals 1 damage to you.
id=129627
auto={T}:Add {1}
auto={T}:Add {B} && Damage 1 controller
auto={T}:Add {G} && Damage 1 controller
name=Llanowar Wastes
rarity=R
color=Land
type=Land
[/card]
[card]
text={B}: Looming Shade gets +1/+1 until end of turn.
auto={B}:1/1
id=129628
@@ -1547,6 +1613,17 @@ subtype=Dragon
toughness=5
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {U} or {R} to your mana pool. Shivan Reef deals 1 damage to you.
id=129731
auto={T}:Add {1}
auto={T}:Add {U} && Damage 1 controller
auto={T}:Add {R} && Damage 1 controller
name=Shivan Reef
rarity=R
color=Land
type=Land
[/card]
[card]
text=Shock deals 2 damage to target creature or player.
target=creature,player
auto=Damage:2
@@ -1712,6 +1789,17 @@ subtype=Human Rebel
toughness=2
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {B} or {R} to your mana pool. Sulfurous Springs deals 1 damage to you.
id=129751
auto={T}:Add {1}
auto={T}:Add {B} && Damage 1 controller
auto={T}:Add {R} && Damage 1 controller
name=Sulfurous Springs
rarity=R
color=Land
type=Land
[/card]
[card]
text=Flying (This creature can't be blocked except by creatures with flying or reach.)
abilities=flying
id=129753
@@ -1845,6 +1933,17 @@ subtype=Wolf
toughness=1
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {U} or {B} to your mana pool. Underground River deals 1 damage to you.
id=129778
auto={T}:Add {1}
auto={T}:Add {U} && Damage 1 controller
auto={T}:Add {B} && Damage 1 controller
name=Underground River
rarity=R
color=Land
type=Land
[/card]
[card]
text=Enchant creature (Target a creature as you play this. This card comes into play attached to that creature.) Enchanted creature gets +2/+1.
target=creature
auto=:2/1
@@ -1984,6 +2083,17 @@ type=Sorcery
mana={2}{W}{W}
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {G} or {U} to your mana pool. Yavimaya Coast deals 1 damage to you.
id=129810
auto={T}:Add {1}
auto={T}:Add {G} && Damage 1 controller
auto={T}:Add {U} && Damage 1 controller
name=Yavimaya Coast
rarity=R
color=Land
type=Land
[/card]
[card]
text=First strike (This creature deals combat damage before creatures without first strike.)
abilities=first strike
id=129790

View File

@@ -20,14 +20,6 @@ subtype=Human Wizard
toughness=2
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {W} or {U} to your mana pool. Adarkar Wastes deals 1 damage to you.
id=129458
name=Adarkar Wastes
rarity=R
color=Land
type=Land
[/card]
[card]
text=Look at target player's hand and choose two cards from it. Put them on top of that player's library in any order.
id=135228
name=Agonizing Memories
@@ -178,14 +170,6 @@ type=Instant
mana={W}
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {R} or {W} to your mana pool. Battlefield Forge deals 1 damage to you.
id=129479
name=Battlefield Forge
rarity=R
color=Land
type=Land
[/card]
[card]
text=Beacon of Destruction deals 5 damage to target creature or player. Shuffle Beacon of Destruction into its owner's library.
id=135262
name=Beacon of Destruction
@@ -271,22 +255,6 @@ subtype=Gnome
toughness=3
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {G} or {W} to your mana pool. Brushland deals 1 damage to you.
id=129496
name=Brushland
rarity=R
color=Land
type=Land
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {W} or {B} to your mana pool. Caves of Koilos deals 1 damage to you.
id=129497
name=Caves of Koilos
rarity=R
color=Land
type=Land
[/card]
[card]
text=Whenever Cephalid Constable deals combat damage to a player, return up to that many target permanents that player controls to their owners' hands.
id=135261
name=Cephalid Constable
@@ -945,14 +913,6 @@ subtype=Juggernaut
toughness=3
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {R} or {G} to your mana pool. Karplusan Forest deals 1 damage to you.
id=129614
name=Karplusan Forest
rarity=R
color=Land
type=Land
[/card]
[card]
text=Karplusan Strider can't be the target of blue or black spells.
id=129911
name=Karplusan Strider
@@ -1041,14 +1001,6 @@ subtype=Elf
toughness=3
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {B} or {G} to your mana pool. Llanowar Wastes deals 1 damage to you.
id=129627
name=Llanowar Wastes
rarity=R
color=Land
type=Land
[/card]
[card]
text=Equipped creature gets +3/+0 and has lifelink and trample. (When it deals damage, you gain that much life. If it would deal enough combat damage to its blockers to destroy them, you may have it deal the rest of its damage to defending player.) Equip {3} ({3}: Attach to target creature you control. Equip only as a sorcery.)
id=129630
name=Loxodon Warhammer
@@ -1645,14 +1597,6 @@ mana={U}
subtype=Aura
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {U} or {R} to your mana pool. Shivan Reef deals 1 damage to you.
id=129731
name=Shivan Reef
rarity=R
color=Land
type=Land
[/card]
[card]
text=Change the target of target spell with a single target.
id=130362
name=Shunt
@@ -1870,14 +1814,7 @@ color=Red
type=Instant
mana={3}{R}
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {B} or {R} to your mana pool. Sulfurous Springs deals 1 damage to you.
id=129751
name=Sulfurous Springs
rarity=R
color=Land
type=Land
[/card]
[card]
text=At the beginning of each player's upkeep, that player returns a creature he or she controls to its owner's hand.
id=129509
@@ -2077,14 +2014,6 @@ mana={2}{R}{R}
subtype=Aura
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {U} or {B} to your mana pool. Underground River deals 1 damage to you.
id=129778
name=Underground River
rarity=R
color=Land
type=Land
[/card]
[card]
text=Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her.
id=129779
name=Underworld Dreams
@@ -2212,14 +2141,6 @@ type=Artifact
mana={2}
[/card]
[card]
text={T}: Add {1} to your mana pool. {T}: Add {G} or {U} to your mana pool. Yavimaya Coast deals 1 damage to you.
id=129810
name=Yavimaya Coast
rarity=R
color=Land
type=Land
[/card]
[card]
text=Yavimaya Enchantress gets +1/+1 for each enchantment in play.
id=130515
name=Yavimaya Enchantress

View File

@@ -12,6 +12,32 @@ subtype=Imp
toughness=1
[/card]
[card]
text=Red creatures you control have first strike.
auto=lord(creature[red]|myinplay) first strike includeself
id=142062
name=Bloodmark Mentor
rarity=U
type=Creature
mana={1}{R}
power=1
subtype=Goblin Warrior
toughness=1
[/card]
[card]
text=Trample Other red creatures you control get +1/+1. Other green creatures you control get +1/+1.
abilities=trample
auto=lord(creature[red]|myinplay) 1/1
auto=lord(creature[green]|myinplay) 1/1
id=147428
name=Boartusk Liege
rarity=R
type=Creature
mana={1}{RG}{RG}{RG}
power=3
subtype=Goblin Knight
toughness=4
[/card]
[card]
text=Haste Wither (This deals damage to creatures in the form of -1/-1 counters.)
abilities=haste,wither
id=153970
@@ -37,6 +63,30 @@ subtype=Elemental Skeleton
toughness=1
[/card]
[card]
text=Black creatures you control have wither. (They deal damage to creatures in the form of -1/-1 counters.)
auto=lord(creature[black]|myinplay) wither includeself
id=142034
name=Corrosive Mentor
rarity=U
type=Creature
mana={2}{B}
power=1
subtype=Elemental Rogue
toughness=3
[/card]
[card]
text=Blue creatures you control are unblockable.
auto=lord(creature[blue]|myinplay) unblockable includeself
id=141981
name=Deepchannel Mentor
rarity=U
type=Creature
mana={5}{U}
power=2
subtype=Merfolk Rogue
toughness=2
[/card]
[card]
text={T}: Add {1} to your mana pool. {RG}, {T}: Add {R}{R}, {R}{G}, or {G}{G} to your mana pool.
auto={T}:Add{1}
auto={RG}{T}:Add{R}{R}
@@ -106,6 +156,20 @@ subtype=Treefolk Shaman
toughness=6
[/card]
[card]
text=Flying Other blue creatures you control get +1/+1. Other black creatures you control get +1/+1.
abilities=flying
auto=lord(creature[blue]|myinplay) 1/1
auto=lord(creature[black]|myinplay) 1/1
id=146743
name=Glen Elendra Liege
rarity=R
type=Creature
mana={1}{UB}{UB}{UB}
power=2
subtype=Faerie Knight
toughness=3
[/card]
[card]
text=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=persist
id=141935

View File

@@ -165,17 +165,6 @@ mana={2}
subtype=Equipment
[/card]
[card]
text=Red creatures you control have first strike.
id=142062
name=Bloodmark Mentor
rarity=U
type=Creature
mana={1}{R}
power=1
subtype=Goblin Warrior
toughness=1
[/card]
[card]
text=Enchant creature Enchanted creature attacks each turn if able.
id=159395
name=Bloodshed Fever
@@ -193,17 +182,6 @@ type=Enchantment
mana={2}{B}
[/card]
[card]
text=Trample Other red creatures you control get +1/+1. Other green creatures you control get +1/+1.
id=147428
name=Boartusk Liege
rarity=R
type=Creature
mana={1}{RG}{RG}{RG}
power=3
subtype=Goblin Knight
toughness=4
[/card]
[card]
text=Plainswalk {2}{R}, Sacrifice Boggart Arsonists: Destroy target Scarecrow or Plains.
id=158684
name=Boggart Arsonists
@@ -299,17 +277,6 @@ type=Instant
mana={2}{U}
[/card]
[card]
text=Black creatures you control have wither. (They deal damage to creatures in the form of -1/-1 counters.)
id=142034
name=Corrosive Mentor
rarity=U
type=Creature
mana={2}{B}
power=1
subtype=Elemental Rogue
toughness=3
[/card]
[card]
text=Corrupt deals damage equal to the number of Swamps you control to target creature or player. You gain life equal to the damage dealt this way.
id=146013
name=Corrupt
@@ -406,17 +373,6 @@ type=Sorcery
mana={X}{GW}
[/card]
[card]
text=Blue creatures you control are unblockable.
id=141981
name=Deepchannel Mentor
rarity=U
type=Creature
mana={5}{U}
power=2
subtype=Merfolk Rogue
toughness=2
[/card]
[card]
text=Deep-Slumber Titan comes into play tapped. Deep-Slumber Titan doesn't untap during your untap step. Whenever Deep-Slumber Titan is dealt damage, untap it.
id=159396
name=Deep-Slumber Titan
@@ -755,17 +711,6 @@ type=Sorcery
mana={1}{G}
[/card]
[card]
text=Flying Other blue creatures you control get +1/+1. Other black creatures you control get +1/+1.
id=146743
name=Glen Elendra Liege
rarity=R
type=Creature
mana={1}{UB}{UB}{UB}
power=2
subtype=Faerie Knight
toughness=3
[/card]
[card]
text=Destroy target creature. If that creature was green or white, its controller discards a card.
id=158757
name=Gloomlance

View File

@@ -15,6 +15,7 @@ afflict.txt
anarchy.txt
animate_dead.txt
animate_dead2.txt
ardakar_wastes.txt
ascendant_evincar.txt
ascendant_evincar2.txt
brass_man.txt

View File

@@ -0,0 +1,18 @@
#Testing Ardakar Wastes with multi
[INIT]
FIRSTMAIN
[PLAYER1]
inplay:129458
[PLAYER2]
[DO]
129458
choice 1
129458
[ASSERT]
FIRSTMAIN
[PLAYER1]
inplay:129458
manapool:{W}
life:19
[PLAYER2]
[END]

View File

@@ -30,6 +30,7 @@ class ActionLayer: public GuiLayer, public JGuiListener{
int reactToClick(MTGCardInstance * card);
void setMenuObject(Targetable * object);
void ButtonPressed(int controllerid, int controlid);
void doReactTo(int menuIndex);
TargetChooser * getCurrentTargetChooser();
};

View File

@@ -23,6 +23,51 @@ using std::map;
*/
//MultiAbility : triggers several actions for a cost
class MultiAbility:public ActivatedAbility{
public:
vector<MTGAbility *> abilities;
vector<TriggeredEvent *> events;
MultiAbility(int _id, MTGCardInstance * card,ManaCost * _cost, int _tap):ActivatedAbility(_id, card,_cost,0,_tap){
}
int Add(TriggeredEvent * event){
events.push_back(event);
return 1;
}
int Add(MTGAbility * ability){
abilities.push_back(ability);
return 1;
}
int resolve(){
vector<int>::size_type sz = abilities.size();
for (unsigned int i = 0; i < sz; i++){
abilities[i]->resolve();
}
sz = events.size();
for (unsigned int i = 0; i < sz; i++){
events[i]->resolve();
}
return 1;
}
~MultiAbility(){
vector<int>::size_type sz = abilities.size();
for (unsigned int i = 0; i < sz; i++){
delete abilities[i];
}
sz = events.size();
for (unsigned int i = 0; i < sz; i++){
delete events[i];
}
}
};
//Drawer, allows to draw a card for a cost:
class ADrawer:public ActivatedAbility{
@@ -627,7 +672,7 @@ class AManaProducer: public MTGAbility{
if (animation < 0){
animation = 0;
currentlyTapping--;
controller->getManaPool()->add(output);
resolve();
if (mParticleSys) mParticleSys->Stop();
}
}
@@ -653,6 +698,12 @@ class AManaProducer: public MTGAbility{
return result;
}
int resolve(){
controller = source->controller();
controller->getManaPool()->add(output);
return 1;
}
int reactToClick(MTGCardInstance * _card){
if (!isReactingToClick( _card)) return 0;
source->tapped = 1;
@@ -664,7 +715,7 @@ class AManaProducer: public MTGAbility{
x0 = cardg->x + 15;
y0 = cardg->y + 20;
}
controller = source->controller();
if (GameOptions::GetInstance()->values[OPTIONS_SFXVOLUME] > 0 && currentlyTapping < 3){
JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/mana.wav");

View File

@@ -147,6 +147,8 @@ class TriggerNextPhase:public TriggerAtPhase{
class TriggeredEvent:public MTGAbilityBasicFeatures{
public:
TriggeredEvent();
TriggeredEvent(MTGCardInstance * source, Damageable * target = NULL);
virtual int resolve()=0;
};
@@ -163,6 +165,15 @@ class BuryEvent: public TriggeredEvent{
int resolve();
};
class DamageEvent:public TriggeredEvent{
public:
int damage;
DamageEvent(MTGCardInstance * _source, Damageable * _target, int _damage);
int resolve();
};
class DestroyCondition:public MTGAbilityBasicFeatures{
public:
virtual int testDestroy();
@@ -189,6 +200,7 @@ class AbilityFactory{
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
int parsePowerToughness(string s, int *power, int *toughness);
Trigger * parseTrigger(string magicText);
Damageable * parseCollateralTarget(MTGCardInstance * card, string s);
public:
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
void addAbilities(int _id, Spell * spell);

View File

@@ -3,6 +3,8 @@
#if defined (WIN32) || defined (LINUX)
#define TESTSUITE 1
#else
#define OutputDebugString(val) {}
#endif
#if defined (_DEBUG) && defined (WIN32)

View File

@@ -176,10 +176,22 @@ void ActionLayer::setMenuObject(Targetable * object){
modal = 1;
}
void ActionLayer::doReactTo(int menuIndex){
if (menuObject){
int controlid = abilitiesMenu->mObjects[menuIndex]->GetId();
char buf[4096];
sprintf(buf, "doReact To %i\n",controlid);
OutputDebugString(buf);
ActionElement * currentAction = (ActionElement *)mObjects[controlid];
currentAction->reactToTargetClick(menuObject);
menuObject = 0;
}
}
void ActionLayer::ButtonPressed(int controllerid, int controlid){
if (controlid == -1){
}else{
ActionElement * currentAction = (ActionElement *)mObjects[controlid];
currentAction->reactToTargetClick(menuObject);

View File

@@ -321,9 +321,9 @@ void GameObserver::cardClick (MTGCardInstance * card, Targetable * object){
}
}else if (reaction){
if (reaction == 1){
mLayers->actionLayer()->reactToClick(card);
mLayers->actionLayer()->reactToClick(card);
}else{
mLayers->actionLayer()->setMenuObject(object);
mLayers->actionLayer()->setMenuObject(object);
}
}else if (card->isTapped() && card->controller() == currentPlayer){
// int a = ConstraintResolver::untap(this, card);

View File

@@ -9,8 +9,6 @@
#include "../include/MTGDeck.h"
int AbilityFactory::countCards(TargetChooser * tc, Player * player, int option){
int result = 0;
GameObserver * game = GameObserver::GetInstance();
@@ -60,6 +58,11 @@ int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone
return 1;
}
Damageable * AbilityFactory::parseCollateralTarget(MTGCardInstance * card, string s){
size_t found = s.find("controller");
if (found != string::npos) return card->controller();
return NULL;
}
int AbilityFactory::parsePowerToughness(string s, int *power, int *toughness){
size_t found = s.find("/");
@@ -118,7 +121,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
//An awful way to get access to the aliasedcard
magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText;
}
string s;
string line;
int size = magicText.size();
if (size == 0) return 0;
unsigned int found;
@@ -128,442 +131,465 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){
while (magicText.size()){
found = magicText.find("\n");
if (found != string::npos){
s = magicText.substr(0,found);
line = magicText.substr(0,found);
magicText = magicText.substr(found+1);
}else{
s = magicText;
line = magicText;
magicText = "";
}
#if defined (WIN32) || defined (LINUX)
char buf[4096];
sprintf(buf, "AUTO ACTION: %s\n", s.c_str());
sprintf(buf, "AUTO ACTION: %s\n", line.c_str());
OutputDebugString(buf);
#endif
TargetChooser * tc = NULL;
MultiAbility * multi = NULL;
int delimiter = line.find("}:");
ManaCost * cost = NULL;
if (delimiter!= string::npos){
cost = ManaCost::parseManaCost(line.substr(0,delimiter+1));
}
OutputDebugString("Pqrsing cost\n");
if (cost && !cost->getConvertedCost()){
OutputDebugString("Cost is null\n");
SAFE_DELETE(cost);
}
int doTap = 0;
TargetChooser * lordTargets = NULL;
int lordIncludeSelf = 0;
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 ?
if (s.find("{t}") != string::npos) doTap = 1;
if (line.find("{t}") != string::npos) doTap = 1;
//Target Abilities
found = s.find("target(");
if (found != string::npos){
int end = s.find(")");
string starget = s.substr(found + 7,end - found - 7);
TargetChooserFactory tcf;
tc = tcf.createTargetChooser(starget, card);
}
//Lord
found = s.find("lord(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
unsigned int end = s.find(")", found+5);
if (end != string::npos){
string lordType = s.substr(found+5,end-found-5).c_str();
TargetChooserFactory tcf;
lordTargets = tcf.createTargetChooser(lordType, card);
}
if (s.find("includeself") != string::npos) lordIncludeSelf = 1;
}
//foreach. Very basic, needs to be improved !
found = s.find("foreach(name:");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
unsigned int end = s.find(")", found+13);
if (end != string::npos){
string type = s.substr(found+13,end-found-13).c_str();
game->addObserver(NEW APlagueRats(id,card,type.c_str()));
result++;
continue;
}
}
//Untapper (Ley Druid...)
found = s.find("untap");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s);
if (tc){
game->addObserver(NEW AUntaper(id, card, cost, tc));
}else{
target->tapped = 0;
}
result++;
continue;
}
//Regeneration
found = s.find("}:regenerate");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s);
if (lordTargets){
game->addObserver(NEW ALord(id,card,lordTargets,lordIncludeSelf,0,0,-1,cost));
}else{
if (tc){
//TODO
}else{
game->addObserver(NEW AStandardRegenerate(id, card, target, cost));
//TODO death ward !
}
}
result++;
continue;
}
//Token creator. Name, type, p/t, abilities
found = s.find("token(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
int end = s.find(",", found);
string sname = s.substr(found + 6,end - found - 6);
int previous = end+1;
end = s.find(",",previous);
string stypes = s.substr(previous,end - previous);
previous = end+1;
end = s.find(",",previous);
string spt = s.substr(previous,end - previous);
int power, toughness;
parsePowerToughness(spt,&power, &toughness);
string sabilities = s.substr(end+1);
ManaCost * cost = ManaCost::parseManaCost(s);
int multiplier = 1;
found = s.find("*");
if (found != string::npos)multiplier = atoi(s.substr(found+1).c_str());
if(cost->getConvertedCost() || doTap){
game->addObserver(NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap));
}else{
delete cost;
cost = NULL;
ATokenCreator * tok = NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap);
for (int i=0; i < multiplier; i++){
tok->resolve();
}
delete tok;
}
result++;
continue;
}
//MoveTo Move a card from a zone to another
found = s.find("moveto(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_BAD; //TODO : depends on where from, where to...
int end = s.find(")");
string szone = s.substr(found + 7,end - found - 7);
if (tc){
ManaCost * cost = ManaCost::parseManaCost(s);
if (cost->getConvertedCost() == 0){
delete cost;
cost = NULL;
}
game->addObserver(NEW AZoneMover(id,card,tc,szone,cost));
}else{
MTGGameZone * fromZone = target->getCurrentZone();
MTGGameZone * destZone = MTGGameZone::stringToZone(szone, target);
target->controller()->game->putInZone(target,fromZone,destZone);
}
result++;
continue;
}
//Bury
found = s.find("bury");
if (found != string::npos){
if (trigger){
if (dryMode) return BAKA_EFFECT_BAD;
BuryEvent * action = NEW BuryEvent();
game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action));
}else{
found = s.find("all(");
if (found != string::npos){
int end = s.find(")");
string starget = s.substr(found + 4,end - found - 4);
TargetChooserFactory tcf;
TargetChooser * targetAll = tcf.createTargetChooser(starget, card);
if (dryMode){
int myNbCards = countCards(targetAll,card->controller());
int opponentNbCards = countCards(targetAll, card->controller()->opponent());
int myCardsPower = countCards(targetAll,card->controller(),COUNT_POWER);
int opponentCardsPower = countCards(targetAll, card->controller()->opponent(),COUNT_POWER);
delete targetAll;
if (myNbCards < opponentNbCards || myCardsPower < opponentCardsPower) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}else{
this->destroyAllInPlay(targetAll,1);
delete targetAll;
}
}else{
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ABurier(id, card,tc));
}else{
target->controller()->game->putInGraveyard(target);
}
}
}
result++;
continue;
}
//Destroy
found = s.find("destroy");
if (found != string::npos){
found = s.find("all(");
while (line.size()){
string s;
found = line.find("&&");
if (found != string::npos){
int end = s.find(")");
string starget = s.substr(found + 4,end - found - 4);
TargetChooserFactory tcf;
TargetChooser * targetAll = tcf.createTargetChooser(starget, card);
if (dryMode){
int myNbCards = countCards(targetAll,card->controller());
int opponentNbCards = countCards(targetAll, card->controller()->opponent());
int myCardsPower = countCards(targetAll,card->controller(),COUNT_POWER);
int opponentCardsPower = countCards(targetAll, card->controller()->opponent(),COUNT_POWER);
delete targetAll;
if (myNbCards < opponentNbCards || myCardsPower < opponentCardsPower) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}else{
this->destroyAllInPlay(targetAll);
delete targetAll;
}
s = line.substr(0,found);
line = line.substr(found+2);
if (!multi){
OutputDebugString("Multi initializing\n");
multi = NEW MultiAbility(id, card, cost,doTap);
game->addObserver(multi);
OutputDebugString("Multi initialized\n");
}
}else{
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ADestroyer(id, card,tc));
}else{
game->mLayers->stackLayer()->addPutInGraveyard(target);
}
s = line;
line = "";
}
result++;
continue;
}
//Damage
found = s.find("damage");
if (found != string::npos){
unsigned int start = s.find(":",found);
if (start == string::npos) start = s.find(" ",found);
unsigned int end = s.find(" ",start);
int damage;
ManaCost * cost = ManaCost::parseManaCost(s);
if (end != string::npos){
damage = atoi(s.substr(start+1,end-start-1).c_str());
}else{
damage = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ADamager(id, card, cost, damage, tc,doTap));
}else{
delete cost;
game->mLayers->stackLayer()->addDamage(card,spell->getNextDamageableTarget(), damage);
}
result++;
continue;
}
TargetChooser * tc = NULL;
//gain/lose life
found = s.find("life");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int life;
ManaCost * cost = ManaCost::parseManaCost(s);
if (end != string::npos){
life = atoi(s.substr(start+1,end-start-1).c_str());
}else{
life = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_GOOD;
if (tc){
//TODO ?
}else{
if (cost->getConvertedCost() == 0 && !doTap){
delete cost;
card->controller()->life+=life;
}else{
//TODO;
}
}
result++;
continue;
}
TargetChooser * lordTargets = NULL;
int lordIncludeSelf = 0;
//Draw
found = s.find("draw:");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int nbcards;
ManaCost * cost = ManaCost::parseManaCost(s);
if (end != string::npos){
nbcards = atoi(s.substr(start+1,end-start-1).c_str());
}else{
nbcards = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_GOOD;
Trigger * trigger = parseTrigger(s);
//Dirty way to remove the trigger text (could get in the way)
if (trigger){
DrawEvent * action = NEW DrawEvent(card->controller(),nbcards);
game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action));
}else{
if (tc){
//TODO ?
}else{
if (cost->getConvertedCost() == 0){
delete cost;
game->mLayers->stackLayer()->addDraw(card->controller(),nbcards);
}else{
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
}
}
found = s.find(":");
s = s.substr(found+1);
}
result++;
continue;
}
//Change Power/Toughness
int power, toughness;
if ( parsePowerToughness(s,&power, &toughness)){
if (dryMode){
if (power >=0 && toughness >= 0 ) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}
int limit = 0;
unsigned int limit_str = s.find("limit:");
if (limit_str != string::npos){
limit = atoi(s.substr(limit_str+6).c_str());
}
ManaCost * cost = ManaCost::parseManaCost(s);
if (lordTargets){
game->addObserver(NEW ALord(id,card,lordTargets,lordIncludeSelf,power,toughness));
}else{
if(tc){
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc));
}else{
if (cost->getConvertedCost() == 0){
delete cost;
if(card->hasType("enchantment")){
game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness));
}else{
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness));
}
//Target Abilities
found = s.find("target(");
if (found != string::npos){
int end = s.find(")");
string starget = s.substr(found + 7,end - found - 7);
TargetChooserFactory tcf;
tc = tcf.createTargetChooser(starget, card);
}
//Lord
found = s.find("lord(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
unsigned int end = s.find(")", found+5);
if (end != string::npos){
string lordType = s.substr(found+5,end-found-5).c_str();
TargetChooserFactory tcf;
lordTargets = tcf.createTargetChooser(lordType, card);
}
if (s.find("includeself") != string::npos) lordIncludeSelf = 1;
}
//foreach. Very basic, needs to be improved !
found = s.find("foreach(name:");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
unsigned int end = s.find(")", found+13);
if (end != string::npos){
string type = s.substr(found+13,end-found-13).c_str();
game->addObserver(NEW APlagueRats(id,card,type.c_str()));
result++;
continue;
}
}
//Untapper (Ley Druid...)
found = s.find("untap");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
if (tc){
game->addObserver(NEW AUntaper(id, card, cost, tc));
}else{
target->tapped = 0;
}
result++;
continue;
}
//Regeneration
found = s.find("}:regenerate");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
if (lordTargets){
game->addObserver(NEW ALord(id,card,lordTargets,lordIncludeSelf,0,0,-1,cost));
}else{
if (tc){
//TODO
}else{
game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit));
game->addObserver(NEW AStandardRegenerate(id, card, target, cost));
//TODO death ward !
}
}
}
result++;
continue;
}
//Mana Producer
found = s.find("add");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s.substr(0,found));
ManaCost * output = ManaCost::parseManaCost(s.substr(found));
if (cost->getConvertedCost()){
game->addObserver(NEW AManaProducer(id, target, output, cost));
}else{
delete cost;
if (doTap){
game->addObserver(NEW AManaProducer(id, target, output));
}else{
card->controller()->getManaPool()->add(output);
delete output;
}
}
result++;
continue;
}
//Gain/loose Ability
for (int j = 0; j < Constants::NB_BASIC_ABILITIES; j++){
found = s.find(Constants::MTGBasicAbilities[j]);
if (found!= string::npos){
int modifier = 1;
if (found > 0 && s[found-1] == '-') modifier = 0;
if (dryMode){
if (j == Constants::DEFENDER){
if (modifier == 1) return BAKA_EFFECT_BAD;
return BAKA_EFFECT_GOOD;
}else{
if (modifier == 1) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}
}
ManaCost * cost = ManaCost::parseManaCost(s);
if (lordTargets){
game->addObserver(NEW ALord(id,card,lordTargets,lordIncludeSelf,0,0,j));
}else{
if (tc){
game->addObserver(NEW ABasicAbilityModifierUntilEOT(id, card, j, cost,tc, modifier));
}else{
if (cost->getConvertedCost() == 0){
delete cost;
if(card->hasType("enchantment")){
game->addObserver(NEW ABasicAbilityModifier(id, card,target, j,modifier));
}else{
game->addObserver(NEW AInstantBasicAbilityModifierUntilEOT(id, card,target, j,modifier));
}
}else{
game->addObserver(NEW ABasicAbilityAuraModifierUntilEOT(id, card,target, cost,j,modifier));
}
}
}
result++;
continue;
}
result++;
continue;
}
//Tapper (icy manipulator)
found = s.find("tap");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * cost = ManaCost::parseManaCost(s);
if (tc){
game->addObserver(NEW ATapper(id, card, cost, tc));
}else{
target->tapped = 1;
//Token creator. Name, type, p/t, abilities
found = s.find("token(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
int end = s.find(",", found);
string sname = s.substr(found + 6,end - found - 6);
int previous = end+1;
end = s.find(",",previous);
string stypes = s.substr(previous,end - previous);
previous = end+1;
end = s.find(",",previous);
string spt = s.substr(previous,end - previous);
int power, toughness;
parsePowerToughness(spt,&power, &toughness);
string sabilities = s.substr(end+1);
int multiplier = 1;
found = s.find("*");
if (found != string::npos)multiplier = atoi(s.substr(found+1).c_str());
if(cost || doTap){
game->addObserver(NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap));
}else{
ATokenCreator * tok = NEW ATokenCreator(id,card,cost,sname,stypes,power,toughness,sabilities,doTap);
for (int i=0; i < multiplier; i++){
tok->resolve();
}
delete tok;
}
result++;
continue;
}
result++;
continue;
}
//MoveTo Move a card from a zone to another
found = s.find("moveto(");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_BAD; //TODO : depends on where from, where to...
int end = s.find(")");
string szone = s.substr(found + 7,end - found - 7);
if (tc){
if (cost){
game->addObserver(NEW AZoneMover(id,card,tc,szone,cost));
}
}else{
MTGGameZone * fromZone = target->getCurrentZone();
MTGGameZone * destZone = MTGGameZone::stringToZone(szone, target);
target->controller()->game->putInZone(target,fromZone,destZone);
}
result++;
continue;
}
//Bury
found = s.find("bury");
if (found != string::npos){
if (trigger){
if (dryMode) return BAKA_EFFECT_BAD;
BuryEvent * action = NEW BuryEvent();
game->addObserver(NEW GenericTriggeredAbility(id, card,trigger,action));
}else{
found = s.find("all(");
if (found != string::npos){
int end = s.find(")");
string starget = s.substr(found + 4,end - found - 4);
TargetChooserFactory tcf;
TargetChooser * targetAll = tcf.createTargetChooser(starget, card);
if (dryMode){
int myNbCards = countCards(targetAll,card->controller());
int opponentNbCards = countCards(targetAll, card->controller()->opponent());
int myCardsPower = countCards(targetAll,card->controller(),COUNT_POWER);
int opponentCardsPower = countCards(targetAll, card->controller()->opponent(),COUNT_POWER);
delete targetAll;
if (myNbCards < opponentNbCards || myCardsPower < opponentCardsPower) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}else{
this->destroyAllInPlay(targetAll,1);
delete targetAll;
}
}else{
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ABurier(id, card,tc));
}else{
target->controller()->game->putInGraveyard(target);
}
}
}
result++;
continue;
}
//Destroy
found = s.find("destroy");
if (found != string::npos){
found = s.find("all(");
if (found != string::npos){
int end = s.find(")");
string starget = s.substr(found + 4,end - found - 4);
TargetChooserFactory tcf;
TargetChooser * targetAll = tcf.createTargetChooser(starget, card);
if (dryMode){
int myNbCards = countCards(targetAll,card->controller());
int opponentNbCards = countCards(targetAll, card->controller()->opponent());
int myCardsPower = countCards(targetAll,card->controller(),COUNT_POWER);
int opponentCardsPower = countCards(targetAll, card->controller()->opponent(),COUNT_POWER);
delete targetAll;
if (myNbCards < opponentNbCards || myCardsPower < opponentCardsPower) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}else{
this->destroyAllInPlay(targetAll);
delete targetAll;
}
}else{
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
game->addObserver(NEW ADestroyer(id, card,tc));
}else{
game->mLayers->stackLayer()->addPutInGraveyard(target);
}
}
result++;
continue;
}
//Damage
found = s.find("damage");
if (found != string::npos){
unsigned int start = s.find(":",found);
if (start == string::npos) start = s.find(" ",found);
unsigned int end = s.find(" ",start);
int damage;
if (end != string::npos){
damage = atoi(s.substr(start+1,end-start-1).c_str());
}else{
damage = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_BAD;
if (tc){
MTGAbility * a = NEW ADamager(id, card, cost, damage, tc,doTap);
if (multi){
multi->Add(a);
}else{
game->addObserver(a);
}
}else{
if (multi){
Damageable * target = parseCollateralTarget(card, s);
if (!target) target = spell->getNextDamageableTarget();
if (!target)OutputDebugString("NO TARGET FOR DAMAGE\n");
multi->Add(NEW DamageEvent(card,target,damage));
}else{
game->mLayers->stackLayer()->addDamage(card,spell->getNextDamageableTarget(), damage);
}
}
result++;
continue;
}
//gain/lose life
found = s.find("life");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int life;
if (end != string::npos){
life = atoi(s.substr(start+1,end-start-1).c_str());
}else{
life = atoi(s.substr(start+1).c_str());
}
if (dryMode) return BAKA_EFFECT_GOOD;
if (tc){
//TODO ?
}else{
if (!cost && !doTap){
card->controller()->life+=life;
}else{
//TODO;
}
}
result++;
continue;
}
//Draw
found = s.find("draw:");
if (found != string::npos){
unsigned int start = s.find(":",found);
unsigned int end = s.find(" ",start);
int nbcards;
if (end != string::npos){
nbcards = atoi(s.substr(start+1,end-start-1).c_str());
}else{
nbcards = atoi(s.substr(start+1).c_str());
}
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){
//TODO ?
}else{
if (!cost){
game->mLayers->stackLayer()->addDraw(card->controller(),nbcards);
}else{
game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap));
}
}
}
result++;
continue;
}
//Change Power/Toughness
int power, toughness;
if ( parsePowerToughness(s,&power, &toughness)){
if (dryMode){
if (power >=0 && toughness >= 0 ) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}
int limit = 0;
unsigned int limit_str = s.find("limit:");
if (limit_str != string::npos){
limit = atoi(s.substr(limit_str+6).c_str());
}
if (lordTargets){
game->addObserver(NEW ALord(id,card,lordTargets,lordIncludeSelf,power,toughness));
}else{
if(tc){
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc));
}else{
if (!cost){
if(card->hasType("enchantment")){
game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness));
}else{
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness));
}
}else{
game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit));
}
}
}
result++;
continue;
}
//Mana Producer
found = s.find("add");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
ManaCost * input = ManaCost::parseManaCost(s.substr(0,found));
ManaCost * output = ManaCost::parseManaCost(s.substr(found));
if (input->getConvertedCost() || doTap){
SAFE_DELETE(cost); //erk
if (!input->getConvertedCost()){
SAFE_DELETE(input);
}
MTGAbility * a = NEW AManaProducer(id, target, output, input);
if (multi){
multi->Add(a);
}else{
game->addObserver(a);
}
}else{
OutputDebugString ("uh oh\n");
card->controller()->getManaPool()->add(output);
delete output;
}
result++;
continue;
}
//Gain/loose Ability
for (int j = 0; j < Constants::NB_BASIC_ABILITIES; j++){
found = s.find(Constants::MTGBasicAbilities[j]);
if (found!= string::npos){
int modifier = 1;
if (found > 0 && s[found-1] == '-') modifier = 0;
if (dryMode){
if (j == Constants::DEFENDER){
if (modifier == 1) return BAKA_EFFECT_BAD;
return BAKA_EFFECT_GOOD;
}else{
if (modifier == 1) return BAKA_EFFECT_GOOD;
return BAKA_EFFECT_BAD;
}
}
if (lordTargets){
game->addObserver(NEW ALord(id,card,lordTargets,lordIncludeSelf,0,0,j));
}else{
if (tc){
game->addObserver(NEW ABasicAbilityModifierUntilEOT(id, card, j, cost,tc, modifier));
}else{
if (!cost){
if(card->hasType("enchantment")){
game->addObserver(NEW ABasicAbilityModifier(id, card,target, j,modifier));
}else{
game->addObserver(NEW AInstantBasicAbilityModifierUntilEOT(id, card,target, j,modifier));
}
}else{
game->addObserver(NEW ABasicAbilityAuraModifierUntilEOT(id, card,target, cost,j,modifier));
}
}
}
result++;
continue;
}
}
//Tapper (icy manipulator)
found = s.find("tap");
if (found != string::npos){
if (dryMode) return BAKA_EFFECT_GOOD;
if (tc){
game->addObserver(NEW ATapper(id, card, cost, tc));
}else{
target->tapped = 1;
}
result++;
continue;
}
#if defined (WIN32) || defined (LINUX)
char buf[4096];
sprintf(buf, "AUTO ACTION PARSED: %s\n", line.c_str());
OutputDebugString(buf);
#endif
}
}
return result;
}
void AbilityFactory::addAbilities(int _id, Spell * spell){
@@ -1853,8 +1879,17 @@ int TriggerNextPhase::testDestroy(){
return 0;
}
TriggeredEvent::TriggeredEvent():MTGAbilityBasicFeatures(){}
TriggeredEvent::TriggeredEvent(MTGCardInstance * _source, Damageable * _target):MTGAbilityBasicFeatures(_source, _target){}
DamageEvent::DamageEvent(MTGCardInstance * _source, Damageable * _target, int _damage):TriggeredEvent(_source,_target),damage(_damage){
}
int DamageEvent::resolve(){
game->mLayers->stackLayer()->addDamage(source,target, damage);
return damage;
}
DrawEvent::DrawEvent(Player * _player, int _nbcards):TriggeredEvent(),player(_player),nbcards(_nbcards){
}

View File

@@ -206,6 +206,7 @@ Player * MTGCardInstance::controller(){
if (game->players[i]->game->inPlay->hasCard(this)) return game->players[i];
if (game->players[i]->game->stack->hasCard(this)) return game->players[i];
if (game->players[i]->game->graveyard->hasCard(this)) return game->players[i];
if (game->players[i]->game->hand->hasCard(this)) return game->players[i];
}
return NULL;
}

View File

@@ -83,6 +83,10 @@ int TestSuiteAI::Act(float dt){
if (g->mLayers->stackLayer()->askIfWishesToInterrupt == this){
g->mLayers->stackLayer()->cancelInterruptOffer();
}
}else if(action.find("choice ")!=string::npos){
OutputDebugString("choice !!!\n");
int choice = atoi(action.substr(action.find("choice ") + 7).c_str());
g->mLayers->actionLayer()->doReactTo(choice);
}else{
int mtgid = atoi(action.c_str());
if (mtgid){
@@ -92,7 +96,7 @@ int TestSuiteAI::Act(float dt){
}else{
MTGCardInstance * card = suite->getCardByMTGId(mtgid);
if (card) {
g->cardClick(card);
g->cardClick(card,card);
}
}
}else{