Erwan
- Triggers made more generic in the parser
This commit is contained in:
@@ -1305,6 +1305,23 @@ subtype=Human Barbarian
|
||||
toughness=1
|
||||
[/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.
|
||||
auto={T}:Add {1}
|
||||
auto={T}:Add {R} && Damage 1 controller
|
||||
@@ -2819,6 +2836,17 @@ subtype=Wolf
|
||||
toughness=1
|
||||
[/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.
|
||||
abilities=flash
|
||||
target=creature
|
||||
|
||||
@@ -494,18 +494,7 @@ color=Red
|
||||
type=Instant
|
||||
mana={1}{R}
|
||||
[/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]
|
||||
text=Karplusan Strider can't be the target of blue or black spells.
|
||||
id=129911
|
||||
@@ -1219,15 +1208,7 @@ color=Blue
|
||||
type=Instant
|
||||
mana={U}{U}
|
||||
[/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]
|
||||
text=Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her.
|
||||
id=129779
|
||||
|
||||
@@ -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.
|
||||
rarity=R
|
||||
[/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]
|
||||
id=106654
|
||||
|
||||
@@ -149,4 +149,4 @@ zombify.txt
|
||||
#Momir Basic Tests
|
||||
########################
|
||||
momir/keldon_warlord.txt
|
||||
momir/overcost.txt
|
||||
momir/overcost.txt
|
||||
@@ -126,17 +126,12 @@ public:
|
||||
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;
|
||||
@@ -147,10 +142,6 @@ public:
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -159,17 +150,6 @@ public:
|
||||
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];
|
||||
}
|
||||
}
|
||||
virtual ostream& toString(ostream& out) const
|
||||
{
|
||||
out << "MultiAbility ::: abilities : ?" // << abilities
|
||||
<< " ; events : ?" // << events
|
||||
<< " (";
|
||||
return ActivatedAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
MultiAbility * clone() const{
|
||||
|
||||
@@ -157,7 +157,7 @@ class ListMaintainerAbility:public MTGAbility{
|
||||
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{
|
||||
public:
|
||||
Targetable * target;
|
||||
@@ -168,32 +168,29 @@ class MTGAbilityBasicFeatures{
|
||||
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:
|
||||
int currentPhase, newPhase;
|
||||
int phaseId;
|
||||
|
||||
TriggerAtPhase(int _phaseId);
|
||||
|
||||
TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId);
|
||||
virtual int trigger();
|
||||
int resolve(){return 0;};
|
||||
virtual TriggerAtPhase* clone() const;
|
||||
};
|
||||
|
||||
class TriggerNextPhase:public TriggerAtPhase{
|
||||
public:
|
||||
int destroyActivated;
|
||||
TriggerNextPhase(int _phaseId);
|
||||
|
||||
TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId);
|
||||
virtual TriggerNextPhase* clone() const;
|
||||
virtual int testDestroy();
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
class TriggeredEvent:public MTGAbilityBasicFeatures{
|
||||
public:
|
||||
TriggeredEvent();
|
||||
@@ -227,17 +224,19 @@ class DestroyCondition:public MTGAbilityBasicFeatures{
|
||||
public:
|
||||
virtual int testDestroy();
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
class GenericTriggeredAbility:public TriggeredAbility{
|
||||
public:
|
||||
Trigger * t;
|
||||
TriggeredEvent * te;
|
||||
DestroyCondition * dc;
|
||||
GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc = NULL, Targetable * _target = NULL);
|
||||
TriggeredAbility * t;
|
||||
MTGAbility * ability;
|
||||
MTGAbility * destroyCondition;
|
||||
GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,MTGAbility * dc = NULL, Targetable * _target = NULL);
|
||||
virtual int trigger();
|
||||
virtual int receiveEvent(WEvent * e);
|
||||
virtual int resolve();
|
||||
virtual int testDestroy();
|
||||
void Update(float dt);
|
||||
virtual GenericTriggeredAbility* clone() const;
|
||||
~GenericTriggeredAbility();
|
||||
};
|
||||
@@ -247,7 +246,7 @@ class AbilityFactory{
|
||||
private:
|
||||
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
|
||||
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);
|
||||
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY);
|
||||
public:
|
||||
|
||||
@@ -44,7 +44,7 @@ int ActionLayer::unstoppableRenderInProgress(){
|
||||
bool ActionLayer::CheckUserInput(u32 key){
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
if (g->waitForExtraPayment && key == PSP_CTRL_CROSS){
|
||||
game->waitForExtraPayment = NULL;
|
||||
g->waitForExtraPayment = NULL;
|
||||
return 1;
|
||||
}
|
||||
if (menuObject){
|
||||
@@ -67,15 +67,16 @@ void ActionLayer::Update(float dt){
|
||||
return;
|
||||
}
|
||||
modal = 0;
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
for (int i=mCount -1 ;i>=0;i--){
|
||||
if (mObjects[i]!= NULL){
|
||||
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
||||
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++){
|
||||
if (mObjects[i]!=NULL){
|
||||
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
||||
|
||||
@@ -67,7 +67,7 @@ int AbilityFactory::parsePowerToughness(string s, int *power, int *toughness){
|
||||
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("@");
|
||||
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++){
|
||||
found = magicText.find(Constants::MTGPhaseCodeNames[i]);
|
||||
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++){
|
||||
found = magicText.find(Constants::MTGPhaseCodeNames[i]);
|
||||
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;
|
||||
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 ?
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -330,13 +339,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
found = s.find(destroys[i]);
|
||||
if (found != string::npos){
|
||||
int bury = destroyTypes[i];
|
||||
if (trigger){
|
||||
/*if (trigger){
|
||||
if (bury){
|
||||
BuryEvent * action = NEW BuryEvent();
|
||||
return NEW GenericTriggeredAbility(id, card,trigger,action);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}*/
|
||||
MTGAbility * a = NEW AADestroyer(id,card,target,bury);
|
||||
a->oneShot = 1;
|
||||
return a;
|
||||
@@ -394,10 +403,10 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
nbcards = atoi(s.substr(start+1).c_str());
|
||||
}
|
||||
|
||||
if (trigger){
|
||||
/*if (trigger){
|
||||
DrawEvent * action = NEW DrawEvent(card->controller(),nbcards);
|
||||
return NEW GenericTriggeredAbility(id, card,trigger,action);
|
||||
}
|
||||
}*/
|
||||
|
||||
MTGAbility * a = NEW AADrawer(id,card,NULL,nbcards);
|
||||
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(){
|
||||
game = GameObserver::GetInstance();
|
||||
@@ -2343,35 +2352,6 @@ void MTGAbilityBasicFeatures::init(MTGCardInstance * _source, Targetable * _targ
|
||||
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(MTGCardInstance * _source, Targetable * _target):MTGAbilityBasicFeatures(_source, _target){}
|
||||
@@ -2409,37 +2389,95 @@ int DestroyCondition::testDestroy(){
|
||||
}
|
||||
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;
|
||||
t = _t;
|
||||
te = _te;
|
||||
dc = _dc;
|
||||
ability = a;
|
||||
destroyCondition = dc;
|
||||
|
||||
t->init(source,target);
|
||||
te->init(source,target);
|
||||
if (dc) dc->init(source,target);
|
||||
t->source = source;
|
||||
t->target = target;
|
||||
ability->source = source;
|
||||
ability->target = target;
|
||||
if (destroyCondition){
|
||||
destroyCondition->source = source;
|
||||
destroyCondition->target = target;;
|
||||
}
|
||||
}
|
||||
|
||||
int GenericTriggeredAbility::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(){
|
||||
return te->resolve();
|
||||
return ability->resolve();
|
||||
}
|
||||
|
||||
int GenericTriggeredAbility::testDestroy(){
|
||||
if (dc) return dc->testDestroy();
|
||||
if (destroyCondition) return destroyCondition->testDestroy();
|
||||
return t->testDestroy();
|
||||
}
|
||||
|
||||
GenericTriggeredAbility::~GenericTriggeredAbility(){
|
||||
delete t;
|
||||
delete te;
|
||||
SAFE_DELETE(dc);
|
||||
if (!isClone){
|
||||
delete t;
|
||||
delete ability;
|
||||
SAFE_DELETE(destroyCondition);
|
||||
}
|
||||
}
|
||||
|
||||
GenericTriggeredAbility* GenericTriggeredAbility::clone() const{
|
||||
|
||||
@@ -432,12 +432,10 @@ HUDDisplay::~HUDDisplay(){
|
||||
for (int i = 0; i < 2 ; i++){
|
||||
Player * p = game->players[i];
|
||||
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);
|
||||
Spell * spell = NEW Spell(copy);
|
||||
spell->resolve();
|
||||
spell->source->counters->addCounter(-1,-1);
|
||||
game->mLayers->playLayer()->forceUpdateCards();
|
||||
delete spell;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user