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
|
||||
[/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
|
||||
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}
|
||||
|
||||
28
projects/mtg/bin/Res/test/ExchangeController.txt
Normal file
28
projects/mtg/bin/Res/test/ExchangeController.txt
Normal file
@@ -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_2.txt
|
||||
exaltedsourcekilled.txt
|
||||
ExchangeController.txt
|
||||
executioners_swing.txt
|
||||
executioners_swing2.txt
|
||||
executioners_swing3.txt
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
#DESC: Tests whether Curiosity works correctly
|
||||
#DESC: when cast on an opponent's creature
|
||||
#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]
|
||||
firstmain
|
||||
[PLAYER1]
|
||||
@@ -29,7 +38,7 @@ next
|
||||
combatend
|
||||
[PLAYER1]
|
||||
inplay:Curiosity
|
||||
hand:Island
|
||||
library:Island
|
||||
life:14
|
||||
[PLAYER2]
|
||||
inplay:Craw Wurm
|
||||
|
||||
@@ -1196,9 +1196,9 @@ public:
|
||||
class TrcardDrawn: public Trigger
|
||||
{
|
||||
public:
|
||||
|
||||
TrcardDrawn(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc,bool once = false) :
|
||||
Trigger(observer, id, source,once, tc)
|
||||
bool thiscontroller, thisopponent;
|
||||
TrcardDrawn(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc,bool once = false, bool thiscontroller = false, bool thisopponent = false) :
|
||||
Trigger(observer, id, source,once, tc),thiscontroller(thiscontroller),thisopponent(thisopponent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1207,7 +1207,12 @@ public:
|
||||
WEventcardDraw * e = dynamic_cast<WEventcardDraw *> (event);
|
||||
if (!e) 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;
|
||||
}
|
||||
|
||||
@@ -1295,8 +1300,10 @@ public:
|
||||
bool sourceUntapped;
|
||||
bool limitOnceATurn;
|
||||
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) :
|
||||
Trigger(observer, id, source, once, tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped),limitOnceATurn(limitOnceATurn)
|
||||
bool thiscontroller;
|
||||
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;
|
||||
}
|
||||
@@ -1313,6 +1320,15 @@ public:
|
||||
if (fromTc && !fromTc->canTarget(e->damage->source)) 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 (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->source->thatmuch = e->damage->damage;
|
||||
this->source->thatmuch = e->damage->damage;
|
||||
@@ -1337,9 +1353,9 @@ class TrLifeGained: public Trigger
|
||||
public:
|
||||
TargetChooser * fromTc;
|
||||
int type;//this allows damagenoncombat and combatdamage to share this trigger
|
||||
bool sourceUntapped;
|
||||
TrLifeGained(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool once = false) :
|
||||
Trigger(observer, id, source, once , tc), fromTc(fromTc), type(type) , sourceUntapped(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, bool thiscontroller = false, bool thisopponent = false) :
|
||||
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 (type == 1 && (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);
|
||||
this->source->thatmuch = abs(e->amount);
|
||||
|
||||
|
||||
@@ -825,7 +825,16 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
|
||||
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))
|
||||
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))
|
||||
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))
|
||||
{
|
||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||
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))
|
||||
{
|
||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||
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))
|
||||
{
|
||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||
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))
|
||||
{
|
||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||
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))
|
||||
{
|
||||
TargetChooser *fromTc = parseSimpleTC(s, "from", card);
|
||||
|
||||
Reference in New Issue
Block a user