Merge pull request #651 from kevlahnota/master
added trigger keyword/s to parse current opponent and current controller correctly
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -187,6 +187,13 @@ power=1
|
|||||||
toughness=1
|
toughness=1
|
||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
|
name=Aladdin's Lamp
|
||||||
|
alias=1092
|
||||||
|
text={X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0.
|
||||||
|
mana={10}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
name=Alive // Well
|
name=Alive // Well
|
||||||
text=Put a 3/3 green Centaur creature token onto the battlefield. -- // -- You gain 2 life for each creature you control. -- -- Fuse (You may cast one or both halves of this card from your hand.)
|
text=Put a 3/3 green Centaur creature token onto the battlefield. -- // -- You gain 2 life for each creature you control. -- -- Fuse (You may cast one or both halves of this card from your hand.)
|
||||||
mana={3}{G} // {W}
|
mana={3}{G} // {W}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#Hypnotic Specter vs Control Magic
|
||||||
|
#The opponent of the current controller of Hypnotic Specter
|
||||||
|
#Must discard at random when combat damage is dealt...
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
hand:Control Magic
|
||||||
|
inplay:Concordant Crossroads
|
||||||
|
manapool:{B}{B}{U}{U}
|
||||||
|
[PLAYER2]
|
||||||
|
inplay:Hypnotic Specter
|
||||||
|
hand:Forest
|
||||||
|
[DO]
|
||||||
|
Control Magic
|
||||||
|
Hypnotic Specter
|
||||||
|
next
|
||||||
|
next
|
||||||
|
Hypnotic Specter
|
||||||
|
next
|
||||||
|
eot
|
||||||
|
[ASSERT]
|
||||||
|
UNTAP
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:Control Magic, Hypnotic Specter, Concordant Crossroads
|
||||||
|
[PLAYER2]
|
||||||
|
graveyard:Forest
|
||||||
|
life:18
|
||||||
|
[END]
|
||||||
@@ -311,6 +311,7 @@ evil_presence3.txt
|
|||||||
evil_presence_i647.txt
|
evil_presence_i647.txt
|
||||||
evil_presence_i647_2.txt
|
evil_presence_i647_2.txt
|
||||||
exaltedsourcekilled.txt
|
exaltedsourcekilled.txt
|
||||||
|
ExchangeController.txt
|
||||||
executioners_swing.txt
|
executioners_swing.txt
|
||||||
executioners_swing2.txt
|
executioners_swing2.txt
|
||||||
executioners_swing3.txt
|
executioners_swing3.txt
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
#DESC: Tests whether Curiosity works correctly
|
#DESC: Tests whether Curiosity works correctly
|
||||||
#DESC: when cast on an opponent's creature
|
#DESC: when cast on an opponent's creature
|
||||||
#DESC: http://code.google.com/p/wagic/issues/detail?id=217
|
#DESC: http://code.google.com/p/wagic/issues/detail?id=217
|
||||||
|
#
|
||||||
|
#revised...10-22-2015...kevlahnota
|
||||||
|
#2/1/2007 You draw one card each time the enchanted creature damages the opponent. This is not one card per point of damage.
|
||||||
|
#2/1/2007 If put on your opponent's creature, you do not draw a card when that creature damages you. The creature has to damage your opponent in order to have this work.
|
||||||
|
#2/1/2007 Drawing a card is optional. If you forget, you can't go back later and do it, even if it is something you normally do.
|
||||||
|
#9/22/2011 "You" refers to the controller of Curiosity, which may be different from the controller of the enchanted creature."An opponent" refers to an opponent of Curiosity's controller.
|
||||||
|
#9/22/2011 Any damage dealt by the enchanted creature to an opponent will cause Curiosity to trigger, not just combat damage.
|
||||||
|
#9/22/2011 Curiosity doesn't trigger if the enchanted creature deals damage to a planeswalker controlled by an opponent.
|
||||||
|
#
|
||||||
[INIT]
|
[INIT]
|
||||||
firstmain
|
firstmain
|
||||||
[PLAYER1]
|
[PLAYER1]
|
||||||
@@ -29,7 +38,7 @@ next
|
|||||||
combatend
|
combatend
|
||||||
[PLAYER1]
|
[PLAYER1]
|
||||||
inplay:Curiosity
|
inplay:Curiosity
|
||||||
hand:Island
|
library:Island
|
||||||
life:14
|
life:14
|
||||||
[PLAYER2]
|
[PLAYER2]
|
||||||
inplay:Craw Wurm
|
inplay:Craw Wurm
|
||||||
|
|||||||
@@ -1196,9 +1196,9 @@ public:
|
|||||||
class TrcardDrawn: public Trigger
|
class TrcardDrawn: public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool thiscontroller, thisopponent;
|
||||||
TrcardDrawn(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc,bool once = false) :
|
TrcardDrawn(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc,bool once = false, bool thiscontroller = false, bool thisopponent = false) :
|
||||||
Trigger(observer, id, source,once, tc)
|
Trigger(observer, id, source,once, tc),thiscontroller(thiscontroller),thisopponent(thisopponent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1207,7 +1207,12 @@ public:
|
|||||||
WEventcardDraw * e = dynamic_cast<WEventcardDraw *> (event);
|
WEventcardDraw * e = dynamic_cast<WEventcardDraw *> (event);
|
||||||
if (!e) return 0;
|
if (!e) return 0;
|
||||||
if (!tc->canTarget(e->player)) return 0;
|
if (!tc->canTarget(e->player)) return 0;
|
||||||
|
if(thiscontroller)
|
||||||
|
if(e->player != source->controller())
|
||||||
|
return 0;
|
||||||
|
if(thisopponent)
|
||||||
|
if(e->player == source->controller())
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,8 +1300,10 @@ public:
|
|||||||
bool sourceUntapped;
|
bool sourceUntapped;
|
||||||
bool limitOnceATurn;
|
bool limitOnceATurn;
|
||||||
int triggeredTurn;
|
int triggeredTurn;
|
||||||
TrDamaged(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool limitOnceATurn = false,bool once = false) :
|
bool thiscontroller;
|
||||||
Trigger(observer, id, source, once, tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped),limitOnceATurn(limitOnceATurn)
|
bool thisopponent;
|
||||||
|
TrDamaged(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool limitOnceATurn = false,bool once = false, bool thiscontroller = false, bool thisopponent = false) :
|
||||||
|
Trigger(observer, id, source, once, tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped),limitOnceATurn(limitOnceATurn),thiscontroller(thiscontroller),thisopponent(thisopponent)
|
||||||
{
|
{
|
||||||
triggeredTurn = -1;
|
triggeredTurn = -1;
|
||||||
}
|
}
|
||||||
@@ -1313,6 +1320,15 @@ public:
|
|||||||
if (fromTc && !fromTc->canTarget(e->damage->source)) return 0;
|
if (fromTc && !fromTc->canTarget(e->damage->source)) return 0;
|
||||||
if (type == 1 && e->damage->typeOfDamage != Damage::DAMAGE_COMBAT) return 0;
|
if (type == 1 && e->damage->typeOfDamage != Damage::DAMAGE_COMBAT) return 0;
|
||||||
if (type == 2 && e->damage->typeOfDamage == Damage::DAMAGE_COMBAT) return 0;
|
if (type == 2 && e->damage->typeOfDamage == Damage::DAMAGE_COMBAT) return 0;
|
||||||
|
if (e->damage->target->type_as_damageable == Damageable::DAMAGEABLE_PLAYER)
|
||||||
|
{
|
||||||
|
if(thiscontroller)
|
||||||
|
if(e->damage->target != (Damageable *)source->controller())
|
||||||
|
return 0;
|
||||||
|
if(thisopponent)
|
||||||
|
if(e->damage->target == (Damageable *)source->controller())
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
e->damage->target->thatmuch = e->damage->damage;
|
e->damage->target->thatmuch = e->damage->damage;
|
||||||
e->damage->source->thatmuch = e->damage->damage;
|
e->damage->source->thatmuch = e->damage->damage;
|
||||||
this->source->thatmuch = e->damage->damage;
|
this->source->thatmuch = e->damage->damage;
|
||||||
@@ -1337,9 +1353,9 @@ class TrLifeGained: public Trigger
|
|||||||
public:
|
public:
|
||||||
TargetChooser * fromTc;
|
TargetChooser * fromTc;
|
||||||
int type;//this allows damagenoncombat and combatdamage to share this trigger
|
int type;//this allows damagenoncombat and combatdamage to share this trigger
|
||||||
bool sourceUntapped;
|
bool sourceUntapped, thiscontroller, thisopponent;
|
||||||
TrLifeGained(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool once = false) :
|
TrLifeGained(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool once = false, bool thiscontroller = false, bool thisopponent = false) :
|
||||||
Trigger(observer, id, source, once , tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped)
|
Trigger(observer, id, source, once , tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped) , thiscontroller(thiscontroller) , thisopponent(thisopponent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1353,6 +1369,12 @@ public:
|
|||||||
if (fromTc && !fromTc->canTarget(e->player)) return 0;
|
if (fromTc && !fromTc->canTarget(e->player)) return 0;
|
||||||
if (type == 1 && (e->amount > 0)) return 0;
|
if (type == 1 && (e->amount > 0)) return 0;
|
||||||
if (type == 0 && (e->amount < 0)) return 0;
|
if (type == 0 && (e->amount < 0)) return 0;
|
||||||
|
if(thiscontroller)
|
||||||
|
if(e->player != source->controller())
|
||||||
|
return 0;
|
||||||
|
if(thisopponent)
|
||||||
|
if(e->player == source->controller())
|
||||||
|
return 0;
|
||||||
e->player->thatmuch = abs(e->amount);
|
e->player->thatmuch = abs(e->amount);
|
||||||
this->source->thatmuch = abs(e->amount);
|
this->source->thatmuch = abs(e->amount);
|
||||||
|
|
||||||
|
|||||||
@@ -825,7 +825,16 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
|
|||||||
attackingTrigger,attackedAloneTrigger,notBlockedTrigger,attackBlockedTrigger,blockingTrigger);
|
attackingTrigger,attackedAloneTrigger,notBlockedTrigger,attackBlockedTrigger,blockingTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Card card is drawn
|
|
||||||
|
//drawn player - controller of card - dynamic version drawof(player) -> returns current controller even with exchange of card controller
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "drawof", card))
|
||||||
|
return NEW TrcardDrawn(observer, id, card, tc,once,true,false);
|
||||||
|
|
||||||
|
//drawn player - opponent of card controller - dynamic version drawfoeof(player) -> returns current opponent even with exchange of card controller
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "drawfoeof", card))
|
||||||
|
return NEW TrcardDrawn(observer, id, card, tc,once,false,true);
|
||||||
|
|
||||||
|
//Card card is drawn - static version - drawn(player) - any player; drawn(controller) - owner forever; drawn(opponent) - opponent forever
|
||||||
if (TargetChooser * tc = parseSimpleTC(s, "drawn", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "drawn", card))
|
||||||
return NEW TrcardDrawn(observer, id, card, tc,once);
|
return NEW TrcardDrawn(observer, id, card, tc,once);
|
||||||
|
|
||||||
@@ -841,35 +850,105 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
|
|||||||
if (TargetChooser * tc = parseSimpleTC(s, "cycled", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "cycled", card))
|
||||||
return NEW TrCardDiscarded(observer, id, card, tc,once,true);
|
return NEW TrCardDiscarded(observer, id, card, tc,once,true);
|
||||||
|
|
||||||
//Card Damaging non combat
|
//Card Damaging non combat current controller
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamageof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 2,false,false,once,true,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Card Damaging non combat current opponent
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamagefoeof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 2,false,false,once,false,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Card Damaging non combat static
|
||||||
if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamaged", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamaged", card))
|
||||||
{
|
{
|
||||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
return NEW TrDamaged(observer, id, card, tc, fromTc, 2,once);
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 2,once);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Card Damaging combat
|
//Card Damaging combat current controller
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "combatdamageof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 1,sourceUntapped,limitOnceATurn,once,true,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Card Damaging combat current opponent
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "combatdamagefoeof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 1,sourceUntapped,limitOnceATurn,once,false,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Card Damaging combat static
|
||||||
if (TargetChooser * tc = parseSimpleTC(s, "combatdamaged", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "combatdamaged", card))
|
||||||
{
|
{
|
||||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
return NEW TrDamaged(observer, id, card, tc, fromTc, 1,sourceUntapped,limitOnceATurn,once);
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 1,sourceUntapped,limitOnceATurn,once);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Card Damaging
|
//Card Damaging current controller
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "damageof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 0,sourceUntapped,limitOnceATurn,once,true,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Card Damaging current opponent
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "damagefoeof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 0,sourceUntapped,limitOnceATurn,once,false,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Card Damaging static
|
||||||
if (TargetChooser * tc = parseSimpleTC(s, "damaged", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "damaged", card))
|
||||||
{
|
{
|
||||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
return NEW TrDamaged(observer, id, card, tc, fromTc, 0,sourceUntapped,limitOnceATurn,once);
|
return NEW TrDamaged(observer, id, card, tc, fromTc, 0,sourceUntapped,limitOnceATurn,once);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Lifed
|
//Lifed current controller
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "lifeof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrLifeGained(observer, id, card, tc, fromTc, 0,sourceUntapped,once,true,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Lifed current opponent
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "lifefoeof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrLifeGained(observer, id, card, tc, fromTc, 0,sourceUntapped,once,false,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Lifed static
|
||||||
if (TargetChooser * tc = parseSimpleTC(s, "lifed", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "lifed", card))
|
||||||
{
|
{
|
||||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
return NEW TrLifeGained(observer, id, card, tc, fromTc, 0,sourceUntapped,once);
|
return NEW TrLifeGained(observer, id, card, tc, fromTc, 0,sourceUntapped,once);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Life Loss
|
//Life Loss current player
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "lifelostof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrLifeGained(observer, id, card, tc, fromTc,1,sourceUntapped,once,true,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Life Loss current opponent
|
||||||
|
if (TargetChooser * tc = parseSimpleTC(s, "lifelostfoeof", card))
|
||||||
|
{
|
||||||
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
return NEW TrLifeGained(observer, id, card, tc, fromTc,1,sourceUntapped,once,false,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Life Loss static
|
||||||
if (TargetChooser * tc = parseSimpleTC(s, "lifeloss", card))
|
if (TargetChooser * tc = parseSimpleTC(s, "lifeloss", card))
|
||||||
{
|
{
|
||||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||||
|
|||||||
Reference in New Issue
Block a user