- Triggers made more generic in the parser
This commit is contained in:
wagic.the.homebrew@gmail.com
2009-07-12 07:47:54 +00:00
parent 3350ad6d03
commit 0ecbfb5d82
9 changed files with 148 additions and 133 deletions
+28
View File
@@ -1305,6 +1305,23 @@ subtype=Human Barbarian
toughness=1 toughness=1
[/card] [/card]
[card] [card]
text=Lands you control have "{T}: Add one mana of any color to your mana pool."
auto=lord(land|myinplay) {T}: add{G}
auto=lord(land|myinplay) {T}: add{R}
auto=lord(land|myinplay) {T}: add{U}
auto=lord(land|myinplay) {T}: add{B}
auto=lord(land|myinplay) {T}: add{W}
id=130500
name=Joiner Adept
rarity=R
color=Green
type=Creature
mana={1}{G}
power=2
subtype=Elf Druid
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. 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 {1}
auto={T}:Add {R} && Damage 1 controller auto={T}:Add {R} && Damage 1 controller
@@ -2819,6 +2836,17 @@ subtype=Wolf
toughness=1 toughness=1
[/card] [/card]
[card] [card]
text=You may tap or untap target artifact, creature, or land. Draw a card.
auto=may untap target(artifact,creature,land)
auto=draw:1
id=136286
name=Twitch
rarity=C
color=Blue
type=Instant
mana={2}{U}
[/card]
[card]
text=Flash (You may play this spell any time you could play an instant.) Enchant creature (Target a creature as you play this. This card comes into play attached to that creature.) Enchanted creature gets +2/+2 and attacks each turn if able. text=Flash (You may play this spell any time you could play an instant.) Enchant creature (Target a creature as you play this. This card comes into play attached to that creature.) Enchanted creature gets +2/+2 and attacks each turn if able.
abilities=flash abilities=flash
target=creature target=creature
+2 -21
View File
@@ -494,18 +494,7 @@ color=Red
type=Instant type=Instant
mana={1}{R} mana={1}{R}
[/card] [/card]
[card]
text=Lands you control have "{T}: Add one mana of any color to your mana pool."
id=130500
name=Joiner Adept
rarity=R
color=Green
type=Creature
mana={1}{G}
power=2
subtype=Elf Druid
toughness=1
[/card]
[card] [card]
text=Karplusan Strider can't be the target of blue or black spells. text=Karplusan Strider can't be the target of blue or black spells.
id=129911 id=129911
@@ -1219,15 +1208,7 @@ color=Blue
type=Instant type=Instant
mana={U}{U} mana={U}{U}
[/card] [/card]
[card]
text=You may tap or untap target artifact, creature, or land. Draw a card.
id=136286
name=Twitch
rarity=C
color=Blue
type=Instant
mana={2}{U}
[/card]
[card] [card]
text=Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her. text=Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her.
id=129779 id=129779
+1 -11
View File
@@ -2098,17 +2098,7 @@ toughness=4
text=Flash (You may play this spell any time you could play an instant.) Creature cards you own that aren't in play have flash. Each opponent can play spells only any time he or she could play a sorcery. text=Flash (You may play this spell any time you could play an instant.) Creature cards you own that aren't in play have flash. Each opponent can play spells only any time he or she could play a sorcery.
rarity=R rarity=R
[/card] [/card]
[card]
id=111085
name=Telekinetic Sliver
mana={2}{U}{U}
type=Creature
subtype=Sliver
power=2
toughness=2
text=All Slivers have "{T}: Tap target permanent."
rarity=U
[/card]
[card] [card]
id=106654 id=106654
+1 -1
View File
@@ -149,4 +149,4 @@ zombify.txt
#Momir Basic Tests #Momir Basic Tests
######################## ########################
momir/keldon_warlord.txt momir/keldon_warlord.txt
momir/overcost.txt momir/overcost.txt
+1 -21
View File
@@ -126,17 +126,12 @@ public:
class MultiAbility:public ActivatedAbility{ class MultiAbility:public ActivatedAbility{
public: public:
vector<MTGAbility *> abilities; vector<MTGAbility *> abilities;
vector<TriggeredEvent *> events;
MultiAbility(int _id, MTGCardInstance * card,ManaCost * _cost, int _tap):ActivatedAbility(_id, card,_cost,0,_tap){ 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){ int Add(MTGAbility * ability){
abilities.push_back(ability); abilities.push_back(ability);
return 1; return 1;
@@ -147,10 +142,6 @@ public:
for (unsigned int i = 0; i < sz; i++){ for (unsigned int i = 0; i < sz; i++){
abilities[i]->resolve(); abilities[i]->resolve();
} }
sz = events.size();
for (unsigned int i = 0; i < sz; i++){
events[i]->resolve();
}
return 1; return 1;
} }
@@ -159,17 +150,6 @@ public:
for (unsigned int i = 0; i < sz; i++){ for (unsigned int i = 0; i < sz; i++){
delete abilities[i]; delete abilities[i];
} }
sz = events.size();
for (unsigned int i = 0; i < sz; i++){
delete events[i];
}
}
virtual ostream& toString(ostream& out) const
{
out << "MultiAbility ::: abilities : ?" // << abilities
<< " ; events : ?" // << events
<< " (";
return ActivatedAbility::toString(out) << ")";
} }
MultiAbility * clone() const{ MultiAbility * clone() const{
+18 -19
View File
@@ -157,7 +157,7 @@ class ListMaintainerAbility:public MTGAbility{
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
/* An attempt to globalize triggered abilities as much as possible */ /* An attempt to globalize triggered abilities as much as possible
class MTGAbilityBasicFeatures{ class MTGAbilityBasicFeatures{
public: public:
Targetable * target; Targetable * target;
@@ -168,32 +168,29 @@ class MTGAbilityBasicFeatures{
void init(MTGCardInstance * _source, Targetable * _target = NULL); void init(MTGCardInstance * _source, Targetable * _target = NULL);
}; };
class Trigger:public MTGAbilityBasicFeatures{ */
public:
virtual int trigger()=0;
virtual int testDestroy(){return 0;};
};
class TriggerAtPhase:public Trigger{ class TriggerAtPhase:public TriggeredAbility{
public: public:
int currentPhase, newPhase;
int phaseId; int phaseId;
TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId);
TriggerAtPhase(int _phaseId);
virtual int trigger(); virtual int trigger();
int resolve(){return 0;};
virtual TriggerAtPhase* clone() const;
}; };
class TriggerNextPhase:public TriggerAtPhase{ class TriggerNextPhase:public TriggerAtPhase{
public: public:
int destroyActivated; int destroyActivated;
TriggerNextPhase(int _phaseId); TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId);
virtual TriggerNextPhase* clone() const;
virtual int testDestroy(); virtual int testDestroy();
}; };
/*
class TriggeredEvent:public MTGAbilityBasicFeatures{ class TriggeredEvent:public MTGAbilityBasicFeatures{
public: public:
TriggeredEvent(); TriggeredEvent();
@@ -227,17 +224,19 @@ class DestroyCondition:public MTGAbilityBasicFeatures{
public: public:
virtual int testDestroy(); virtual int testDestroy();
}; };
*/
class GenericTriggeredAbility:public TriggeredAbility{ class GenericTriggeredAbility:public TriggeredAbility{
public: public:
Trigger * t; TriggeredAbility * t;
TriggeredEvent * te; MTGAbility * ability;
DestroyCondition * dc; MTGAbility * destroyCondition;
GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc = NULL, Targetable * _target = NULL); GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,MTGAbility * dc = NULL, Targetable * _target = NULL);
virtual int trigger(); virtual int trigger();
virtual int receiveEvent(WEvent * e);
virtual int resolve(); virtual int resolve();
virtual int testDestroy(); virtual int testDestroy();
void Update(float dt);
virtual GenericTriggeredAbility* clone() const; virtual GenericTriggeredAbility* clone() const;
~GenericTriggeredAbility(); ~GenericTriggeredAbility();
}; };
@@ -247,7 +246,7 @@ class AbilityFactory{
private: private:
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0); int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
int parsePowerToughness(string s, int *power, int *toughness); int parsePowerToughness(string s, int *power, int *toughness);
Trigger * parseTrigger(string magicText); TriggeredAbility * parseTrigger(string s, int id, Spell * spell, MTGCardInstance *card, Targetable * target);
MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0); MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0);
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY); int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY);
public: public:
+4 -3
View File
@@ -44,7 +44,7 @@ int ActionLayer::unstoppableRenderInProgress(){
bool ActionLayer::CheckUserInput(u32 key){ bool ActionLayer::CheckUserInput(u32 key){
GameObserver * g = GameObserver::GetInstance(); GameObserver * g = GameObserver::GetInstance();
if (g->waitForExtraPayment && key == PSP_CTRL_CROSS){ if (g->waitForExtraPayment && key == PSP_CTRL_CROSS){
game->waitForExtraPayment = NULL; g->waitForExtraPayment = NULL;
return 1; return 1;
} }
if (menuObject){ if (menuObject){
@@ -67,15 +67,16 @@ void ActionLayer::Update(float dt){
return; return;
} }
modal = 0; modal = 0;
GameObserver * g = GameObserver::GetInstance();
for (int i=mCount -1 ;i>=0;i--){ for (int i=mCount -1 ;i>=0;i--){
if (mObjects[i]!= NULL){ if (mObjects[i]!= NULL){
ActionElement * currentAction = (ActionElement *)mObjects[i]; ActionElement * currentAction = (ActionElement *)mObjects[i];
if (currentAction->testDestroy()){ if (currentAction->testDestroy()){
game->removeObserver(currentAction); g->removeObserver(currentAction);
} }
} }
} }
int newPhase = GameObserver::GetInstance()->getCurrentGamePhase(); int newPhase = g->getCurrentGamePhase();
for (int i=0;i<mCount;i++){ for (int i=0;i<mCount;i++){
if (mObjects[i]!=NULL){ if (mObjects[i]!=NULL){
ActionElement * currentAction = (ActionElement *)mObjects[i]; ActionElement * currentAction = (ActionElement *)mObjects[i];
+93 -55
View File
@@ -67,7 +67,7 @@ int AbilityFactory::parsePowerToughness(string s, int *power, int *toughness){
return 0; return 0;
} }
Trigger * AbilityFactory::parseTrigger(string magicText){ TriggeredAbility * AbilityFactory::parseTrigger(string magicText, int id, Spell * spell, MTGCardInstance *card, Targetable * target){
size_t found = magicText.find("@"); size_t found = magicText.find("@");
if (found == string::npos) return NULL; if (found == string::npos) return NULL;
@@ -77,7 +77,7 @@ Trigger * AbilityFactory::parseTrigger(string magicText){
for (int i = 0; i < Constants::NB_MTG_PHASES; i++){ for (int i = 0; i < Constants::NB_MTG_PHASES; i++){
found = magicText.find(Constants::MTGPhaseCodeNames[i]); found = magicText.find(Constants::MTGPhaseCodeNames[i]);
if (found != string::npos){ if (found != string::npos){
return NEW TriggerNextPhase(i); return NEW TriggerNextPhase(id, card,target,i);
} }
} }
} }
@@ -88,7 +88,7 @@ Trigger * AbilityFactory::parseTrigger(string magicText){
for (int i = 0; i < Constants::NB_MTG_PHASES; i++){ for (int i = 0; i < Constants::NB_MTG_PHASES; i++){
found = magicText.find(Constants::MTGPhaseCodeNames[i]); found = magicText.find(Constants::MTGPhaseCodeNames[i]);
if (found != string::npos){ if (found != string::npos){
return NEW TriggerAtPhase(i); return NEW TriggerAtPhase(id, card,target,i);
} }
} }
} }
@@ -110,6 +110,21 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
MTGCardInstance * target = card->target; MTGCardInstance * target = card->target;
if (!target) target = card; if (!target) target = card;
TriggeredAbility * trigger = NULL;
trigger = parseTrigger(s,id,spell,card,target);
//Dirty way to remove the trigger text (could get in the way)
if (trigger){
found = s.find(":");
string s1 = s.substr(found+1);
MTGAbility * a = parseMagicLine(s1, id, spell, card,activated);
if (!a){
delete trigger;
return NULL;
}
return NEW GenericTriggeredAbility(id,card,trigger,a,NULL,target);
}
int doTap = 0; //Tap in the cost ? int doTap = 0; //Tap in the cost ?
if (s.find("{t}") != string::npos) doTap = 1; if (s.find("{t}") != string::npos) doTap = 1;
@@ -193,13 +208,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return NEW MayAbility(id,a1,card); return NEW MayAbility(id,a1,card);
} }
Trigger * trigger = NULL;
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);
}
//Lord, foreach, aslongas //Lord, foreach, aslongas
@@ -330,13 +339,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
found = s.find(destroys[i]); found = s.find(destroys[i]);
if (found != string::npos){ if (found != string::npos){
int bury = destroyTypes[i]; int bury = destroyTypes[i];
if (trigger){ /*if (trigger){
if (bury){ if (bury){
BuryEvent * action = NEW BuryEvent(); BuryEvent * action = NEW BuryEvent();
return NEW GenericTriggeredAbility(id, card,trigger,action); return NEW GenericTriggeredAbility(id, card,trigger,action);
} }
return NULL; return NULL;
} }*/
MTGAbility * a = NEW AADestroyer(id,card,target,bury); MTGAbility * a = NEW AADestroyer(id,card,target,bury);
a->oneShot = 1; a->oneShot = 1;
return a; return a;
@@ -394,10 +403,10 @@ 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());
} }
if (trigger){ /*if (trigger){
DrawEvent * action = NEW DrawEvent(card->controller(),nbcards); DrawEvent * action = NEW DrawEvent(card->controller(),nbcards);
return NEW GenericTriggeredAbility(id, card,trigger,action); return NEW GenericTriggeredAbility(id, card,trigger,action);
} }*/
MTGAbility * a = NEW AADrawer(id,card,NULL,nbcards); MTGAbility * a = NEW AADrawer(id,card,NULL,nbcards);
a->oneShot = 1; a->oneShot = 1;
@@ -2328,7 +2337,7 @@ ostream& ListMaintainerAbility::toString(ostream& out) const
} }
/* An attempt to globalize triggered abilities as much as possible */ /* An attempt to globalize triggered abilities as much as possible
MTGAbilityBasicFeatures::MTGAbilityBasicFeatures(){ MTGAbilityBasicFeatures::MTGAbilityBasicFeatures(){
game = GameObserver::GetInstance(); game = GameObserver::GetInstance();
@@ -2343,35 +2352,6 @@ void MTGAbilityBasicFeatures::init(MTGCardInstance * _source, Targetable * _targ
if (!target) target = source; if (!target) target = source;
} }
TriggerAtPhase::TriggerAtPhase(int _phaseId):Trigger(),phaseId(_phaseId){
currentPhase = game->getCurrentGamePhase();
newPhase = game->getCurrentGamePhase();
}
int TriggerAtPhase::trigger(){
int result = 0;
newPhase = game->getCurrentGamePhase();
if (currentPhase != newPhase && newPhase == phaseId){
result = 1;
}
currentPhase = newPhase;
return result;
}
TriggerNextPhase::TriggerNextPhase(int _phaseId):TriggerAtPhase(_phaseId){
destroyActivated = 0;
}
int TriggerNextPhase::testDestroy(){
if (newPhase <= phaseId) destroyActivated = 1;
if ( newPhase > phaseId && destroyActivated){
return 1;
}
return 0;
}
TriggeredEvent::TriggeredEvent():MTGAbilityBasicFeatures(){} TriggeredEvent::TriggeredEvent():MTGAbilityBasicFeatures(){}
TriggeredEvent::TriggeredEvent(MTGCardInstance * _source, Targetable * _target):MTGAbilityBasicFeatures(_source, _target){} TriggeredEvent::TriggeredEvent(MTGCardInstance * _source, Targetable * _target):MTGAbilityBasicFeatures(_source, _target){}
@@ -2409,37 +2389,95 @@ int DestroyCondition::testDestroy(){
} }
return 0; return 0;
} }
*/
TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId):TriggeredAbility(id, source,target),phaseId(_phaseId){
GameObserver * g = GameObserver::GetInstance();
newPhase = g->getCurrentGamePhase();
currentPhase = newPhase;
}
int TriggerAtPhase::trigger(){
int result = 0;
if (currentPhase != newPhase && newPhase == phaseId){
result = 1;
}
return result;
}
GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc , Targetable * _target ): TriggeredAbility(id, _source,_target){ TriggerAtPhase* TriggerAtPhase::clone() const{
TriggerAtPhase * a = NEW TriggerAtPhase(*this);
a->isClone = 1;
return a;
}
TriggerNextPhase::TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId):TriggerAtPhase(id, source,target,_phaseId){
destroyActivated = 0;
}
int TriggerNextPhase::testDestroy(){
if (newPhase <= phaseId) destroyActivated = 1;
if ( newPhase > phaseId && destroyActivated){
return 1;
}
return 0;
}
TriggerNextPhase* TriggerNextPhase::clone() const{
TriggerNextPhase * a = NEW TriggerNextPhase(*this);
a->isClone = 1;
return a;
}
GenericTriggeredAbility::GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a , MTGAbility * dc, Targetable * _target ): TriggeredAbility(id, _source,_target){
if (!target) target = source; if (!target) target = source;
t = _t; t = _t;
te = _te; ability = a;
dc = _dc; destroyCondition = dc;
t->init(source,target); t->source = source;
te->init(source,target); t->target = target;
if (dc) dc->init(source,target); ability->source = source;
ability->target = target;
if (destroyCondition){
destroyCondition->source = source;
destroyCondition->target = target;;
}
} }
int GenericTriggeredAbility::trigger(){ int GenericTriggeredAbility::trigger(){
return t->trigger(); return t->trigger();
} }
int GenericTriggeredAbility::receiveEvent(WEvent * e){
if (t->receiveEvent(e)) return resolve();
return 0;
}
void GenericTriggeredAbility::Update(float dt){
GameObserver * g = GameObserver::GetInstance();
int newPhase = g->getCurrentGamePhase();
t->newPhase = newPhase;
TriggeredAbility::Update(dt);
t->currentPhase = newPhase;
}
int GenericTriggeredAbility::resolve(){ int GenericTriggeredAbility::resolve(){
return te->resolve(); return ability->resolve();
} }
int GenericTriggeredAbility::testDestroy(){ int GenericTriggeredAbility::testDestroy(){
if (dc) return dc->testDestroy(); if (destroyCondition) return destroyCondition->testDestroy();
return t->testDestroy(); return t->testDestroy();
} }
GenericTriggeredAbility::~GenericTriggeredAbility(){ GenericTriggeredAbility::~GenericTriggeredAbility(){
delete t; if (!isClone){
delete te; delete t;
SAFE_DELETE(dc); delete ability;
SAFE_DELETE(destroyCondition);
}
} }
GenericTriggeredAbility* GenericTriggeredAbility::clone() const{ GenericTriggeredAbility* GenericTriggeredAbility::clone() const{
-2
View File
@@ -432,12 +432,10 @@ HUDDisplay::~HUDDisplay(){
for (int i = 0; i < 2 ; i++){ for (int i = 0; i < 2 ; i++){
Player * p = game->players[i]; Player * p = game->players[i];
if (e->to == p->game->graveyard){ if (e->to == p->game->graveyard){
//p->game->putInZone(card, p->game->graveyard, card->owner->game->hand);
MTGCardInstance * copy = p->game->putInZone(e->card, p->game->graveyard, e->card->owner->game->stack); MTGCardInstance * copy = p->game->putInZone(e->card, p->game->graveyard, e->card->owner->game->stack);
Spell * spell = NEW Spell(copy); Spell * spell = NEW Spell(copy);
spell->resolve(); spell->resolve();
spell->source->counters->addCounter(-1,-1); spell->source->counters->addCounter(-1,-1);
game->mLayers->playLayer()->forceUpdateCards();
delete spell; delete spell;
return 1; return 1;
} }