Erwan
-new trigger: @tapped(... -Parser now supports X for P/T. WARNING: this does not work for activated abilities. And currently this works only for P/T but will be added progressively to other things
This commit is contained in:
@@ -855,6 +855,7 @@ name=Flowstone Slide
|
|||||||
rarity=R
|
rarity=R
|
||||||
type=Sorcery
|
type=Sorcery
|
||||||
mana={X}{2}{R}{R}
|
mana={X}{2}{R}{R}
|
||||||
|
auto=lord(creature) x/-x
|
||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
text={T}: Add {G} to your mana pool.
|
text={T}: Add {G} to your mana pool.
|
||||||
|
|||||||
@@ -549,11 +549,11 @@ toughness=2
|
|||||||
text=Target creature gets +X/+0 until end of turn.
|
text=Target creature gets +X/+0 until end of turn.
|
||||||
id=2456
|
id=2456
|
||||||
target=creature
|
target=creature
|
||||||
alias=1164
|
|
||||||
name=Howl from Beyond
|
name=Howl from Beyond
|
||||||
rarity=C
|
rarity=C
|
||||||
type=Instant
|
type=Instant
|
||||||
mana={X}{B}
|
mana={X}{B}
|
||||||
|
auto=X/0
|
||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
text=Hurricane deals X damage to each creature with flying and each player.
|
text=Hurricane deals X damage to each creature with flying and each player.
|
||||||
@@ -1465,6 +1465,7 @@ toughness=1
|
|||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
text=Whenever an Island an opponent controls becomes tapped, you may gain 1 life.
|
text=Whenever an Island an opponent controls becomes tapped, you may gain 1 life.
|
||||||
|
auto=@tapped(island|opponentBattlefield):life:1 controller
|
||||||
id=2593
|
id=2593
|
||||||
name=Thoughtleech
|
name=Thoughtleech
|
||||||
rarity=U
|
rarity=U
|
||||||
|
|||||||
@@ -791,6 +791,7 @@ abilities=legendary
|
|||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
text=Whenever a Mountain an opponent controls becomes tapped, you gain 1 life.
|
text=Whenever a Mountain an opponent controls becomes tapped, you gain 1 life.
|
||||||
|
auto=@tapped(mountain|opponentBattlefield):life:1 controller
|
||||||
id=1625
|
id=1625
|
||||||
name=Lifeblood
|
name=Lifeblood
|
||||||
rarity=R
|
rarity=R
|
||||||
|
|||||||
@@ -1015,6 +1015,7 @@ name=Howl from Beyond
|
|||||||
rarity=C
|
rarity=C
|
||||||
type=Instant
|
type=Instant
|
||||||
mana={X}{B}
|
mana={X}{B}
|
||||||
|
auto=X/0
|
||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
text=At the beginning of each player's draw step, if Howling Mine is untapped, that player draws a card.
|
text=At the beginning of each player's draw step, if Howling Mine is untapped, that player draws a card.
|
||||||
@@ -1288,6 +1289,7 @@ mana={G}
|
|||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
text=Whenever a Forest an opponent controls becomes tapped, you gain 1 life.
|
text=Whenever a Forest an opponent controls becomes tapped, you gain 1 life.
|
||||||
|
auto=@tapped(forest|opponentBattlefield):life:1 controller
|
||||||
id=1205
|
id=1205
|
||||||
name=Lifetap
|
name=Lifetap
|
||||||
rarity=U
|
rarity=U
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ fists_of_ironwood.txt
|
|||||||
flare.txt
|
flare.txt
|
||||||
fledgling_imp.txt
|
fledgling_imp.txt
|
||||||
fledgling_imp2.txt
|
fledgling_imp2.txt
|
||||||
|
flowstone_slide.txt
|
||||||
foratog.txt
|
foratog.txt
|
||||||
force_of_nature.txt
|
force_of_nature.txt
|
||||||
force_of_nature2.txt
|
force_of_nature2.txt
|
||||||
@@ -121,6 +122,7 @@ gravedigger.txt
|
|||||||
hannas_custody.txt
|
hannas_custody.txt
|
||||||
harpoon_sniper.txt
|
harpoon_sniper.txt
|
||||||
hellfire.txt
|
hellfire.txt
|
||||||
|
howl_from_beyond.txt
|
||||||
howl_of_the_night_pack.txt
|
howl_of_the_night_pack.txt
|
||||||
hymn_of_rebirth.txt
|
hymn_of_rebirth.txt
|
||||||
icatian_priest.txt
|
icatian_priest.txt
|
||||||
@@ -140,6 +142,7 @@ leveler.txt
|
|||||||
lhurgoyf.txt
|
lhurgoyf.txt
|
||||||
liability.txt
|
liability.txt
|
||||||
lifeforce.txt
|
lifeforce.txt
|
||||||
|
lifetap.txt
|
||||||
living_lands.txt
|
living_lands.txt
|
||||||
lord_of_the_pit.txt
|
lord_of_the_pit.txt
|
||||||
lord_of_the_pit2.txt
|
lord_of_the_pit2.txt
|
||||||
|
|||||||
21
projects/mtg/bin/Res/test/flagstones.txt
Normal file
21
projects/mtg/bin/Res/test/flagstones.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#Bug: Flagstones of trokair crash the game when going to graveyard
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:flagstones of trokair
|
||||||
|
manapool:{2}{R}
|
||||||
|
hand:stone rain
|
||||||
|
library:plains
|
||||||
|
[PLAYER2]
|
||||||
|
[DO]
|
||||||
|
stone rain
|
||||||
|
flagstones of trokair
|
||||||
|
choice 0
|
||||||
|
plains
|
||||||
|
[ASSERT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:plains
|
||||||
|
graveyard:stone rain,flagstones of trokair
|
||||||
|
[PLAYER2]
|
||||||
|
[END]
|
||||||
28
projects/mtg/bin/Res/test/flowstone_slide.txt
Normal file
28
projects/mtg/bin/Res/test/flowstone_slide.txt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#Test: Parse X cost
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
manapool:{1}{2}{R}{R}
|
||||||
|
inplay:grizzly bears,dragon engine
|
||||||
|
hand:Flowstone slide
|
||||||
|
[PLAYER2]
|
||||||
|
[DO]
|
||||||
|
Flowstone slide
|
||||||
|
next
|
||||||
|
#begin
|
||||||
|
next
|
||||||
|
#attackers
|
||||||
|
grizzly bears
|
||||||
|
dragon engine
|
||||||
|
next
|
||||||
|
#blockers
|
||||||
|
next
|
||||||
|
#damage
|
||||||
|
[ASSERT]
|
||||||
|
COMBATDAMAGE
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:grizzly bears,dragon engine
|
||||||
|
graveyard:Flowstone slide
|
||||||
|
[PLAYER2]
|
||||||
|
life:15
|
||||||
|
[END]
|
||||||
28
projects/mtg/bin/Res/test/howl_from_beyond.txt
Normal file
28
projects/mtg/bin/Res/test/howl_from_beyond.txt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#Test: Parse X cost
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
manapool:{5}{B}
|
||||||
|
inplay:grizzly bears
|
||||||
|
hand:howl from beyond
|
||||||
|
[PLAYER2]
|
||||||
|
[DO]
|
||||||
|
howl from beyond
|
||||||
|
grizzly bears
|
||||||
|
next
|
||||||
|
#begin
|
||||||
|
next
|
||||||
|
#attackers
|
||||||
|
grizzly bears
|
||||||
|
next
|
||||||
|
#blockers
|
||||||
|
next
|
||||||
|
#damage
|
||||||
|
[ASSERT]
|
||||||
|
COMBATDAMAGE
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:grizzly bears
|
||||||
|
graveyard:howl from beyond
|
||||||
|
[PLAYER2]
|
||||||
|
life:13
|
||||||
|
[END]
|
||||||
18
projects/mtg/bin/Res/test/lifetap.txt
Normal file
18
projects/mtg/bin/Res/test/lifetap.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#Test: @tapped trigger
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
inplay:forest
|
||||||
|
[PLAYER2]
|
||||||
|
inplay:lifetap
|
||||||
|
[DO]
|
||||||
|
forest
|
||||||
|
[ASSERT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
manapool:{G}
|
||||||
|
inplay:forest
|
||||||
|
[PLAYER2]
|
||||||
|
inplay:lifetap
|
||||||
|
life:21
|
||||||
|
[END]
|
||||||
@@ -22,6 +22,71 @@
|
|||||||
using std::map;
|
using std::map;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Misc classes
|
||||||
|
//
|
||||||
|
class WParsedInt{
|
||||||
|
public:
|
||||||
|
int intValue;
|
||||||
|
|
||||||
|
int computeX(Spell * spell, MTGCardInstance * card){
|
||||||
|
ManaCost * c = spell->cost->Diff(card->getManaCost());
|
||||||
|
int x = c->getCost(Constants::MTG_NB_COLORS);
|
||||||
|
delete c;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
WParsedInt(){
|
||||||
|
intValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WParsedInt(string s, Spell * spell, MTGCardInstance * card){
|
||||||
|
int multiplier = 1;
|
||||||
|
if (s[0] == '-'){
|
||||||
|
s = s.substr(1);
|
||||||
|
multiplier = -1;
|
||||||
|
}
|
||||||
|
if (s == "x" || s == "X"){
|
||||||
|
intValue = computeX(spell,card);
|
||||||
|
}else{
|
||||||
|
intValue = atoi(s.c_str());
|
||||||
|
}
|
||||||
|
intValue *= multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getValue(){
|
||||||
|
return intValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class WParsedPT{
|
||||||
|
public:
|
||||||
|
bool ok;
|
||||||
|
WParsedInt power,toughness;
|
||||||
|
|
||||||
|
WParsedPT(int p, int t){
|
||||||
|
power.intValue = p;
|
||||||
|
toughness.intValue = t;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WParsedPT(string s, Spell * spell, MTGCardInstance * card){
|
||||||
|
size_t found = s.find("/");
|
||||||
|
ok = false;
|
||||||
|
if (found != string::npos){
|
||||||
|
size_t end = s.find(" ", found);
|
||||||
|
if (end == string::npos) end = s.size();
|
||||||
|
size_t start = s.find_last_of(" ",found);
|
||||||
|
if (start == string::npos) start = 0;
|
||||||
|
else start++;
|
||||||
|
|
||||||
|
power = WParsedInt(s.substr(start,found - start), spell, card);
|
||||||
|
toughness = WParsedInt(s.substr(found+1,end-found-1), spell, card);
|
||||||
|
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
//Triggers
|
//Triggers
|
||||||
//
|
//
|
||||||
@@ -56,6 +121,36 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TrCardTapped:public TriggeredAbility{
|
||||||
|
public:
|
||||||
|
TargetChooser * tc;
|
||||||
|
bool tap;
|
||||||
|
TrCardTapped(int id, MTGCardInstance * source, TargetChooser * tc, bool tap = true):TriggeredAbility(id,source), tc(tc),tap(tap){}
|
||||||
|
|
||||||
|
int resolve(){
|
||||||
|
return 0; //This is a trigger, this function should not be called
|
||||||
|
}
|
||||||
|
|
||||||
|
int triggerOnEvent(WEvent * event){
|
||||||
|
WEventCardTap * e = dynamic_cast<WEventCardTap *>(event);
|
||||||
|
if (!e) return 0;
|
||||||
|
if (e->before == e->after) return 0;
|
||||||
|
if (e->after != tap) return 0;
|
||||||
|
if (!tc->canTarget(e->card)) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
~TrCardTapped(){
|
||||||
|
SAFE_DELETE(tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TrCardTapped * clone() const{
|
||||||
|
TrCardTapped * a = NEW TrCardTapped(*this);
|
||||||
|
a->isClone = 1;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//counters
|
//counters
|
||||||
class AACounter: public ActivatedAbility{
|
class AACounter: public ActivatedAbility{
|
||||||
@@ -935,38 +1030,33 @@ class AUntaperOnceDuringTurn:public AUnBlocker{
|
|||||||
//Alteration of Power and Toughness (enchantments)
|
//Alteration of Power and Toughness (enchantments)
|
||||||
class APowerToughnessModifier: public MTGAbility{
|
class APowerToughnessModifier: public MTGAbility{
|
||||||
public:
|
public:
|
||||||
int power, toughness;
|
WParsedPT * wppt;
|
||||||
APowerToughnessModifier(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness):MTGAbility(id,_source,_target),power(_power),toughness(_toughness){
|
APowerToughnessModifier(int id, MTGCardInstance * _source, MTGCardInstance * _target, WParsedPT * wppt):MTGAbility(id,_source,_target),wppt(wppt){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int addToGame(){
|
int addToGame(){
|
||||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||||
_target->power += power;
|
_target->power += wppt->power.getValue();
|
||||||
_target->addToToughness(toughness);
|
_target->addToToughness(wppt->toughness.getValue());
|
||||||
return MTGAbility::addToGame();
|
return MTGAbility::addToGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
int destroy(){
|
int destroy(){
|
||||||
((MTGCardInstance *)target)->power -= power;
|
((MTGCardInstance *)target)->power -= wppt->power.getValue();
|
||||||
((MTGCardInstance *)target)->addToToughness(-toughness);
|
((MTGCardInstance *)target)->addToToughness(- wppt->toughness.getValue());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual ostream& toString(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "APowerToughnessModifier ::: power : " << power
|
|
||||||
<< " ; toughness : " << toughness
|
|
||||||
<< " (";
|
|
||||||
return MTGAbility::toString(out) << ")";
|
|
||||||
}
|
|
||||||
APowerToughnessModifier * clone() const{
|
APowerToughnessModifier * clone() const{
|
||||||
APowerToughnessModifier * a = NEW APowerToughnessModifier(*this);
|
APowerToughnessModifier * a = NEW APowerToughnessModifier(*this);
|
||||||
|
a->wppt = NEW WParsedPT(*(a->wppt));
|
||||||
a->isClone = 1;
|
a->isClone = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
~APowerToughnessModifier(){
|
~APowerToughnessModifier(){
|
||||||
OutputDebugString ("DELETING POWERTOUGHNESS");
|
delete(wppt);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -978,9 +1068,9 @@ class ATargetterPowerToughnessModifierUntilEOT: public TargetAbility{
|
|||||||
public:
|
public:
|
||||||
MTGCardInstance * mTargets[50];
|
MTGCardInstance * mTargets[50];
|
||||||
int nbTargets;
|
int nbTargets;
|
||||||
int power, toughness;
|
WParsedPT * wppt;
|
||||||
|
|
||||||
ATargetterPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, int _power, int _toughness, ManaCost * _cost, TargetChooser * _tc = NULL, int doTap=1):TargetAbility(_id,_source,_tc,_cost,0,doTap),power(_power),toughness(_toughness){
|
ATargetterPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, WParsedPT * wppt, ManaCost * _cost, TargetChooser * _tc = NULL, int doTap=1):TargetAbility(_id,_source,_tc,_cost,0,doTap),wppt(wppt){
|
||||||
if (!tc) tc = NEW CreatureTargetChooser(_source);
|
if (!tc) tc = NEW CreatureTargetChooser(_source);
|
||||||
nbTargets = 0;
|
nbTargets = 0;
|
||||||
}
|
}
|
||||||
@@ -991,8 +1081,8 @@ class ATargetterPowerToughnessModifierUntilEOT: public TargetAbility{
|
|||||||
for (int i = 0; i < nbTargets; i++){
|
for (int i = 0; i < nbTargets; i++){
|
||||||
MTGCardInstance * mTarget = mTargets[i];
|
MTGCardInstance * mTarget = mTargets[i];
|
||||||
if(mTarget){
|
if(mTarget){
|
||||||
mTarget->power-=power;
|
mTarget->power-=wppt->power.getValue();
|
||||||
mTarget->addToToughness(-toughness);
|
mTarget->addToToughness(-wppt->toughness.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nbTargets = 0;
|
nbTargets = 0;
|
||||||
@@ -1005,65 +1095,60 @@ class ATargetterPowerToughnessModifierUntilEOT: public TargetAbility{
|
|||||||
MTGCardInstance * mTarget = tc->getNextCardTarget();
|
MTGCardInstance * mTarget = tc->getNextCardTarget();
|
||||||
if (mTarget){
|
if (mTarget){
|
||||||
mTargets[nbTargets] = mTarget;
|
mTargets[nbTargets] = mTarget;
|
||||||
mTarget->power+= power;
|
mTarget->power+= wppt->power.getValue();
|
||||||
mTarget->addToToughness(toughness);
|
mTarget->addToToughness(wppt->toughness.getValue());
|
||||||
nbTargets++;
|
nbTargets++;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "ATargetterPowerToughnessModifierUntilEOT ::: mTargets : " << mTargets
|
|
||||||
<< " ; nbTargets : " << nbTargets
|
|
||||||
<< " ; power : " << power
|
|
||||||
<< " ; toughness : " << toughness
|
|
||||||
<< " (";
|
|
||||||
return TargetAbility::toString(out) << ")";
|
|
||||||
}
|
|
||||||
ATargetterPowerToughnessModifierUntilEOT * clone() const{
|
ATargetterPowerToughnessModifierUntilEOT * clone() const{
|
||||||
ATargetterPowerToughnessModifierUntilEOT * a = NEW ATargetterPowerToughnessModifierUntilEOT(*this);
|
ATargetterPowerToughnessModifierUntilEOT * a = NEW ATargetterPowerToughnessModifierUntilEOT(*this);
|
||||||
|
a->wppt = NEW WParsedPT(*(a->wppt));
|
||||||
a->isClone = 1;
|
a->isClone = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~ATargetterPowerToughnessModifierUntilEOT(){
|
||||||
|
delete(wppt);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Alteration of Power and toughness until end of turn (instant)
|
//Alteration of Power and toughness until end of turn (instant)
|
||||||
class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{
|
class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{
|
||||||
public:
|
public:
|
||||||
int power, toughness;
|
WParsedPT * wppt;
|
||||||
AInstantPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness): InstantAbility(_id, _source, _target), power(_power), toughness(_toughness){
|
AInstantPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, WParsedPT * wppt): InstantAbility(_id, _source, _target), wppt(wppt){
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve(){
|
int resolve(){
|
||||||
((MTGCardInstance *)target)->power +=power;
|
((MTGCardInstance *)target)->power +=wppt->power.getValue();
|
||||||
((MTGCardInstance *)target)->addToToughness(toughness);
|
((MTGCardInstance *)target)->addToToughness(wppt->toughness.getValue());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int destroy(){
|
int destroy(){
|
||||||
((MTGCardInstance *)target)->power -=power;
|
((MTGCardInstance *)target)->power -=wppt->power.getValue();
|
||||||
((MTGCardInstance *)target)->addToToughness(-toughness);
|
((MTGCardInstance *)target)->addToToughness(-wppt->toughness.getValue());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * getMenuText(){
|
const char * getMenuText(){
|
||||||
sprintf(menuText, "%i/%i",power,toughness);
|
sprintf(menuText, "%i/%i",wppt->power.getValue(),wppt->toughness.getValue());
|
||||||
return menuText;
|
return menuText;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "APowerToughnessModifierUntilEndOfTurn ::: power : " << power
|
|
||||||
<< " ; toughness : " << toughness
|
|
||||||
<< " (";
|
|
||||||
return InstantAbility::toString(out) << ")";
|
|
||||||
}
|
|
||||||
AInstantPowerToughnessModifierUntilEOT * clone() const{
|
AInstantPowerToughnessModifierUntilEOT * clone() const{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(*this);
|
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(*this);
|
||||||
|
a->wppt = NEW WParsedPT(*(a->wppt));
|
||||||
a->isClone = 1;
|
a->isClone = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~AInstantPowerToughnessModifierUntilEOT(){
|
||||||
|
delete wppt;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1074,10 +1159,10 @@ class APowerToughnessModifierUntilEndOfTurn: public ActivatedAbility{
|
|||||||
AInstantPowerToughnessModifierUntilEOT * ability;
|
AInstantPowerToughnessModifierUntilEOT * ability;
|
||||||
int counters;
|
int counters;
|
||||||
int maxcounters;
|
int maxcounters;
|
||||||
APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness, ManaCost * _cost = NULL, int _maxcounters = 0):ActivatedAbility(id,_source,_cost,0,0),maxcounters(_maxcounters){
|
APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, WParsedPT * wppt, ManaCost * _cost = NULL, int _maxcounters = 0):ActivatedAbility(id,_source,_cost,0,0),maxcounters(_maxcounters){
|
||||||
counters = 0;
|
counters = 0;
|
||||||
target=_target;
|
target=_target;
|
||||||
ability = NEW AInstantPowerToughnessModifierUntilEOT(id,_source,_target,_power,_toughness);
|
ability = NEW AInstantPowerToughnessModifierUntilEOT(id,_source,_target,wppt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(float dt){
|
void Update(float dt){
|
||||||
@@ -3270,7 +3355,7 @@ class AWanderlust:public TriggeredAbility{
|
|||||||
//1284 Dragon Whelp
|
//1284 Dragon Whelp
|
||||||
class ADragonWhelp: public APowerToughnessModifierUntilEndOfTurn{
|
class ADragonWhelp: public APowerToughnessModifierUntilEndOfTurn{
|
||||||
public:
|
public:
|
||||||
ADragonWhelp(int id, MTGCardInstance * card):APowerToughnessModifierUntilEndOfTurn(id, card, card, 1, 0, NEW ManaCost()){
|
ADragonWhelp(int id, MTGCardInstance * card):APowerToughnessModifierUntilEndOfTurn(id, card, card, NEW WParsedPT(1, 0), NEW ManaCost()){
|
||||||
cost->add(Constants::MTG_COLOR_RED, 1);
|
cost->add(Constants::MTG_COLOR_RED, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3771,51 +3856,6 @@ class AShieldOfTheAge: public TargetAbility{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// GiveLifeForTappedType
|
|
||||||
class AGiveLifeForTappedType:public MTGAbility{
|
|
||||||
public:
|
|
||||||
char type[20];
|
|
||||||
int nbtypestapped;
|
|
||||||
|
|
||||||
int counttypesTapped(){
|
|
||||||
int result = 0;
|
|
||||||
MTGInPlay * inplay = source->controller()->opponent()->game->inPlay;
|
|
||||||
for (int i = 0; i < inplay->nb_cards; i++){
|
|
||||||
MTGCardInstance * card = inplay->cards[i];
|
|
||||||
if (card->isTapped() && card->hasType(type)) result++;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
AGiveLifeForTappedType(int _id, MTGCardInstance * source, const char * _type):MTGAbility(_id, source){
|
|
||||||
sprintf(type,"%s",_type);{
|
|
||||||
nbtypestapped = counttypesTapped();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(float dt){
|
|
||||||
int newcount = counttypesTapped();
|
|
||||||
for (int i=0; i < newcount - nbtypestapped; i++){
|
|
||||||
source->controller()->life++;
|
|
||||||
}
|
|
||||||
nbtypestapped = newcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "AGiveLifeForTappedType ::: type : " << type
|
|
||||||
<< " ; nbtypestapped : " << nbtypestapped
|
|
||||||
<< " (";
|
|
||||||
return MTGAbility::toString(out) << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
AGiveLifeForTappedType * clone() const{
|
|
||||||
AGiveLifeForTappedType * a = NEW AGiveLifeForTappedType(*this);
|
|
||||||
a->isClone = 1;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Minion of Leshrac
|
//Minion of Leshrac
|
||||||
class AMinionofLeshrac: public TargetAbility{
|
class AMinionofLeshrac: public TargetAbility{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -96,6 +96,18 @@ TriggeredAbility * AbilityFactory::parseTrigger(string magicText, int id, Spell
|
|||||||
return NEW TrCardAddedToZone(id,card,toTc,(TargetZoneChooser *)fromTc);
|
return NEW TrCardAddedToZone(id,card,toTc,(TargetZoneChooser *)fromTc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Card Tapped
|
||||||
|
found = s.find("tapped(");
|
||||||
|
if (found != string::npos){
|
||||||
|
size_t end = s.find (")");
|
||||||
|
string starget = s.substr(found+7,end - found - 7);
|
||||||
|
TargetChooserFactory tcf;
|
||||||
|
TargetChooser *tc = tcf.createTargetChooser(starget,card);
|
||||||
|
tc->targetter = NULL;
|
||||||
|
|
||||||
|
return NEW TrCardTapped(id,card,tc);
|
||||||
|
}
|
||||||
|
|
||||||
int who = 0;
|
int who = 0;
|
||||||
if (s.find("my") != string::npos) who = 1;
|
if (s.find("my") != string::npos) who = 1;
|
||||||
if (s.find("opponent") != string::npos) who = -1;
|
if (s.find("opponent") != string::npos) who = -1;
|
||||||
@@ -556,15 +568,17 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
if (found!= string::npos) forceUEOT = 1;
|
if (found!= string::npos) forceUEOT = 1;
|
||||||
|
|
||||||
//Change Power/Toughness
|
//Change Power/Toughness
|
||||||
int power, toughness;
|
WParsedPT * wppt = NEW WParsedPT(s,spell,card);
|
||||||
if ( parsePowerToughness(s,&power, &toughness)){
|
if (wppt->ok){
|
||||||
if (!activated){
|
if (!activated){
|
||||||
if(card->hasType("instant") || card->hasType("sorcery") || forceUEOT){
|
if(card->hasType("instant") || card->hasType("sorcery") || forceUEOT){
|
||||||
return NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness);
|
return NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,wppt);
|
||||||
}
|
}
|
||||||
return NEW APowerToughnessModifier(id, card, target,power,toughness);
|
return NEW APowerToughnessModifier(id, card, target,wppt);
|
||||||
}
|
}
|
||||||
return NEW APowerToughnessModifierUntilEndOfTurn(id,card,target,power,toughness);
|
return NEW APowerToughnessModifierUntilEndOfTurn(id,card,target,wppt);
|
||||||
|
}else{
|
||||||
|
delete wppt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -644,8 +658,8 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode){
|
|||||||
if (dynamic_cast<AADrawer *>(a)) return BAKA_EFFECT_GOOD;
|
if (dynamic_cast<AADrawer *>(a)) return BAKA_EFFECT_GOOD;
|
||||||
if (dynamic_cast<AARandomDiscarder *>(a)) return BAKA_EFFECT_BAD;
|
if (dynamic_cast<AARandomDiscarder *>(a)) return BAKA_EFFECT_BAD;
|
||||||
if (dynamic_cast<ARampageAbility *>(a)) return BAKA_EFFECT_GOOD;
|
if (dynamic_cast<ARampageAbility *>(a)) return BAKA_EFFECT_GOOD;
|
||||||
if (AInstantPowerToughnessModifierUntilEOT * abi = dynamic_cast<AInstantPowerToughnessModifierUntilEOT *>(a)) return (abi->power>=0 && abi->toughness>=0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
if (AInstantPowerToughnessModifierUntilEOT * abi = dynamic_cast<AInstantPowerToughnessModifierUntilEOT *>(a)) return (abi->wppt->power.getValue()>=0 && abi->wppt->toughness.getValue()>=0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
||||||
if (APowerToughnessModifier * abi = dynamic_cast<APowerToughnessModifier *>(a)) return (abi->power>=0 && abi->toughness>=0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
if (APowerToughnessModifier * abi = dynamic_cast<APowerToughnessModifier *>(a)) return (abi->wppt->power.getValue()>=0 && abi->wppt->toughness.getValue()>=0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
||||||
if (APowerToughnessModifierUntilEndOfTurn * abi = dynamic_cast<APowerToughnessModifierUntilEndOfTurn *>(a)) return abilityEfficiency(abi->ability, p, mode);
|
if (APowerToughnessModifierUntilEndOfTurn * abi = dynamic_cast<APowerToughnessModifierUntilEndOfTurn *>(a)) return abilityEfficiency(abi->ability, p, mode);
|
||||||
|
|
||||||
map<int,bool> badAbilities;
|
map<int,bool> badAbilities;
|
||||||
@@ -966,11 +980,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1205: //Lifetap
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AGiveLifeForTappedType(_id, card, "forest"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1259: //Living lands
|
case 1259: //Living lands
|
||||||
{
|
{
|
||||||
game->addObserver(NEW AConvertLandToCreatures(id, card, "forest"));
|
game->addObserver(NEW AConvertLandToCreatures(id, card, "forest"));
|
||||||
@@ -1062,13 +1072,13 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
game->addObserver(ability);
|
game->addObserver(ability);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1164: //Howl from beyond
|
/*case 1164: //Howl from beyond
|
||||||
{
|
{
|
||||||
int x = computeX(spell,card);
|
int x = computeX(spell,card);
|
||||||
AInstantPowerToughnessModifierUntilEOT * ability = NEW AInstantPowerToughnessModifierUntilEOT( _id, card, card->target, x, 0);
|
AInstantPowerToughnessModifierUntilEOT * ability = NEW AInstantPowerToughnessModifierUntilEOT( _id, card, card->target, x, 0);
|
||||||
game->addObserver(ability);
|
game->addObserver(ability);
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
case 1202: //Hurkyl's Recall
|
case 1202: //Hurkyl's Recall
|
||||||
{
|
{
|
||||||
Player * player = spell->getNextPlayerTarget();
|
Player * player = spell->getNextPlayerTarget();
|
||||||
@@ -1361,11 +1371,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
game->currentlyActing()->life+= card->target->getManaCost()->getConvertedCost();
|
game->currentlyActing()->life+= card->target->getManaCost()->getConvertedCost();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1625: //Lifeblood
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1480: //Energy Tap
|
case 1480: //Energy Tap
|
||||||
{
|
{
|
||||||
card->target->tap();
|
card->target->tap();
|
||||||
@@ -1377,7 +1382,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
{
|
{
|
||||||
int toughness = card->target->getManaCost()->getConvertedCost();
|
int toughness = card->target->getManaCost()->getConvertedCost();
|
||||||
int power = 0;
|
int power = 0;
|
||||||
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, card->target,power,toughness));
|
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, card->target, NEW WParsedPT(power,toughness)));
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1703: //Pendelhaven
|
case 1703: //Pendelhaven
|
||||||
@@ -1385,7 +1390,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
||||||
tc->maxpower = 1;
|
tc->maxpower = 1;
|
||||||
tc->maxtoughness =1;
|
tc->maxtoughness =1;
|
||||||
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, 1,2, NEW ManaCost(),tc));
|
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, NEW WParsedPT(1,2), NEW ManaCost(),tc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1396,11 +1401,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
card->target->controller()->life-= card->target->getManaCost()->getConvertedCost();
|
card->target->controller()->life-= card->target->getManaCost()->getConvertedCost();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2593: //Thoughtleech
|
|
||||||
{
|
|
||||||
game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2474: //Minion of Leshrac
|
case 2474: //Minion of Leshrac
|
||||||
{
|
{
|
||||||
game->addObserver(NEW AMinionofLeshrac( _id, card));
|
game->addObserver(NEW AMinionofLeshrac( _id, card));
|
||||||
@@ -1425,7 +1425,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
||||||
tc->maxpower = 1;
|
tc->maxpower = 1;
|
||||||
tc->maxtoughness =1;
|
tc->maxtoughness =1;
|
||||||
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, 1,2, NEW ManaCost(cost,1),tc));
|
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, NEW WParsedPT(1,2), NEW ManaCost(cost,1),tc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1480,16 +1480,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
|||||||
game->addObserver( NEW AInstantControlSteal(_id,card,card->target));
|
game->addObserver( NEW AInstantControlSteal(_id,card,card->target));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 130542: //Flowstone Slide
|
|
||||||
{
|
|
||||||
int x = computeX(spell,card);
|
|
||||||
MTGAbility * a = NEW AInstantPowerToughnessModifierUntilEOT(id, card, card,x,-x);
|
|
||||||
TargetChooserFactory tcf;
|
|
||||||
TargetChooser * lordTargets = tcf.createTargetChooser("creature", card);
|
|
||||||
game->addObserver(NEW ALord(id, card, lordTargets, 0, a));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 130373: //Lavaborn Muse
|
case 130373: //Lavaborn Muse
|
||||||
{
|
{
|
||||||
game->addObserver( NEW ALavaborn(_id ,card, Constants::MTG_PHASE_UPKEEP, -3,-3));
|
game->addObserver( NEW ALavaborn(_id ,card, Constants::MTG_PHASE_UPKEEP, -3,-3));
|
||||||
|
|||||||
Reference in New Issue
Block a user