Zeth Fixes
Memleaks and others
This commit is contained in:
@@ -1043,7 +1043,7 @@ type=Enchantment
|
||||
[/card]
|
||||
[card]
|
||||
name=AEther Burst
|
||||
target=<plusonetype:AEther Burst:graveyard>creature|battlefield
|
||||
target=<type:AEther Burst:graveyardplus1plusend>creature|battlefield
|
||||
auto=moveto(ownerhand)
|
||||
text=Return up to X target creatures to their owners' hands, where X is one plus the number of cards named AEther Burst in all graveyards as you cast AEther Burst.
|
||||
mana={1}{U}
|
||||
@@ -3677,7 +3677,7 @@ toughness=1+*
|
||||
[/card]
|
||||
[card]
|
||||
name=An-Havva Inn
|
||||
auto=life:plusonetype:creature[green]|battlefield controller
|
||||
auto=life:type:creature[green]|battlefieldplus1plusend controller
|
||||
text=You gain X plus 1 life, where X is the number of green creatures on the battlefield.
|
||||
mana={1}{G}{G}
|
||||
type=Sorcery
|
||||
@@ -10126,7 +10126,7 @@ type=Sorcery
|
||||
[card]
|
||||
name=Black Vise
|
||||
auto=name(choose opponent) notatarget(opponent) deplete:0
|
||||
auto=@each targetedplayer upkeep:damage:morethanfourcards targetedplayer
|
||||
auto=@each targetedplayer upkeep:damage:type:*:targetedpersonshandminus4minusend targetedplayer
|
||||
text=As Black Vise enters the battlefield, choose an opponent. -- At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4.
|
||||
mana={1}
|
||||
type=Artifact
|
||||
@@ -54376,7 +54376,7 @@ type=Artifact
|
||||
[/card]
|
||||
[card]
|
||||
name=Iron Maiden
|
||||
auto=@each opponent upkeep:damage:morethanfourcards opponent
|
||||
auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent
|
||||
text=At the beginning of each opponent's upkeep, Iron Maiden deals X damage to that player, where X is the number of cards in his or her hand minus 4.
|
||||
mana={3}
|
||||
type=Artifact
|
||||
@@ -57937,7 +57937,7 @@ type=Instant
|
||||
[card]
|
||||
name=Kindle
|
||||
target=creature,player
|
||||
auto=damage:plustwotype:kindle:graveyard
|
||||
auto=damage:type:kindle:graveyardplus2plusend
|
||||
text=Kindle deals X damage to target creature or player, where X is 2 plus the number of cards named Kindle in all graveyards.
|
||||
mana={1}{R}
|
||||
type=Instant
|
||||
@@ -61533,7 +61533,7 @@ toughness=5
|
||||
[/card]
|
||||
[card]
|
||||
name=Lhurgoyf
|
||||
anyzone=type:creature:graveyard/plusonetype:creature:graveyard cdaactive
|
||||
anyzone=type:creature:graveyard/type:creature:graveyardplus1plusend cdaactive
|
||||
text=Lhurgoyf's power is equal to the number of creature cards in all graveyards and its toughness is equal to that number plus 1.
|
||||
mana={2}{G}{G}
|
||||
type=Creature
|
||||
@@ -68102,7 +68102,7 @@ type=Legendary Land
|
||||
[card]
|
||||
name=Mind Burst
|
||||
target=player
|
||||
auto=ability$!name(discard) target(<plusonetype:mind burst:graveyard>*|myhand) reject!$ targetedplayer
|
||||
auto=ability$!name(discard) target(<type:mind burst:graveyard>*|myhandplus1plusend) reject!$ targetedplayer
|
||||
text=Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards.
|
||||
mana={1}{B}
|
||||
type=Sorcery
|
||||
@@ -109311,7 +109311,7 @@ toughness=7
|
||||
[/card]
|
||||
[card]
|
||||
name=Tarmogoyf
|
||||
anyzone=gravecardtypes/plusonegravecardtypes cdaactive
|
||||
anyzone=gravecardtypes/gravecardtypesplus1plusend cdaactive
|
||||
text=Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (The card types are artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal.)
|
||||
mana={1}{G}
|
||||
type=Creature
|
||||
@@ -120125,7 +120125,7 @@ toughness=3
|
||||
[/card]
|
||||
[card]
|
||||
name=Viseling
|
||||
auto=@each opponent upkeep:damage:morethanfourcards opponent
|
||||
auto=@each opponent upkeep:damage:type:*:opponenthandminus4minusend opponent
|
||||
text=At the beginning of each opponent's upkeep, Viseling deals X damage to that player, where X is the number of cards in his or her hand minus 4.
|
||||
mana={4}
|
||||
type=Artifact Creature
|
||||
@@ -120200,7 +120200,7 @@ type=Instant
|
||||
[/card]
|
||||
[card]
|
||||
name=Vitalizing Cascade
|
||||
auto=life:Xplusthree
|
||||
auto=life:Xplus3plusend
|
||||
text=You gain X plus 3 life.
|
||||
mana={X}{G}{W}
|
||||
type=Instant
|
||||
@@ -121951,7 +121951,7 @@ toughness=4
|
||||
[card]
|
||||
name=Wall of Tombstones
|
||||
abilities=defender
|
||||
auto=@each my upkeep:transforms((,settoughness=plusonetype:creature:mygraveyard)) forever
|
||||
auto=@each my upkeep:transforms((,settoughness=type:creature:mygraveyardplus1plusend)) forever
|
||||
text=Defender (This creature can't attack.) -- At the beginning of your upkeep, Wall of Tombstones's toughness becomes 1 plus the number of creature cards in your graveyard. (This effect lasts indefinitely.)
|
||||
mana={1}{B}
|
||||
type=Creature
|
||||
@@ -127555,6 +127555,46 @@ subtype=Orc Warrior
|
||||
power=7
|
||||
toughness=2
|
||||
[/card]
|
||||
######
|
||||
######unsorted
|
||||
[card]
|
||||
name=Dark Suspicions
|
||||
auto=@each opponent upkeep:life:-mathtype:*:opponenthandminustype:*:myhandminusendmathend opponent
|
||||
text=At the beginning of each opponent's upkeep, that player loses X life, where X is the number of cards in that player's hand minus the number of cards in your hand.
|
||||
mana={2}{B}{B}
|
||||
type=Enchantment
|
||||
[/card]
|
||||
[card]
|
||||
name=Bulwark
|
||||
auto=@each opponent upkeep:target(opponent) damage:mathtype:*:myhandminustype:*:opponenthandminusendmathend opponent
|
||||
text=At the beginning of your upkeep, Bulwark deals X damage to target opponent, where X is the number of cards in your hand minus the number of cards in that player's hand.
|
||||
mana={3}{R}{R}
|
||||
type=Enchantment
|
||||
[/card]
|
||||
[card]
|
||||
name=Roiling Horror
|
||||
anyzone=mathlifetotalminusopponentlifetotalminusendmathend/mathlifetotalminusopponentlifetotalminusendmathend cdaactive
|
||||
autoexile=@counterremoved(0/0,1,Time) from(sourcecard) suspended:ability$!choice life:-1 target(opponent) && life:1 controller!$ controller
|
||||
text=Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. -- Suspend X—{X}{B}{B}{B}. X can't be 0. (Rather than cast this card from your hand, you may pay {X}{B}{B}{B} and exile it with X time counters on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost. It has haste.) -- Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life.
|
||||
mana={3}{B}{B}
|
||||
suspend(0)={X}{b}{b}{b}
|
||||
type=Creature
|
||||
subtype=Horror
|
||||
power=*
|
||||
toughness=*
|
||||
[/card]
|
||||
[card]
|
||||
name=Dark Deal
|
||||
auto=count(type:*:myhand)
|
||||
auto=all(*|myhand) reject
|
||||
auto=draw:countedamountplus1plusend controller
|
||||
auto=count(type:*:opponenthand)
|
||||
auto=all(*|opponenthand) reject
|
||||
auto=draw:countedamountplus1plusend opponent
|
||||
text=Each player discards all the cards in his or her hand, then draws that many cards minus one.
|
||||
mana={2}{B}
|
||||
type=Sorcery
|
||||
[/card]
|
||||
##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also
|
||||
##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type.
|
||||
[card]
|
||||
|
||||
@@ -41,111 +41,111 @@ public:
|
||||
class MTGRevealingCards : public MTGAbility, public CardDisplay
|
||||
{
|
||||
public:
|
||||
vector<CardView*> cards;
|
||||
Player * playerForZone;
|
||||
MTGGameZone * RevealZone;
|
||||
MTGGameZone * RevealFromZone;
|
||||
string revealCertainTypes;
|
||||
string revealUntil;
|
||||
vector<CardView*> cards;
|
||||
Player * playerForZone;
|
||||
MTGGameZone * RevealZone;
|
||||
MTGGameZone * RevealFromZone;
|
||||
string revealCertainTypes;
|
||||
string revealUntil;
|
||||
|
||||
CardDisplay * revealDisplay;
|
||||
vector<CardDisplay*>trashDisplays;//used for repeat
|
||||
int nbCard;
|
||||
string abilityString;
|
||||
string number;
|
||||
string abilityOne;
|
||||
string abilityTwo;
|
||||
string afterReveal;
|
||||
bool afterEffectActivated;
|
||||
MTGAbility * abilityToCast;
|
||||
MTGAbility * abilityFirst;
|
||||
MTGAbility * abilitySecond;
|
||||
MTGAbility * abilityAfter;
|
||||
vector<MTGAbility*>abilities;
|
||||
bool repeat;//only the first ability can be repeated, and it must be targeted.
|
||||
bool initCD;
|
||||
CardDisplay * revealDisplay;
|
||||
vector<CardDisplay*>trashDisplays;//used for repeat
|
||||
int nbCard;
|
||||
string abilityString;
|
||||
string number;
|
||||
string abilityOne;
|
||||
string abilityTwo;
|
||||
string afterReveal;
|
||||
bool afterEffectActivated;
|
||||
MTGAbility * abilityToCast;
|
||||
MTGAbility * abilityFirst;
|
||||
MTGAbility * abilitySecond;
|
||||
MTGAbility * abilityAfter;
|
||||
vector<MTGAbility*>abilities;
|
||||
bool repeat;//only the first ability can be repeated, and it must be targeted.
|
||||
bool initCD;
|
||||
|
||||
void Update(float dt);
|
||||
int testDestroy();
|
||||
int toResolve();
|
||||
void CardViewBackup(MTGCardInstance * backup);
|
||||
void Render();
|
||||
bool CheckUserInput(JButton key);
|
||||
MTGAbility * contructAbility(string abilityToMake = "");
|
||||
MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text);
|
||||
virtual MTGRevealingCards * clone() const;
|
||||
~MTGRevealingCards();
|
||||
int receiveEvent(WEvent*);
|
||||
void Update(float dt);
|
||||
int testDestroy();
|
||||
int toResolve();
|
||||
void CardViewBackup(MTGCardInstance * backup);
|
||||
void Render();
|
||||
bool CheckUserInput(JButton key);
|
||||
MTGAbility * contructAbility(string abilityToMake = "");
|
||||
MTGRevealingCards(GameObserver* observer, int _id, MTGCardInstance * card, string text);
|
||||
virtual MTGRevealingCards * clone() const;
|
||||
~MTGRevealingCards();
|
||||
int receiveEvent(WEvent*);
|
||||
};
|
||||
|
||||
class RevealDisplay : public CardDisplay
|
||||
{
|
||||
public:
|
||||
RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL,
|
||||
int nb_displayed_items = 7);
|
||||
void AddCard(MTGCardInstance * _card);
|
||||
bool CheckUserInput(JButton key);
|
||||
RevealDisplay(int id, GameObserver* game, int x, int y, JGuiListener * listener = NULL, TargetChooser * tc = NULL,
|
||||
int nb_displayed_items = 7);
|
||||
void AddCard(MTGCardInstance * _card);
|
||||
bool CheckUserInput(JButton key);
|
||||
};
|
||||
|
||||
class GenericRevealAbility : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
string howMany;
|
||||
MTGRevealingCards * ability;
|
||||
GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
GenericRevealAbility * clone() const;
|
||||
~GenericRevealAbility();
|
||||
string howMany;
|
||||
MTGRevealingCards * ability;
|
||||
GenericRevealAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
GenericRevealAbility * clone() const;
|
||||
~GenericRevealAbility();
|
||||
|
||||
};
|
||||
|
||||
class MTGScryCards : public MTGAbility, public CardDisplay
|
||||
{
|
||||
public:
|
||||
vector<CardView*> cards;
|
||||
MTGGameZone * RevealZone;
|
||||
MTGGameZone * RevealFromZone;
|
||||
vector<CardView*> cards;
|
||||
MTGGameZone * RevealZone;
|
||||
MTGGameZone * RevealFromZone;
|
||||
|
||||
CardDisplay * revealDisplay;
|
||||
vector<CardDisplay*>trashDisplays;//used for repeat
|
||||
int nbCard;
|
||||
bool delayed;
|
||||
bool dontRevealAfter;
|
||||
int revealTopAmount;
|
||||
string delayedAbilityString;
|
||||
string abilityString;
|
||||
string number;
|
||||
string abilityOne;
|
||||
string abilityTwo;
|
||||
MTGAbility * abilityToCast;
|
||||
MTGAbility * abilityFirst;
|
||||
MTGAbility * abilitySecond;
|
||||
vector<MTGAbility*>abilities;
|
||||
bool initCD;
|
||||
void Update(float dt);
|
||||
int testDestroy();
|
||||
void initDisplay(int value = 0);
|
||||
int toResolve();
|
||||
void Render();
|
||||
bool CheckUserInput(JButton key);
|
||||
MTGAbility * contructAbility(string abilityToMake = "");
|
||||
MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text);
|
||||
virtual MTGScryCards * clone() const;
|
||||
~MTGScryCards();
|
||||
int receiveEvent(WEvent*);
|
||||
CardDisplay * revealDisplay;
|
||||
vector<CardDisplay*>trashDisplays;//used for repeat
|
||||
int nbCard;
|
||||
bool delayed;
|
||||
bool dontRevealAfter;
|
||||
int revealTopAmount;
|
||||
string delayedAbilityString;
|
||||
string abilityString;
|
||||
string number;
|
||||
string abilityOne;
|
||||
string abilityTwo;
|
||||
MTGAbility * abilityToCast;
|
||||
MTGAbility * abilityFirst;
|
||||
MTGAbility * abilitySecond;
|
||||
vector<MTGAbility*>abilities;
|
||||
bool initCD;
|
||||
void Update(float dt);
|
||||
int testDestroy();
|
||||
void initDisplay(int value = 0);
|
||||
int toResolve();
|
||||
void Render();
|
||||
bool CheckUserInput(JButton key);
|
||||
MTGAbility * contructAbility(string abilityToMake = "");
|
||||
MTGScryCards(GameObserver* observer, int _id, MTGCardInstance * card, string text);
|
||||
virtual MTGScryCards * clone() const;
|
||||
~MTGScryCards();
|
||||
int receiveEvent(WEvent*);
|
||||
};
|
||||
|
||||
class GenericScryAbility : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
string howMany;
|
||||
MTGScryCards * ability;
|
||||
GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
GenericScryAbility * clone() const;
|
||||
~GenericScryAbility();
|
||||
string howMany;
|
||||
MTGScryCards * ability;
|
||||
GenericScryAbility(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string _howMany);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
GenericScryAbility * clone() const;
|
||||
~GenericScryAbility();
|
||||
|
||||
};
|
||||
|
||||
@@ -166,11 +166,11 @@ private:
|
||||
{
|
||||
if(!s.size())
|
||||
return;
|
||||
if (!card)
|
||||
{
|
||||
intValue = atoi(s.c_str());//if there is no card, try parsing a number.
|
||||
return;
|
||||
}
|
||||
if (!card)
|
||||
{
|
||||
intValue = atoi(s.c_str());//if there is no card, try parsing a number.
|
||||
return;
|
||||
}
|
||||
MTGCardInstance * target = card->target;
|
||||
if(!card->storedCard)
|
||||
card->storedCard = card->storedSourceCard;
|
||||
@@ -179,10 +179,8 @@ private:
|
||||
bool halfdown = false;
|
||||
bool twice = false;
|
||||
bool thrice = false;
|
||||
bool plusone = false;
|
||||
bool plustwo = false;
|
||||
bool plusthree = false;
|
||||
bool other = false;//othertype:[subtype]
|
||||
|
||||
if (!target) target = card;
|
||||
int multiplier = 1;
|
||||
if (s[0] == '-')
|
||||
@@ -231,24 +229,7 @@ private:
|
||||
size_t tXXX = s.find("thrice");
|
||||
s.erase(tXXX,tXXX + 6);
|
||||
}
|
||||
if(s.find("plusone") != string::npos)
|
||||
{
|
||||
plusone = true;
|
||||
size_t pOne = s.find("plusone");
|
||||
s.erase(pOne,pOne + 7);
|
||||
}
|
||||
if(s.find("plustwo") != string::npos)
|
||||
{
|
||||
plustwo = true;
|
||||
size_t pTwo = s.find("plustwo");
|
||||
s.erase(pTwo,pTwo + 7);
|
||||
}
|
||||
if(s.find("plusthree") != string::npos)
|
||||
{
|
||||
plusthree = true;
|
||||
size_t pThree = s.find("plusthree");
|
||||
s.erase(pThree,pThree + 9);
|
||||
}
|
||||
|
||||
if(s.find("othertype") != string::npos)
|
||||
{
|
||||
other = true;
|
||||
@@ -273,18 +254,58 @@ private:
|
||||
size_t otc = s.find("otherconvertedcost");
|
||||
s.erase(otc,otc + 5);
|
||||
}
|
||||
if(s == "prex")
|
||||
|
||||
if (s.find("plusend") != string::npos || s.find("minusend") != string::npos || s.find("math") != string::npos)
|
||||
{
|
||||
if (card->setX > -1)
|
||||
{
|
||||
intValue = card->setX;
|
||||
}
|
||||
else
|
||||
{
|
||||
ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost());
|
||||
intValue = cX->getCost(Constants::NB_Colors);
|
||||
delete cX;
|
||||
}
|
||||
//plus#plusend and minus#minusend splits the first part and second parts and parses the
|
||||
//ints for each part, then either adds or subtracts those 2 variables as specified.
|
||||
vector<string>mathFound = parseBetween(s, "math", "mathend", true);
|
||||
if (mathFound.size())//maths allows us to get the value before applying multipliers
|
||||
{
|
||||
WParsedInt numPar(mathFound[1], NULL, card);
|
||||
intValue = numPar.getValue();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<string>plusSplit = parseBetween(s, "", "plus", true);
|
||||
if (plusSplit.size())
|
||||
{
|
||||
WParsedInt numPar(plusSplit[1], NULL, card);
|
||||
intValue = numPar.getValue();
|
||||
}
|
||||
vector<string>plusFound = parseBetween(s, "plus", "plusend", true);
|
||||
if (plusFound.size())
|
||||
{
|
||||
WParsedInt numPar(plusFound[1], NULL, card);
|
||||
intValue += numPar.getValue();
|
||||
}
|
||||
vector<string>minusSplit = parseBetween(s, "", "minus", true);
|
||||
if (minusSplit.size())
|
||||
{
|
||||
WParsedInt numPar(minusSplit[1], NULL, card);
|
||||
intValue = numPar.getValue();
|
||||
}
|
||||
vector<string>minusFound = parseBetween(s, "minus", "minusend", true);
|
||||
if (minusFound.size())
|
||||
{
|
||||
WParsedInt numPar(minusFound[1], NULL, card);
|
||||
intValue -= numPar.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(s == "prex")
|
||||
{
|
||||
if (card->setX > -1)
|
||||
{
|
||||
intValue = card->setX;
|
||||
}
|
||||
else
|
||||
{
|
||||
ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost());
|
||||
intValue = cX->getCost(Constants::NB_Colors);
|
||||
delete cX;
|
||||
}
|
||||
}
|
||||
else if (s == "x" || s == "X")
|
||||
{
|
||||
@@ -361,10 +382,10 @@ private:
|
||||
{
|
||||
intValue = countDevotionTo(card,card->controller()->inPlay(),Constants::MTG_COLOR_BLUE,Constants::MTG_COLOR_GREEN);
|
||||
}
|
||||
else if (s == "Iroas")//devotion to red white
|
||||
{
|
||||
intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE);
|
||||
}
|
||||
else if (s == "Iroas")//devotion to red white
|
||||
{
|
||||
intValue = countDevotionTo(card, card->controller()->inPlay(), Constants::MTG_COLOR_RED, Constants::MTG_COLOR_WHITE);
|
||||
}
|
||||
else if (s.find("type:") != string::npos)
|
||||
{
|
||||
size_t begins = s.find("type:");
|
||||
@@ -681,10 +702,10 @@ private:
|
||||
{
|
||||
intValue = target->getCurrentToughness();
|
||||
}
|
||||
else if (s == "countedamount")
|
||||
{
|
||||
intValue = target->CountedObjects;
|
||||
}
|
||||
else if (s == "countedamount")
|
||||
{
|
||||
intValue = target->CountedObjects;
|
||||
}
|
||||
else if (s == "kicked")
|
||||
{
|
||||
intValue = target->kicked;
|
||||
@@ -806,12 +827,18 @@ private:
|
||||
else if (s == "pbasiclandtypes")//Basic Land types
|
||||
{
|
||||
MTGGameZone * checkZone = card->controller()->inPlay();
|
||||
intValue =
|
||||
cardHasTypeinZone("forest",checkZone) +
|
||||
cardHasTypeinZone("plains",checkZone) +
|
||||
cardHasTypeinZone("swamp",checkZone) +
|
||||
cardHasTypeinZone("island",checkZone) +
|
||||
cardHasTypeinZone("mountain",checkZone);
|
||||
intValue = //mtg rules 205.4c
|
||||
cardHasTypeinZone("waste", checkZone) +
|
||||
cardHasTypeinZone("forest", checkZone) +
|
||||
cardHasTypeinZone("plains", checkZone) +
|
||||
cardHasTypeinZone("swamp", checkZone) +
|
||||
cardHasTypeinZone("island", checkZone) +
|
||||
cardHasTypeinZone("mountain", checkZone) +
|
||||
cardHasTypeinZone("snow-covered forest", checkZone) +
|
||||
cardHasTypeinZone("snow-covered plains", checkZone) +
|
||||
cardHasTypeinZone("snow-covered swamp", checkZone) +
|
||||
cardHasTypeinZone("snow-covered island", checkZone) +
|
||||
cardHasTypeinZone("snow-covered mountain", checkZone);
|
||||
}
|
||||
else if (s == "myname")//Name of the card you control
|
||||
{
|
||||
@@ -858,13 +885,6 @@ private:
|
||||
cardHasTypeinZone("artifact",checkZone);
|
||||
}
|
||||
}
|
||||
else if (s == "morethanfourcards")
|
||||
{
|
||||
intValue = 0;
|
||||
int damage = card->playerTarget ? card->playerTarget->game->hand->nb_cards - 4 : card->controller()->opponent()->game->hand->nb_cards - 4;
|
||||
if ( damage > 0 )
|
||||
intValue = damage;
|
||||
}
|
||||
else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable
|
||||
{
|
||||
intValue = 0;
|
||||
@@ -874,55 +894,47 @@ private:
|
||||
intValue += card->controller()->game->inPlay->cards[j]->power;
|
||||
}
|
||||
}
|
||||
else if (s == "revealedp")
|
||||
{
|
||||
if (card->revealedLast)
|
||||
intValue = card->revealedLast->power;
|
||||
}
|
||||
else if (s == "revealedt")
|
||||
{
|
||||
if (card->revealedLast)
|
||||
intValue = card->revealedLast->toughness;
|
||||
}
|
||||
else if (s == "revealedmana")
|
||||
{
|
||||
if (card->revealedLast)
|
||||
intValue = card->revealedLast->getManaCost()->getConvertedCost();
|
||||
}
|
||||
else
|
||||
else if (s == "revealedp")
|
||||
{
|
||||
if (card->revealedLast)
|
||||
intValue = card->revealedLast->power;
|
||||
}
|
||||
else if (s == "revealedt")
|
||||
{
|
||||
if (card->revealedLast)
|
||||
intValue = card->revealedLast->toughness;
|
||||
}
|
||||
else if (s == "revealedmana")
|
||||
{
|
||||
if (card->revealedLast)
|
||||
intValue = card->revealedLast->getManaCost()->getConvertedCost();
|
||||
}
|
||||
else if(!intValue)//found nothing, try parsing a atoi
|
||||
{
|
||||
intValue = atoi(s.c_str());
|
||||
}
|
||||
if(intValue > 0)
|
||||
if (intValue > 0)//dont divide by 0 the rest are valid.
|
||||
{
|
||||
if(halfup)
|
||||
if (halfup)
|
||||
{
|
||||
if(intValue%2 == 1)
|
||||
if (intValue % 2 == 1)
|
||||
intValue++;
|
||||
intValue = intValue/2;
|
||||
intValue = intValue / 2;
|
||||
}
|
||||
if(halfdown)
|
||||
intValue = intValue/2;
|
||||
if(twice)
|
||||
intValue = intValue*2;
|
||||
if(thrice)
|
||||
intValue = intValue*3;
|
||||
if(plusone)
|
||||
intValue = intValue+1;
|
||||
if(plustwo)
|
||||
intValue = intValue+2;
|
||||
if(plusthree)
|
||||
intValue = intValue+3;
|
||||
if (halfdown)
|
||||
intValue = intValue / 2;
|
||||
}
|
||||
else
|
||||
if (twice)
|
||||
intValue = intValue * 2;
|
||||
if (thrice)
|
||||
intValue = intValue * 3;
|
||||
if (intValue < 0)
|
||||
{
|
||||
if(plusone)
|
||||
intValue = intValue+1;
|
||||
if(plustwo)
|
||||
intValue = intValue+2;
|
||||
if(plusthree)
|
||||
intValue = intValue+3;
|
||||
//we remove "-" at the start and are parsing for real values.
|
||||
//if we ended up with a value less than 0, then we return just 0
|
||||
intValue = 0;
|
||||
}
|
||||
|
||||
intValue *= multiplier;
|
||||
}
|
||||
public:
|
||||
@@ -3477,7 +3489,7 @@ public:
|
||||
list<int> colors;
|
||||
int power, toughness;
|
||||
int tokenId;
|
||||
string _cardName;
|
||||
string _cardName;
|
||||
string name;
|
||||
string sabilities;
|
||||
string starfound;
|
||||
@@ -3489,7 +3501,7 @@ public:
|
||||
MTGCardInstance * myToken;
|
||||
vector<MTGAbility *> currentAbilities;
|
||||
Player * tokenReciever;
|
||||
//by id
|
||||
//by id
|
||||
ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, int tokenId,string starfound, WParsedInt * multiplier = NULL,
|
||||
int who = 0,bool aLivingWeapon = false) :
|
||||
ActivatedAbility(observer, _id, _source, _cost, 0), tokenId(tokenId), starfound(starfound),multiplier(multiplier), who(who),aLivingWeapon(aLivingWeapon)
|
||||
@@ -3499,18 +3511,18 @@ public:
|
||||
if (card) name = card->data->getName();
|
||||
battleReady = false;
|
||||
}
|
||||
//by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)...
|
||||
ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL,
|
||||
int who = 0, bool aLivingWeapon = false) :
|
||||
ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon)
|
||||
{
|
||||
if (!multiplier) this->multiplier = NEW WParsedInt(1);
|
||||
MTGCard * card = MTGCollection()->getCardByName(_cardName);
|
||||
tokenId = card->getId();
|
||||
if (card) name = card->data->getName();
|
||||
battleReady = false;
|
||||
}
|
||||
//by construction
|
||||
//by name, card still require valid card.dat info, this just makes the primitive code far more readable. token(Eldrazi scion) instead of token(-1234234)...
|
||||
ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string cardName, string starfound, WParsedInt * multiplier = NULL,
|
||||
int who = 0, bool aLivingWeapon = false) :
|
||||
ActivatedAbility(observer, _id, _source, _cost, 0), _cardName(cardName), starfound(starfound), multiplier(multiplier), who(who), aLivingWeapon(aLivingWeapon)
|
||||
{
|
||||
if (!multiplier) this->multiplier = NEW WParsedInt(1);
|
||||
MTGCard * card = MTGCollection()->getCardByName(_cardName);
|
||||
tokenId = card->getId();
|
||||
if (card) name = card->data->getName();
|
||||
battleReady = false;
|
||||
}
|
||||
//by construction
|
||||
ATokenCreator(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable *, ManaCost * _cost, string sname, string stypes, int _power, int _toughness,
|
||||
string sabilities, string starfound,WParsedInt * multiplier = NULL, int _who = 0,bool aLivingWeapon = false,string spt = "") :
|
||||
ActivatedAbility(observer, _id, _source, _cost, 0),sabilities(sabilities),starfound(starfound), multiplier(multiplier), who(_who),aLivingWeapon(aLivingWeapon),spt(spt)
|
||||
@@ -4033,12 +4045,12 @@ class AThis: public MTGAbility, public NestedAbility
|
||||
public:
|
||||
MTGAbility * a;
|
||||
ThisDescriptor * td;
|
||||
string restrictionCheck;
|
||||
string restrictionCheck;
|
||||
AThis(GameObserver* observer, int _id, MTGCardInstance * _source, Damageable * _target, ThisDescriptor * _td, MTGAbility * ability, string restriction = "") :
|
||||
MTGAbility(observer, _id, _source, _target), NestedAbility(ability)
|
||||
{
|
||||
td = _td;
|
||||
restrictionCheck = restriction;
|
||||
restrictionCheck = restriction;
|
||||
ability->source = source;
|
||||
ability->target = target;
|
||||
a = NULL;
|
||||
@@ -4062,18 +4074,18 @@ public:
|
||||
|
||||
int resolve()
|
||||
{
|
||||
int match = 0;
|
||||
if (td)
|
||||
{
|
||||
match = td->match(source);
|
||||
}
|
||||
else
|
||||
{//restriction check instead of Targetchooser
|
||||
AbilityFactory abf(target->getObserver());
|
||||
int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck);
|
||||
if (checkCond)
|
||||
match = 1;
|
||||
}
|
||||
int match = 0;
|
||||
if (td)
|
||||
{
|
||||
match = td->match(source);
|
||||
}
|
||||
else
|
||||
{//restriction check instead of Targetchooser
|
||||
AbilityFactory abf(target->getObserver());
|
||||
int checkCond = abf.parseCastRestrictions(source, source->controller(), restrictionCheck);
|
||||
if (checkCond)
|
||||
match = 1;
|
||||
}
|
||||
if (match > 0)
|
||||
{
|
||||
addAbilityToGame();
|
||||
@@ -4120,7 +4132,7 @@ public:
|
||||
{
|
||||
AThis * a = NEW AThis(*this);
|
||||
a->ability = ability->clone();
|
||||
if(a->td)
|
||||
if(a->td)
|
||||
a->td = td->clone();
|
||||
return a;
|
||||
}
|
||||
@@ -4338,11 +4350,11 @@ public:
|
||||
class ABestow : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
MTGCardInstance * _card;
|
||||
ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
ABestow * clone() const;
|
||||
MTGCardInstance * _card;
|
||||
ABestow(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
ABestow * clone() const;
|
||||
};
|
||||
|
||||
/* Can tap a target for a cost */
|
||||
@@ -4369,16 +4381,16 @@ public:
|
||||
class AAWhatsX : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
int value;
|
||||
MTGAbility * costRule;
|
||||
AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL);
|
||||
int resolve();
|
||||
const string getMenuText()
|
||||
{
|
||||
sprintf(menuText, "%i", value);
|
||||
return menuText;
|
||||
};
|
||||
AAWhatsX * clone() const;
|
||||
int value;
|
||||
MTGAbility * costRule;
|
||||
AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL);
|
||||
int resolve();
|
||||
const string getMenuText()
|
||||
{
|
||||
sprintf(menuText, "%i", value);
|
||||
return menuText;
|
||||
};
|
||||
AAWhatsX * clone() const;
|
||||
};
|
||||
|
||||
/* set max level up on a levelup creature this is an Ai hint ability, no effect for players.*/
|
||||
@@ -4395,17 +4407,17 @@ public:
|
||||
class AACountObject : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
string value;
|
||||
string value;
|
||||
|
||||
AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value ="");
|
||||
int resolve();
|
||||
AACountObject * clone() const;
|
||||
AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, ManaCost * _cost = NULL, string value ="");
|
||||
int resolve();
|
||||
AACountObject * clone() const;
|
||||
};
|
||||
/* Can prevent a card from untapping next untap */
|
||||
class AAFrozen: public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
bool freeze;
|
||||
bool freeze;
|
||||
AAFrozen(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, bool tap, ManaCost * _cost = NULL);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
@@ -5196,32 +5208,32 @@ public:
|
||||
class AGrant : public MTGAbility
|
||||
{
|
||||
public:
|
||||
MTGCardInstance * Blessed;
|
||||
bool resolved;
|
||||
MTGAbility * Granted;
|
||||
MTGAbility * toGrant;
|
||||
AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant);
|
||||
void Update(float dt);
|
||||
void resolveGrant();
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
AGrant * clone() const;
|
||||
~AGrant();
|
||||
MTGCardInstance * Blessed;
|
||||
bool resolved;
|
||||
MTGAbility * Granted;
|
||||
MTGAbility * toGrant;
|
||||
AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant);
|
||||
void Update(float dt);
|
||||
void resolveGrant();
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
AGrant * clone() const;
|
||||
~AGrant();
|
||||
private:
|
||||
void removeGranted(MTGCardInstance *_target);
|
||||
void removeGranted(MTGCardInstance *_target);
|
||||
};
|
||||
|
||||
//GrantWrapper
|
||||
class AGrantWrapper : public InstantAbility
|
||||
{
|
||||
public:
|
||||
AGrant * ability;
|
||||
MTGAbility * Granted;
|
||||
AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
AGrantWrapper * clone() const;
|
||||
~AGrantWrapper();
|
||||
AGrant * ability;
|
||||
MTGAbility * Granted;
|
||||
AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
AGrantWrapper * clone() const;
|
||||
~AGrantWrapper();
|
||||
|
||||
};
|
||||
//ABlink
|
||||
@@ -6473,7 +6485,7 @@ public:
|
||||
MTGCardInstance * theNamedCard;
|
||||
bool noEvent;
|
||||
bool putinplay;
|
||||
bool asNormalMadness;
|
||||
bool asNormalMadness;
|
||||
AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay,bool asNormalMadness = false);
|
||||
|
||||
int testDestroy(){return 0;};
|
||||
|
||||
@@ -58,6 +58,10 @@ public:
|
||||
int Angel[2];
|
||||
bool dragonbonusgranted[2];
|
||||
int dragon[2];
|
||||
bool eldrazibonusgranted[2];
|
||||
int eldrazi[2];
|
||||
bool werewolfbonusgranted[2];
|
||||
int werewolf[2];
|
||||
|
||||
int receiveEvent(WEvent * event);
|
||||
void grantAward(string awardName,int amount);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -251,7 +251,7 @@ int Damage::resolve()
|
||||
target->lifeLostThisTurn += damage;
|
||||
if ( typeOfDamage == 1 && target == source->controller()->opponent() )//add vector prowledtypes.
|
||||
{
|
||||
vector<string> values = MTGAllCards::getCreatureValuesById();
|
||||
vector<string> values = MTGAllCards::getCreatureValuesById();//getting a weird crash here. rarely.
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
if ( source->hasSubtype( values[i] ) && find(source->controller()->prowledTypes.begin(), source->controller()->prowledTypes.end(), values[i])==source->controller()->prowledTypes.end() )
|
||||
|
||||
@@ -1057,208 +1057,115 @@ void GameObserver::Affinity()
|
||||
if (!card)
|
||||
continue;
|
||||
|
||||
///////////////////////////
|
||||
//reset extracost shadows//
|
||||
///////////////////////////
|
||||
card->isExtraCostTarget = false;
|
||||
if (mExtraPayment != NULL)
|
||||
{
|
||||
for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++)
|
||||
{
|
||||
|
||||
if (mExtraPayment->costs[ec]->tc)
|
||||
{
|
||||
vector<Targetable*>targetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom();
|
||||
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||
{
|
||||
Targetable * cardMasked = *it;
|
||||
dynamic_cast<MTGCardInstance*>(cardMasked)->isExtraCostTarget = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
////////////////////////////
|
||||
bool NewAffinityFound = false;
|
||||
for (unsigned int na = 0; na < card->cardsAbilities.size(); na++)
|
||||
{
|
||||
if (!card->cardsAbilities[na])
|
||||
break;
|
||||
ANewAffinity * newAff = dynamic_cast<ANewAffinity*>(card->cardsAbilities[na]);
|
||||
if (newAff)
|
||||
{
|
||||
NewAffinityFound = true;
|
||||
}
|
||||
}
|
||||
bool DoReduceIncrease = false;
|
||||
if (card->has(Constants::AFFINITYARTIFACTS) ||
|
||||
card->has(Constants::AFFINITYFOREST) ||
|
||||
card->has(Constants::AFFINITYGREENCREATURES) ||
|
||||
card->has(Constants::AFFINITYISLAND) ||
|
||||
card->has(Constants::AFFINITYMOUNTAIN) ||
|
||||
card->has(Constants::AFFINITYPLAINS) ||
|
||||
card->has(Constants::AFFINITYSWAMP) ||
|
||||
card->has(Constants::TRINISPHERE) ||
|
||||
card->getIncreasedManaCost()->getConvertedCost() ||
|
||||
card->getReducedManaCost()->getConvertedCost() ||
|
||||
NewAffinityFound)
|
||||
DoReduceIncrease = true;
|
||||
if (!DoReduceIncrease)
|
||||
continue;
|
||||
//above we check if there are even any cards that effect cards manacost
|
||||
//if there are none, leave this function. manacost->copy( is a very expensive funtion
|
||||
//1mb a sec to run at all time even when no known reducers or increasers are in play.
|
||||
//memory snapshot shots pointed to this as such a heavy load that games with many cards inplay
|
||||
//would slow to a crawl.
|
||||
//only do any of the following if a card with the stated ability is in your hand.
|
||||
int color = 0;
|
||||
string type = "";
|
||||
|
||||
ManaCost * original = NEW ManaCost();
|
||||
original->copy(card->model->data->getManaCost());
|
||||
if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost())
|
||||
{//start1
|
||||
if(card->getIncreasedManaCost()->getConvertedCost())
|
||||
original->add(card->getIncreasedManaCost());
|
||||
if(card->getReducedManaCost()->getConvertedCost())
|
||||
original->remove(card->getReducedManaCost());
|
||||
if(card->getManaCost())
|
||||
card->getManaCost()->copy(original);
|
||||
if(card->getManaCost()->extraCosts)
|
||||
///////////////////////////
|
||||
//reset extracost shadows//
|
||||
///////////////////////////
|
||||
card->isExtraCostTarget = false;
|
||||
if (mExtraPayment != NULL)
|
||||
{
|
||||
for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++)
|
||||
{
|
||||
for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++)
|
||||
|
||||
if (mExtraPayment->costs[ec]->tc)
|
||||
{
|
||||
card->getManaCost()->extraCosts->costs[i]->setSource(card);
|
||||
vector<Targetable*>targetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom();
|
||||
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||
{
|
||||
Targetable * cardMasked = *it;
|
||||
dynamic_cast<MTGCardInstance*>(cardMasked)->isExtraCostTarget = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}//end1
|
||||
int reducem = 0;
|
||||
bool resetCost = false;
|
||||
for(unsigned int na = 0; na < card->cardsAbilities.size();na++)
|
||||
{//start2
|
||||
if (!card->cardsAbilities[na])
|
||||
break;
|
||||
}
|
||||
////////////////////////////
|
||||
bool NewAffinityFound = false;
|
||||
for (unsigned int na = 0; na < card->cardsAbilities.size(); na++)
|
||||
{
|
||||
if (!card->cardsAbilities[na])
|
||||
break;
|
||||
ANewAffinity * newAff = dynamic_cast<ANewAffinity*>(card->cardsAbilities[na]);
|
||||
if(newAff)
|
||||
if (newAff)
|
||||
{
|
||||
if(!resetCost)
|
||||
{
|
||||
resetCost = true;
|
||||
card->getManaCost()->copy(original);
|
||||
if(card->getManaCost()->extraCosts)
|
||||
{
|
||||
for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++)
|
||||
{
|
||||
card->getManaCost()->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
TargetChooserFactory tf(this);
|
||||
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL);
|
||||
NewAffinityFound = true;
|
||||
}
|
||||
}
|
||||
bool DoReduceIncrease = false;
|
||||
if (card->has(Constants::AFFINITYARTIFACTS) ||
|
||||
card->has(Constants::AFFINITYFOREST) ||
|
||||
card->has(Constants::AFFINITYGREENCREATURES) ||
|
||||
card->has(Constants::AFFINITYISLAND) ||
|
||||
card->has(Constants::AFFINITYMOUNTAIN) ||
|
||||
card->has(Constants::AFFINITYPLAINS) ||
|
||||
card->has(Constants::AFFINITYSWAMP) ||
|
||||
card->has(Constants::TRINISPHERE) ||
|
||||
card->getIncreasedManaCost()->getConvertedCost() ||
|
||||
card->getReducedManaCost()->getConvertedCost() ||
|
||||
NewAffinityFound)
|
||||
DoReduceIncrease = true;
|
||||
if (!DoReduceIncrease)
|
||||
continue;
|
||||
//above we check if there are even any cards that effect cards manacost
|
||||
//if there are none, leave this function. manacost->copy( is a very expensive funtion
|
||||
//1mb a sec to run at all time even when no known reducers or increasers are in play.
|
||||
//memory snapshot shots pointed to this as such a heavy load that games with many cards inplay
|
||||
//would slow to a crawl.
|
||||
//only do any of the following if a card with the stated ability is in your hand.
|
||||
//kicker is an addon to normal cost, suspend is not casting. add cost as needed EXACTLY as seen below.
|
||||
card->getManaCost()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost()));
|
||||
card->getManaCost()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
if (card->getManaCost()->getAlternative())
|
||||
{
|
||||
card->getManaCost()->getAlternative()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative()));
|
||||
card->getManaCost()->getAlternative()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
}
|
||||
if (card->getManaCost()->getBestow())
|
||||
{
|
||||
card->getManaCost()->getBestow()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow()));
|
||||
card->getManaCost()->getBestow()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
}
|
||||
if (card->getManaCost()->getRetrace())
|
||||
{
|
||||
card->getManaCost()->getRetrace()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace()));
|
||||
card->getManaCost()->getRetrace()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
}
|
||||
if (card->getManaCost()->getBuyback())
|
||||
{
|
||||
card->getManaCost()->getBuyback()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback()));
|
||||
card->getManaCost()->getBuyback()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
}
|
||||
if (card->getManaCost()->getFlashback())
|
||||
{
|
||||
card->getManaCost()->getFlashback()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback()));
|
||||
card->getManaCost()->getFlashback()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
}
|
||||
if (card->getManaCost()->getMorph())
|
||||
{
|
||||
card->getManaCost()->getMorph()->resetCosts();
|
||||
ManaCost * newCost = NEW ManaCost();
|
||||
newCost->copy(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph()));
|
||||
card->getManaCost()->getMorph()->copy(newCost);
|
||||
SAFE_DELETE(newCost);
|
||||
}
|
||||
|
||||
for (int w = 0; w < 2; ++w)
|
||||
{
|
||||
Player *p = this->players[w];
|
||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile };
|
||||
for (int k = 0; k < 6; k++)
|
||||
{
|
||||
MTGGameZone * z = zones[k];
|
||||
if (tcn->targetsZone(z))
|
||||
{
|
||||
reducem += z->countByCanTarget(tcn);
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_DELETE(tcn);
|
||||
ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString);
|
||||
for(int j = 0; j < reducem; j++)
|
||||
card->getManaCost()->remove(removingCost);
|
||||
SAFE_DELETE(removingCost);
|
||||
}
|
||||
}//end2
|
||||
if(card->has(Constants::AFFINITYARTIFACTS)||
|
||||
card->has(Constants::AFFINITYFOREST)||
|
||||
card->has(Constants::AFFINITYGREENCREATURES)||
|
||||
card->has(Constants::AFFINITYISLAND)||
|
||||
card->has(Constants::AFFINITYMOUNTAIN)||
|
||||
card->has(Constants::AFFINITYPLAINS)||
|
||||
card->has(Constants::AFFINITYSWAMP))
|
||||
{//start3
|
||||
if (card->has(Constants::AFFINITYARTIFACTS))
|
||||
{
|
||||
type = "artifact";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYSWAMP))
|
||||
{
|
||||
type = "swamp";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYMOUNTAIN))
|
||||
{
|
||||
type = "mountain";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYPLAINS))
|
||||
{
|
||||
type = "plains";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYISLAND))
|
||||
{
|
||||
type = "island";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYFOREST))
|
||||
{
|
||||
type = "forest";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
color = 1;
|
||||
type = "creature";
|
||||
}
|
||||
card->getManaCost()->copy(original);
|
||||
if(card->getManaCost()->extraCosts)
|
||||
{
|
||||
for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++)
|
||||
{
|
||||
card->getManaCost()->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
}
|
||||
int reduce = 0;
|
||||
if(card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(this);
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL);
|
||||
reduce = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else
|
||||
{
|
||||
reduce = card->controller()->game->battlefield->countByType(type);
|
||||
}
|
||||
for(int i = 0; i < reduce;i++)
|
||||
{
|
||||
if(card->getManaCost()->getCost(color) > 0)
|
||||
card->getManaCost()->remove(color,1);
|
||||
}
|
||||
}//end3
|
||||
//trinisphere... now how to implement kicker recomputation
|
||||
|
||||
if(card->has(Constants::TRINISPHERE))
|
||||
{
|
||||
for(int jj = card->getManaCost()->getConvertedCost(); jj < 3; jj++)
|
||||
{
|
||||
card->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1);
|
||||
card->countTrini++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(card->countTrini)
|
||||
{
|
||||
card->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini);
|
||||
card->countTrini=0;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_DELETE(original);
|
||||
}//end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to
|
||||
cardistargetted = 0;
|
||||
cardistargetter = 0;
|
||||
myconvertedcost = getManaCost()->getConvertedCost();
|
||||
revealedLast = NULL;
|
||||
MadnessPlay = false;
|
||||
revealedLast = NULL;
|
||||
MadnessPlay = false;
|
||||
}
|
||||
|
||||
MTGCardInstance * MTGCardInstance::createSnapShot()
|
||||
@@ -153,14 +153,14 @@ int MTGCardInstance::init()
|
||||
data = this;
|
||||
X = 0;
|
||||
castX = 0;
|
||||
setX = -1;
|
||||
setX = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MTGCardInstance::initMTGCI()
|
||||
{
|
||||
X = 0;
|
||||
setX = -1;
|
||||
setX = -1;
|
||||
sample = "";
|
||||
model = NULL;
|
||||
isToken = false;
|
||||
@@ -198,7 +198,7 @@ void MTGCardInstance::initMTGCI()
|
||||
wasDealtDamage = false;
|
||||
isDualWielding = false;
|
||||
suspended = false;
|
||||
isBestowed = false;
|
||||
isBestowed = false;
|
||||
castMethod = Constants::NOT_CAST;
|
||||
mPropertiesChangedSinceLastUpdate = false;
|
||||
stillNeeded = true;
|
||||
@@ -228,7 +228,7 @@ void MTGCardInstance::initMTGCI()
|
||||
imprintW = 0;
|
||||
currentimprintName = "";
|
||||
imprintedNames.clear();
|
||||
CountedObjects = 0;
|
||||
CountedObjects = 0;
|
||||
|
||||
for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++)
|
||||
alternateCostPaid[i] = 0;
|
||||
@@ -782,8 +782,8 @@ int MTGCardInstance::getCurrentToughness()
|
||||
//check stack
|
||||
bool MTGCardInstance::StackIsEmptyandSorcerySpeed()
|
||||
{
|
||||
Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current.
|
||||
Player * whoCurrent = getObserver()->currentPlayer;
|
||||
Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current.
|
||||
Player * whoCurrent = getObserver()->currentPlayer;
|
||||
if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) &&
|
||||
(getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN ||
|
||||
getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) &&
|
||||
@@ -961,121 +961,156 @@ JQuadPtr MTGCardInstance::getIcon()
|
||||
return WResourceManager::Instance()->RetrieveCard(this, CACHE_THUMB);
|
||||
}
|
||||
|
||||
ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * newCost, ManaCost * refCost, bool noTrinisphere)
|
||||
ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cost, ManaCost * Data, bool noTrinisphere)
|
||||
{
|
||||
if(!card)
|
||||
return NULL;
|
||||
|
||||
if(card->getIncreasedManaCost()->getConvertedCost())
|
||||
newCost->add(card->getIncreasedManaCost());
|
||||
if(card->getReducedManaCost()->getConvertedCost())
|
||||
newCost->remove(card->getReducedManaCost());
|
||||
if(refCost->extraCosts)
|
||||
newCost->extraCosts = refCost->extraCosts;
|
||||
//affinity
|
||||
int color = 0;
|
||||
string type = "";
|
||||
ManaCost * original = NEW ManaCost();
|
||||
original->copy(newCost);
|
||||
|
||||
int reducem = 0;
|
||||
bool resetCost = false;
|
||||
for(unsigned int na = 0; na < card->cardsAbilities.size();na++)
|
||||
{//start2
|
||||
ANewAffinity * newAff = dynamic_cast<ANewAffinity*>(card->cardsAbilities[na]);
|
||||
if(newAff)
|
||||
{
|
||||
if(!resetCost)
|
||||
{
|
||||
resetCost = true;
|
||||
newCost->copy(original);
|
||||
}
|
||||
TargetChooserFactory tf(observer);
|
||||
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL);
|
||||
int color = 0;
|
||||
string type = "";
|
||||
ManaCost * original = NEW ManaCost();
|
||||
original->copy(Data);
|
||||
if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost())
|
||||
{//start1
|
||||
if (card->getIncreasedManaCost()->getConvertedCost())
|
||||
original->add(card->getIncreasedManaCost());
|
||||
if (card->getReducedManaCost()->getConvertedCost())
|
||||
original->remove(card->getReducedManaCost());
|
||||
|
||||
for (int w = 0; w < 2; ++w)
|
||||
Cost->copy(original);
|
||||
if (Cost->extraCosts)
|
||||
{
|
||||
for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
Cost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
}
|
||||
}//end1
|
||||
int reducem = 0;
|
||||
bool resetCost = false;
|
||||
for (unsigned int na = 0; na < card->cardsAbilities.size(); na++)
|
||||
{//start2
|
||||
if (!card->cardsAbilities[na])
|
||||
break;
|
||||
ANewAffinity * newAff = dynamic_cast<ANewAffinity*>(card->cardsAbilities[na]);
|
||||
if (newAff)
|
||||
{
|
||||
if (!resetCost)
|
||||
{
|
||||
resetCost = true;
|
||||
Cost->copy(original);
|
||||
if (Cost->extraCosts)
|
||||
{
|
||||
Player *p = observer->players[w];
|
||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile };
|
||||
for (int k = 0; k < 6; k++)
|
||||
for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
MTGGameZone * z = zones[k];
|
||||
if (tcn->targetsZone(z))
|
||||
reducem += z->countByCanTarget(tcn);
|
||||
Cost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
}
|
||||
SAFE_DELETE(tcn);
|
||||
ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString);
|
||||
for(int j = 0; j < reducem; j++)
|
||||
newCost->remove(removingCost);
|
||||
SAFE_DELETE(removingCost);
|
||||
}
|
||||
}//end2
|
||||
if(card->has(Constants::AFFINITYARTIFACTS)||
|
||||
card->has(Constants::AFFINITYFOREST)||
|
||||
card->has(Constants::AFFINITYGREENCREATURES)||
|
||||
card->has(Constants::AFFINITYISLAND)||
|
||||
card->has(Constants::AFFINITYMOUNTAIN)||
|
||||
card->has(Constants::AFFINITYPLAINS)||
|
||||
card->has(Constants::AFFINITYSWAMP))
|
||||
{//start3
|
||||
if (card->has(Constants::AFFINITYARTIFACTS))
|
||||
type = "artifact";
|
||||
else if (card->has(Constants::AFFINITYSWAMP))
|
||||
type = "swamp";
|
||||
else if (card->has(Constants::AFFINITYMOUNTAIN))
|
||||
type = "mountain";
|
||||
else if (card->has(Constants::AFFINITYPLAINS))
|
||||
type = "plains";
|
||||
else if (card->has(Constants::AFFINITYISLAND))
|
||||
type = "island";
|
||||
else if (card->has(Constants::AFFINITYFOREST))
|
||||
type = "forest";
|
||||
else if (card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
color = 1;
|
||||
type = "creature";
|
||||
}
|
||||
newCost->copy(original);
|
||||
int reduce = 0;
|
||||
if(card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(observer);
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL);
|
||||
reduce = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else
|
||||
reduce = card->controller()->game->battlefield->countByType(type);
|
||||
for(int i = 0; i < reduce;i++)
|
||||
if(newCost->getCost(color) > 0)
|
||||
newCost->remove(color,1);
|
||||
}//end3
|
||||
|
||||
if(!noTrinisphere)
|
||||
{
|
||||
//trinisphere... now how to implement kicker recomputation
|
||||
if(card->has(Constants::TRINISPHERE))
|
||||
{
|
||||
for(int jj = newCost->getConvertedCost(); jj < 3; jj++)
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL);
|
||||
|
||||
for (int w = 0; w < 2; ++w)
|
||||
{
|
||||
newCost->add(Constants::MTG_COLOR_ARTIFACT, 1);
|
||||
card->countTrini++;
|
||||
Player *p = getObserver()->players[w];
|
||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile };
|
||||
for (int k = 0; k < 6; k++)
|
||||
{
|
||||
MTGGameZone * z = zones[k];
|
||||
if (tcn->targetsZone(z))
|
||||
{
|
||||
reducem += z->countByCanTarget(tcn);
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_DELETE(tcn);
|
||||
ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString);
|
||||
for (int j = 0; j < reducem; j++)
|
||||
original->remove(removingCost);
|
||||
SAFE_DELETE(removingCost);
|
||||
}
|
||||
}//end2
|
||||
if (card->has(Constants::AFFINITYARTIFACTS) ||
|
||||
card->has(Constants::AFFINITYFOREST) ||
|
||||
card->has(Constants::AFFINITYGREENCREATURES) ||
|
||||
card->has(Constants::AFFINITYISLAND) ||
|
||||
card->has(Constants::AFFINITYMOUNTAIN) ||
|
||||
card->has(Constants::AFFINITYPLAINS) ||
|
||||
card->has(Constants::AFFINITYSWAMP))
|
||||
{//start3
|
||||
if (card->has(Constants::AFFINITYARTIFACTS))
|
||||
{
|
||||
type = "artifact";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYSWAMP))
|
||||
{
|
||||
type = "swamp";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYMOUNTAIN))
|
||||
{
|
||||
type = "mountain";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYPLAINS))
|
||||
{
|
||||
type = "plains";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYISLAND))
|
||||
{
|
||||
type = "island";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYFOREST))
|
||||
{
|
||||
type = "forest";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
color = 1;
|
||||
type = "creature";
|
||||
}
|
||||
|
||||
Cost->copy(original);
|
||||
if (Cost->extraCosts)
|
||||
{
|
||||
for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
Cost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
}
|
||||
int reduce = 0;
|
||||
if (card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[green]", NULL);
|
||||
reduce = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(card->countTrini)
|
||||
{
|
||||
newCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini);
|
||||
card->countTrini=0;
|
||||
}
|
||||
reduce = card->controller()->game->battlefield->countByType(type);
|
||||
}
|
||||
for (int i = 0; i < reduce; i++)
|
||||
{
|
||||
if (Cost->getCost(color) > 0)
|
||||
Cost->remove(color, 1);
|
||||
}
|
||||
}//end3
|
||||
//trinisphere... now how to implement kicker recomputation
|
||||
|
||||
if (card->has(Constants::TRINISPHERE))
|
||||
{
|
||||
for (int jj = Cost->getConvertedCost(); jj < 3; jj++)
|
||||
{
|
||||
Cost->add(Constants::MTG_COLOR_ARTIFACT, 1);
|
||||
card->countTrini++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (card->countTrini)
|
||||
{
|
||||
Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini);
|
||||
card->countTrini = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_DELETE(original);
|
||||
|
||||
return newCost;
|
||||
return Cost;
|
||||
}
|
||||
|
||||
MTGCardInstance * MTGCardInstance::getNextPartner()
|
||||
|
||||
@@ -49,6 +49,10 @@ PermanentAbility(observer, _id)
|
||||
Angel[i] = 0;
|
||||
dragonbonusgranted[i] = false;
|
||||
dragon[i] = 0;
|
||||
eldrazibonusgranted[i] = false;
|
||||
eldrazi[i] = 0;
|
||||
werewolfbonusgranted[i] = false;
|
||||
werewolf[i] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -171,6 +175,10 @@ int MTGEventBonus::receiveEvent(WEvent * event)
|
||||
Angel[currentPlayer->getId()]++;
|
||||
if(e->card->hasType("dragon")||e->card->hasType("wurm")||e->card->hasType("drake")||e->card->hasType("snake")||e->card->hasType("hydra"))
|
||||
dragon[currentPlayer->getId()]++;
|
||||
if (e->card->hasType("eldrazi"))
|
||||
eldrazi[currentPlayer->getId()]++;
|
||||
if (e->card->hasType("werewolf") || e->card->hasType("wolf"))
|
||||
werewolf[currentPlayer->getId()]++;
|
||||
}
|
||||
if(toys[currentPlayer->getId()] > 30 && !toybonusgranted[currentPlayer->getId()])
|
||||
{
|
||||
@@ -228,6 +236,16 @@ int MTGEventBonus::receiveEvent(WEvent * event)
|
||||
grantAward("Teeth And Scales!",300);
|
||||
dragonbonusgranted[currentPlayer->getId()] = true;
|
||||
}
|
||||
if (eldrazi[currentPlayer->getId()] > 30 && !eldrazibonusgranted[currentPlayer->getId()])
|
||||
{
|
||||
grantAward("Colorblind!", 300);
|
||||
eldrazibonusgranted[currentPlayer->getId()] = true;
|
||||
}
|
||||
if (werewolf[currentPlayer->getId()] > 30 && !werewolfbonusgranted[currentPlayer->getId()])
|
||||
{
|
||||
grantAward("Full Moon!", 300);
|
||||
werewolfbonusgranted[currentPlayer->getId()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//bonus for dealing 100+ damage from a single source
|
||||
@@ -365,65 +383,65 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
|
||||
return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * cost = card->getManaCost();
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
///////announce X cost///////
|
||||
if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1)
|
||||
{
|
||||
vector<MTGAbility*>selection;
|
||||
int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1;
|
||||
//you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would
|
||||
//give me the correct amount sorry.
|
||||
for (int i = 0; i < options; ++i)
|
||||
{
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
///////announce X cost///////
|
||||
if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1)
|
||||
{
|
||||
vector<MTGAbility*>selection;
|
||||
int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1;
|
||||
//you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would
|
||||
//give me the correct amount sorry.
|
||||
for (int i = 0; i < options; ++i)
|
||||
{
|
||||
|
||||
MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this);
|
||||
MTGAbility * setCardX = setX->clone();
|
||||
setCardX->oneShot = true;
|
||||
selection.push_back(setCardX);
|
||||
SAFE_DELETE(setX);
|
||||
}
|
||||
if (selection.size())
|
||||
{
|
||||
MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection);
|
||||
game->mLayers->actionLayer()->currentActionCard = card;
|
||||
a1->resolve();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//////X is set, below we set sunburst for X if needed and cast or reset the card.//////
|
||||
//////107.3a If a spell or activated ability has a mana cost, alternative cost, //////
|
||||
//////additional cost, and / or activation cost with an{ X }, [-X], or X in it, //////
|
||||
//////and the value of X isn’t defined by the text of that spell or ability, the //////
|
||||
//////controller of that spell or ability chooses and announces the value of X as//////
|
||||
//////part of casting the spell or activating the ability. //////
|
||||
//////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in //////
|
||||
//////its mana cost or in any alternative cost or additional cost it has equals //////
|
||||
//////the announced value.While an activated ability is on the stack, any X in //////
|
||||
//////its activation cost equals the announced value. //////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
if (card->setX > -1)
|
||||
{
|
||||
ManaCost * Xcost = NEW ManaCost();
|
||||
Xcost->copy(cost);
|
||||
Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX);
|
||||
Xcost->remove(7, 1);
|
||||
if (playerMana->canAfford(Xcost))
|
||||
{
|
||||
cost->copy(Xcost);
|
||||
SAFE_DELETE(Xcost);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (card->setX > -1)
|
||||
card->setX = -1;
|
||||
SAFE_DELETE(Xcost);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////
|
||||
////cards without X contenue from here////
|
||||
//////////////////////////////////////////
|
||||
MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this);
|
||||
MTGAbility * setCardX = setX->clone();
|
||||
setCardX->oneShot = true;
|
||||
selection.push_back(setCardX);
|
||||
SAFE_DELETE(setX);
|
||||
}
|
||||
if (selection.size())
|
||||
{
|
||||
MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection);
|
||||
game->mLayers->actionLayer()->currentActionCard = card;
|
||||
a1->resolve();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//////X is set, below we set sunburst for X if needed and cast or reset the card.//////
|
||||
//////107.3a If a spell or activated ability has a mana cost, alternative cost, //////
|
||||
//////additional cost, and / or activation cost with an{ X }, [-X], or X in it, //////
|
||||
//////and the value of X isn’t defined by the text of that spell or ability, the //////
|
||||
//////controller of that spell or ability chooses and announces the value of X as//////
|
||||
//////part of casting the spell or activating the ability. //////
|
||||
//////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in //////
|
||||
//////its mana cost or in any alternative cost or additional cost it has equals //////
|
||||
//////the announced value.While an activated ability is on the stack, any X in //////
|
||||
//////its activation cost equals the announced value. //////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
if (card->setX > -1)
|
||||
{
|
||||
ManaCost * Xcost = NEW ManaCost();
|
||||
Xcost->copy(cost);
|
||||
Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX);
|
||||
Xcost->remove(7, 1);
|
||||
if (playerMana->canAfford(Xcost))
|
||||
{
|
||||
cost->copy(Xcost);
|
||||
SAFE_DELETE(Xcost);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (card->setX > -1)
|
||||
card->setX = -1;
|
||||
SAFE_DELETE(Xcost);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////
|
||||
////cards without X contenue from here////
|
||||
//////////////////////////////////////////
|
||||
//this handles extra cost payments at the moment a card is played.
|
||||
if (cost->isExtraPaymentSet())
|
||||
{
|
||||
@@ -438,7 +456,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
|
||||
game->mExtraPayment = cost->extraCosts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
|
||||
int payResult = player->getManaPool()->pay(card->getManaCost());
|
||||
if (card->getManaCost()->getKicker() && (OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number || card->controller()->isAI()))
|
||||
@@ -552,9 +570,9 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
ManaCost * withKickerCost= NEW ManaCost(card->getManaCost());
|
||||
withKickerCost->add(card->getManaCost()->getKicker());
|
||||
//cost reduction/recalculation must be here or outside somehow...
|
||||
//no recalculations beyound this point, reactToClick is the function that
|
||||
//happens only with the assumption that you could actually pay for it, any calculations after will
|
||||
//have negitive effects. this function is basically "can i play this card?"
|
||||
//no recalculations beyound this point, reactToClick is the function that
|
||||
//happens only with the assumption that you could actually pay for it, any calculations after will
|
||||
//have negitive effects. this function is basically "can i play this card?"
|
||||
#ifdef WIN32
|
||||
withKickerCost->Dump();
|
||||
#endif
|
||||
@@ -691,7 +709,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
|
||||
return 0;//overload has its own rule
|
||||
if(!card->getManaCost()->getAlternative())
|
||||
return 0;
|
||||
ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative());
|
||||
ManaCost * alternateCost = card->getManaCost()->getAlternative();
|
||||
if(alternateCost->extraCosts)
|
||||
for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -755,7 +773,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card)
|
||||
if ( !isReactingToClick(card))
|
||||
return 0;
|
||||
|
||||
ManaCost * alternateCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getAlternative()),card->getManaCost()->getAlternative());
|
||||
ManaCost * alternateCost = card->getManaCost()->getAlternative();
|
||||
card->paymenttype = MTGAbility::ALTERNATIVE_COST;
|
||||
if(alternateCost->extraCosts)
|
||||
for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++)
|
||||
@@ -769,61 +787,61 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter
|
||||
|
||||
Player * player = game->currentlyActing();
|
||||
ManaPool * playerMana = player->getManaPool();
|
||||
///////announce X cost///////
|
||||
if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1)
|
||||
{
|
||||
vector<MTGAbility*>selection;
|
||||
int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1;
|
||||
//you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would
|
||||
//give me the correct amount sorry.
|
||||
for (int i = 0; i < options; ++i)
|
||||
{
|
||||
///////announce X cost///////
|
||||
if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1)
|
||||
{
|
||||
vector<MTGAbility*>selection;
|
||||
int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1;
|
||||
//you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would
|
||||
//give me the correct amount sorry.
|
||||
for (int i = 0; i < options; ++i)
|
||||
{
|
||||
|
||||
MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this);
|
||||
MTGAbility * setCardX = setX->clone();
|
||||
setCardX->oneShot = true;
|
||||
selection.push_back(setCardX);
|
||||
SAFE_DELETE(setX);
|
||||
}
|
||||
if (selection.size())
|
||||
{
|
||||
MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection);
|
||||
game->mLayers->actionLayer()->currentActionCard = card;
|
||||
a1->resolve();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//////X is set, below we set sunburst for X if needed and cast or reset the card.//////
|
||||
//////107.3a If a spell or activated ability has a mana cost, alternative cost, //////
|
||||
//////additional cost, and / or activation cost with an{ X }, [-X], or X in it, //////
|
||||
//////and the value of X isn’t defined by the text of that spell or ability, the //////
|
||||
//////controller of that spell or ability chooses and announces the value of X as//////
|
||||
//////part of casting the spell or activating the ability. //////
|
||||
//////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in //////
|
||||
//////its mana cost or in any alternative cost or additional cost it has equals //////
|
||||
//////the announced value.While an activated ability is on the stack, any X in //////
|
||||
//////its activation cost equals the announced value. //////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
if (card->setX > -1)
|
||||
{
|
||||
ManaCost * Xcost = NEW ManaCost();
|
||||
Xcost->copy(alternateCost);
|
||||
Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX);
|
||||
Xcost->remove(7, 1);//remove the X
|
||||
if (playerMana->canAfford(Xcost))
|
||||
{
|
||||
alternateCost->copy(Xcost);
|
||||
SAFE_DELETE(Xcost);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (card->setX > -1)
|
||||
card->setX = -1;
|
||||
SAFE_DELETE(Xcost);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this);
|
||||
MTGAbility * setCardX = setX->clone();
|
||||
setCardX->oneShot = true;
|
||||
selection.push_back(setCardX);
|
||||
SAFE_DELETE(setX);
|
||||
}
|
||||
if (selection.size())
|
||||
{
|
||||
MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection);
|
||||
game->mLayers->actionLayer()->currentActionCard = card;
|
||||
a1->resolve();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//////X is set, below we set sunburst for X if needed and cast or reset the card.//////
|
||||
//////107.3a If a spell or activated ability has a mana cost, alternative cost, //////
|
||||
//////additional cost, and / or activation cost with an{ X }, [-X], or X in it, //////
|
||||
//////and the value of X isn’t defined by the text of that spell or ability, the //////
|
||||
//////controller of that spell or ability chooses and announces the value of X as//////
|
||||
//////part of casting the spell or activating the ability. //////
|
||||
//////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in //////
|
||||
//////its mana cost or in any alternative cost or additional cost it has equals //////
|
||||
//////the announced value.While an activated ability is on the stack, any X in //////
|
||||
//////its activation cost equals the announced value. //////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
if (card->setX > -1)
|
||||
{
|
||||
ManaCost * Xcost = NEW ManaCost();
|
||||
Xcost->copy(alternateCost);
|
||||
Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX);
|
||||
Xcost->remove(7, 1);//remove the X
|
||||
if (playerMana->canAfford(Xcost))
|
||||
{
|
||||
alternateCost->copy(Xcost);
|
||||
SAFE_DELETE(Xcost);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (card->setX > -1)
|
||||
card->setX = -1;
|
||||
SAFE_DELETE(Xcost);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//this handles extra cost payments at the moment a card is played.
|
||||
|
||||
@@ -880,7 +898,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter
|
||||
{
|
||||
|
||||
ManaCost * c = spellCost->Diff(alternateCost);
|
||||
copy->X = card->setX;
|
||||
copy->X = card->setX;
|
||||
copy->castX = copy->X;
|
||||
delete c;
|
||||
}
|
||||
@@ -924,7 +942,7 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
return 0;
|
||||
if(!card->getManaCost()->getBuyback())
|
||||
return 0;
|
||||
ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback());
|
||||
ManaCost * buybackCost = card->getManaCost()->getBuyback();
|
||||
if(buybackCost->extraCosts)
|
||||
for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -938,7 +956,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card)
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
|
||||
ManaCost * buybackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getBuyback()),card->getManaCost()->getBuyback());
|
||||
ManaCost * buybackCost = card->getManaCost()->getBuyback();
|
||||
if(buybackCost->extraCosts)
|
||||
for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -978,7 +996,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
return 0;
|
||||
if(!card->getManaCost()->getFlashback())
|
||||
return 0;
|
||||
ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback());
|
||||
ManaCost * flashbackCost = card->getManaCost()->getFlashback();
|
||||
if(flashbackCost->extraCosts)
|
||||
for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -989,7 +1007,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
|
||||
int MTGFlashBackRule::reactToClick(MTGCardInstance * card)
|
||||
{
|
||||
ManaCost * flashbackCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getFlashback()),card->getManaCost()->getFlashback());
|
||||
ManaCost * flashbackCost = card->getManaCost()->getFlashback();
|
||||
if(flashbackCost->extraCosts)
|
||||
for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -1031,17 +1049,17 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
Player * player = game->currentlyActing();
|
||||
if(!card->getManaCost()->getRetrace())
|
||||
return 0;
|
||||
ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace());
|
||||
if (!player->game->graveyard->hasCard(card))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
auto retraceCost = card->getManaCost()->getRetrace();
|
||||
if(retraceCost->extraCosts)
|
||||
for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
retraceCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
|
||||
if (!player->game->graveyard->hasCard(card))
|
||||
return 0;
|
||||
|
||||
return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost );
|
||||
}
|
||||
return MTGAlternativeCostRule::isReactingToClick( card, mana, retraceCost);
|
||||
}
|
||||
|
||||
|
||||
@@ -1050,7 +1068,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card)
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
|
||||
ManaCost * retraceCost = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getRetrace()),card->getManaCost()->getRetrace());
|
||||
ManaCost * retraceCost = card->getManaCost()->getRetrace();
|
||||
if(retraceCost->extraCosts)
|
||||
for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -1227,7 +1245,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY)
|
||||
return 0;
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph());
|
||||
ManaCost * morph = card->getManaCost()->getMorph();
|
||||
if(morph->extraCosts)
|
||||
for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -1256,7 +1274,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card)
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * cost = card->getManaCost();
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
ManaCost * morph = card->computeNewCost(card,NEW ManaCost(card->model->data->getManaCost()->getMorph()),card->getManaCost()->getMorph());
|
||||
ManaCost * morph = card->getManaCost()->getMorph();
|
||||
if(morph->extraCosts)
|
||||
for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -1346,23 +1364,26 @@ MTGAlternativeCostRule(observer, _id)
|
||||
|
||||
int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
{
|
||||
if(!card->has(Constants::PAYZERO))
|
||||
if (!card->has(Constants::PAYZERO))
|
||||
return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
|
||||
ManaCost * newCost = card->computeNewCost(card,cost,cost);
|
||||
if(newCost->extraCosts)
|
||||
for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++)
|
||||
if (card->isLand() || (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)))
|
||||
{
|
||||
//only allowed to pay zero for cards in library??? above is "if you dont have it in hand, grave, or exile"
|
||||
return 0;
|
||||
}
|
||||
if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}", NULL, NULL));
|
||||
ManaCost * newCost = card->computeNewCost(card, cost, cost);
|
||||
SAFE_DELETE(cost);
|
||||
if (newCost->extraCosts)
|
||||
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
newCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
|
||||
if(card->isLand())
|
||||
return 0;
|
||||
if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))
|
||||
return 0;
|
||||
if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card)))
|
||||
return 0;
|
||||
if(card->has(Constants::CANPLAYFROMGRAVEYARD))
|
||||
CustomName = "Zero Cast From Graveyard";
|
||||
else if(card->has(Constants::CANPLAYFROMEXILE))
|
||||
@@ -1412,22 +1433,26 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
{
|
||||
if (!card->has(Constants::OVERLOAD))
|
||||
return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative());
|
||||
ManaCost * newCost = card->computeNewCost(card,cost,cost);
|
||||
if (card->isLand())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Player * player = card->controller();
|
||||
if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card)) || (!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ManaCost * newCost = card->getManaCost()->getAlternative();
|
||||
if(newCost->extraCosts)
|
||||
for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
newCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
|
||||
if (card->isLand())
|
||||
return 0;
|
||||
if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card))
|
||||
return 0;
|
||||
if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card)))
|
||||
return 0;
|
||||
|
||||
return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost);
|
||||
}
|
||||
|
||||
@@ -1437,7 +1462,7 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card)
|
||||
return 0;
|
||||
|
||||
ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative());
|
||||
ManaCost * newCost = card->computeNewCost(card,cost,cost);
|
||||
ManaCost * newCost = card->getManaCost()->getAlternative();
|
||||
if(newCost->extraCosts)
|
||||
for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++)
|
||||
{
|
||||
@@ -1462,64 +1487,64 @@ MTGOverloadRule * MTGOverloadRule::clone() const
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//bestow
|
||||
MTGBestowRule::MTGBestowRule(GameObserver* observer, int _id) :
|
||||
MTGAlternativeCostRule(observer, _id)
|
||||
MTGAlternativeCostRule(observer, _id)
|
||||
{
|
||||
aType = MTGAbility::BESTOW_COST;
|
||||
aType = MTGAbility::BESTOW_COST;
|
||||
}
|
||||
|
||||
int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
{
|
||||
if (!card->model)
|
||||
return 0;
|
||||
//Player * player = game->currentlyActing();
|
||||
if (!card->model->data->getManaCost()->getBestow())
|
||||
return 0;
|
||||
if (card->isInPlay(game))
|
||||
return 0;
|
||||
ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow());
|
||||
ManaCost * newCost = card->computeNewCost(card, cost, cost);
|
||||
if (newCost->extraCosts)
|
||||
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
newCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
SAFE_DELETE(cost);
|
||||
if (card->isLand())
|
||||
return 0;
|
||||
if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature"))
|
||||
return 0;
|
||||
return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost);
|
||||
if (!card->model)
|
||||
return 0;
|
||||
if (!card->model->data->getManaCost()->getBestow())
|
||||
return 0;
|
||||
if (card->isInPlay(game))
|
||||
return 0;
|
||||
if (card->isLand())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!card->controller()->inPlay()->hasType("creature") && !card->controller()->opponent()->inPlay()->hasType("creature"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ManaCost * newCost = card->getManaCost()->getBestow();
|
||||
if (newCost->extraCosts)
|
||||
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
newCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
return MTGAlternativeCostRule::isReactingToClick(card, mana, newCost);
|
||||
}
|
||||
|
||||
int MTGBestowRule::reactToClick(MTGCardInstance * card)
|
||||
{
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
//this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash
|
||||
//TODO::::we need to get to the source of this leak and fix it.
|
||||
ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getBestow());
|
||||
ManaCost * newCost = card->computeNewCost(card, cost, cost);
|
||||
|
||||
if (newCost->extraCosts)
|
||||
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
newCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
//this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash
|
||||
//TODO::::we need to get to the source of this leak and fix it.
|
||||
ManaCost * newCost = card->getManaCost()->getBestow();
|
||||
|
||||
if (newCost->extraCosts)
|
||||
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
|
||||
{
|
||||
newCost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
|
||||
card->paymenttype = MTGAbility::BESTOW_COST;
|
||||
card->spellTargetType = "creature|battlefield";
|
||||
return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false);
|
||||
card->paymenttype = MTGAbility::BESTOW_COST;
|
||||
card->spellTargetType = "creature|battlefield";
|
||||
return MTGAlternativeCostRule::reactToClick(card, newCost, ManaCost::MANA_PAID_WITH_BESTOW, false);
|
||||
}
|
||||
|
||||
ostream& MTGBestowRule::toString(ostream& out) const
|
||||
{
|
||||
out << "MTGBestowRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
out << "MTGBestowRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
MTGBestowRule * MTGBestowRule::clone() const
|
||||
{
|
||||
return NEW MTGBestowRule(*this);
|
||||
return NEW MTGBestowRule(*this);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1710,19 +1735,19 @@ int MTGAttackRule::receiveEvent(WEvent *e)
|
||||
for (int i = 0; i < z->nb_cards; i++)
|
||||
{
|
||||
MTGCardInstance * card = z->cards[i];
|
||||
if (card->isAttacker() && card->has(Constants::NOSOLO))
|
||||
{
|
||||
TargetChooserFactory tf(game);
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL);
|
||||
int Check = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
if (Check <2)
|
||||
card->initAttackersDefensers();
|
||||
}
|
||||
if (card->isAttacker() && card->has(Constants::DETHRONE))
|
||||
{
|
||||
if (p->opponent()->life >= p->life)
|
||||
card->counters->addCounter(1, 1);
|
||||
}
|
||||
if (card->isAttacker() && card->has(Constants::NOSOLO))
|
||||
{
|
||||
TargetChooserFactory tf(game);
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL);
|
||||
int Check = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
if (Check <2)
|
||||
card->initAttackersDefensers();
|
||||
}
|
||||
if (card->isAttacker() && card->has(Constants::DETHRONE))
|
||||
{
|
||||
if (p->opponent()->life >= p->life)
|
||||
card->counters->addCounter(1, 1);
|
||||
}
|
||||
if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn.
|
||||
reactToClick(card);
|
||||
if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI())
|
||||
@@ -2036,49 +2061,49 @@ PermanentAbility(observer, _id)
|
||||
int MTGBlockRule::receiveEvent(WEvent *e)
|
||||
{
|
||||
|
||||
if (dynamic_cast<WEventBlockersChosen*>(e))
|
||||
{//do not refactor, these are keep seperate for readability.
|
||||
Player * p = game->currentPlayer;
|
||||
if (dynamic_cast<WEventBlockersChosen*>(e))
|
||||
{//do not refactor, these are keep seperate for readability.
|
||||
Player * p = game->currentPlayer;
|
||||
|
||||
vector<MTGCardInstance *> Attacker;
|
||||
MTGGameZone * k = p->game->inPlay;
|
||||
for (int i = 0; i < k->nb_cards; i++)
|
||||
{
|
||||
MTGCardInstance * card = k->cards[i];
|
||||
if (card->isAttacker())
|
||||
{
|
||||
Attacker.push_back(card);
|
||||
}
|
||||
}
|
||||
//force cards that must block, to block whatever is first found. players have a chance to set thier own
|
||||
//but if ignored we do it for them.
|
||||
if (Attacker.size())
|
||||
{
|
||||
MTGGameZone * tf = p->opponent()->game->inPlay;
|
||||
for (size_t i = 0; i < tf->cards.size(); i++)
|
||||
{
|
||||
MTGCardInstance * card = tf->cards[i];
|
||||
if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock())
|
||||
{//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them
|
||||
//unassigned as a block.
|
||||
for (size_t i = 0; i < Attacker.size(); i++)
|
||||
{
|
||||
if (card->canBlock(Attacker[i]) && !card->defenser)
|
||||
{
|
||||
blocker = NEW AABlock(card->getObserver(), -1, card, NULL);
|
||||
blocker->oneShot = true;
|
||||
blocker->forceDestroy = 1;
|
||||
blocker->canBeInterrupted = false;
|
||||
blocker->target = Attacker[i];
|
||||
blocker->resolve();
|
||||
SAFE_DELETE(blocker);
|
||||
}
|
||||
}
|
||||
vector<MTGCardInstance *> Attacker;
|
||||
MTGGameZone * k = p->game->inPlay;
|
||||
for (int i = 0; i < k->nb_cards; i++)
|
||||
{
|
||||
MTGCardInstance * card = k->cards[i];
|
||||
if (card->isAttacker())
|
||||
{
|
||||
Attacker.push_back(card);
|
||||
}
|
||||
}
|
||||
//force cards that must block, to block whatever is first found. players have a chance to set thier own
|
||||
//but if ignored we do it for them.
|
||||
if (Attacker.size())
|
||||
{
|
||||
MTGGameZone * tf = p->opponent()->game->inPlay;
|
||||
for (size_t i = 0; i < tf->cards.size(); i++)
|
||||
{
|
||||
MTGCardInstance * card = tf->cards[i];
|
||||
if (card->has(Constants::MUSTBLOCK) && !card->defenser && card->canBlock())
|
||||
{//force mustblockers to block the first thing theyre allowed to block if player leaves blockers with them
|
||||
//unassigned as a block.
|
||||
for (size_t i = 0; i < Attacker.size(); i++)
|
||||
{
|
||||
if (card->canBlock(Attacker[i]) && !card->defenser)
|
||||
{
|
||||
blocker = NEW AABlock(card->getObserver(), -1, card, NULL);
|
||||
blocker->oneShot = true;
|
||||
blocker->forceDestroy = 1;
|
||||
blocker->canBeInterrupted = false;
|
||||
blocker->target = Attacker[i];
|
||||
blocker->resolve();
|
||||
SAFE_DELETE(blocker);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (dynamic_cast<WEventBlockersChosen*>(e))
|
||||
{
|
||||
|
||||
@@ -2098,23 +2123,23 @@ int MTGBlockRule::receiveEvent(WEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
//if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal.
|
||||
MTGGameZone * z = p->game->inPlay;
|
||||
for (int i = 0; i < z->nb_cards; i++)
|
||||
{
|
||||
MTGCardInstance * card = z->cards[i];
|
||||
if (card->has(Constants::MENACE) && card->blockers.size() < 2)
|
||||
{
|
||||
while (card->blockers.size())
|
||||
{
|
||||
MTGCardInstance * blockingCard = card->blockers.front();
|
||||
blockingCard->toggleDefenser(NULL);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//if a card with menace is not blocked by 2 or more, remove any known blockers and attacking as normal.
|
||||
MTGGameZone * z = p->game->inPlay;
|
||||
for (int i = 0; i < z->nb_cards; i++)
|
||||
{
|
||||
MTGCardInstance * card = z->cards[i];
|
||||
if (card->has(Constants::MENACE) && card->blockers.size() < 2)
|
||||
{
|
||||
while (card->blockers.size())
|
||||
{
|
||||
MTGCardInstance * blockingCard = card->blockers.front();
|
||||
blockingCard->toggleDefenser(NULL);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -2877,6 +2902,7 @@ int MTGPersistRule::receiveEvent(WEvent * event)
|
||||
}
|
||||
AAMover *putinplay = NEW AAMover(game, game->mLayers->actionLayer()->getMaxId(), copy, copy,"ownerbattlefield",code,NULL,undying,persist);
|
||||
putinplay->oneShot = true;
|
||||
game->mLayers->actionLayer()->garbage.push_back(putinplay);
|
||||
putinplay->fireAbility();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
//Exile
|
||||
//Exile
|
||||
manaCost->addExtraCost(NEW ExileTargetCost(tc));
|
||||
break;
|
||||
case 'h': //bounce (move to Hand)
|
||||
@@ -179,12 +179,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
}
|
||||
break;
|
||||
case 'd': //DiscardRandom cost
|
||||
if (value.find("delve") != string::npos)
|
||||
{
|
||||
if(!tc)
|
||||
tc = tcf.createTargetChooser("*|mygraveyard", c);
|
||||
manaCost->addExtraCost(NEW Delve(tc));
|
||||
}
|
||||
if (value.find("delve") != string::npos)
|
||||
{
|
||||
if(!tc)
|
||||
tc = tcf.createTargetChooser("*|mygraveyard", c);
|
||||
manaCost->addExtraCost(NEW Delve(tc));
|
||||
}
|
||||
else if (value == "d")
|
||||
{
|
||||
manaCost->addExtraCost(NEW DiscardRandomCost(tc));
|
||||
@@ -259,12 +259,12 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
break;
|
||||
case 'c': //Counters or cycle
|
||||
{
|
||||
if (value.find("convoke") != string::npos)
|
||||
{
|
||||
if (!tc)
|
||||
tc = tcf.createTargetChooser("creature|mybattlefield", c);
|
||||
manaCost->addExtraCost(NEW Convoke(tc));
|
||||
}
|
||||
if (value.find("convoke") != string::npos)
|
||||
{
|
||||
if (!tc)
|
||||
tc = tcf.createTargetChooser("creature|mybattlefield", c);
|
||||
manaCost->addExtraCost(NEW Convoke(tc));
|
||||
}
|
||||
else if(value == "chosencolor")
|
||||
{
|
||||
if(c)
|
||||
@@ -390,19 +390,21 @@ ManaCost::ManaCost(ManaCost * manaCost)
|
||||
cost[i] = manaCost->getCost(i);
|
||||
}
|
||||
hybrids = manaCost->hybrids;
|
||||
|
||||
kicker = NEW ManaCost( manaCost->kicker );
|
||||
if(kicker)
|
||||
kicker->isMulti = manaCost->isMulti;
|
||||
kicker = NEW ManaCost(manaCost->kicker);
|
||||
if (kicker)
|
||||
kicker->isMulti = manaCost->isMulti;
|
||||
Retrace = NEW ManaCost( manaCost->Retrace );
|
||||
BuyBack = NEW ManaCost( manaCost->BuyBack );
|
||||
alternative = NEW ManaCost( manaCost->alternative );
|
||||
FlashBack = NEW ManaCost( manaCost->FlashBack );
|
||||
morph = NEW ManaCost( manaCost->morph );
|
||||
suspend = NEW ManaCost( manaCost->suspend );
|
||||
Bestow = NEW ManaCost(manaCost->Bestow);
|
||||
|
||||
extraCosts = manaCost->extraCosts ? manaCost->extraCosts->clone() : NULL;
|
||||
Bestow = NEW ManaCost(manaCost->Bestow);
|
||||
extraCosts = NULL;
|
||||
if (manaCost->extraCosts)
|
||||
{
|
||||
extraCosts = manaCost->extraCosts->clone();
|
||||
}
|
||||
manaUsedToCast = NULL;
|
||||
xColor = manaCost->xColor;
|
||||
}
|
||||
@@ -429,9 +431,13 @@ ManaCost::ManaCost(const ManaCost& manaCost)
|
||||
FlashBack = NEW ManaCost( manaCost.FlashBack );
|
||||
morph = NEW ManaCost( manaCost.morph );
|
||||
suspend = NEW ManaCost( manaCost.suspend );
|
||||
Bestow = NEW ManaCost(manaCost.Bestow);
|
||||
Bestow = NEW ManaCost(manaCost.Bestow);
|
||||
extraCosts = NULL;
|
||||
if (manaCost.extraCosts)
|
||||
{
|
||||
extraCosts = manaCost.extraCosts->clone();
|
||||
}
|
||||
|
||||
extraCosts = manaCost.extraCosts ? manaCost.extraCosts->clone() : NULL;
|
||||
manaUsedToCast = NULL;
|
||||
xColor = manaCost.xColor;
|
||||
}
|
||||
@@ -453,7 +459,7 @@ ManaCost & ManaCost::operator= (const ManaCost & manaCost)
|
||||
FlashBack = manaCost.FlashBack;
|
||||
morph = manaCost.morph;
|
||||
suspend = manaCost.suspend;
|
||||
Bestow = manaCost.Bestow;
|
||||
Bestow = manaCost.Bestow;
|
||||
manaUsedToCast = manaCost.manaUsedToCast;
|
||||
xColor = manaCost.xColor;
|
||||
}
|
||||
@@ -470,7 +476,7 @@ ManaCost::~ManaCost()
|
||||
SAFE_DELETE(Retrace);
|
||||
SAFE_DELETE(morph);
|
||||
SAFE_DELETE(suspend);
|
||||
SAFE_DELETE(Bestow);
|
||||
SAFE_DELETE(Bestow);
|
||||
SAFE_DELETE(manaUsedToCast);
|
||||
|
||||
cost.erase(cost.begin() ,cost.end());
|
||||
@@ -480,7 +486,6 @@ void ManaCost::x()
|
||||
{
|
||||
if (cost.size() <= (size_t)Constants::NB_Colors)
|
||||
{
|
||||
DebugTrace("Seems ManaCost was not properly initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -491,7 +496,6 @@ int ManaCost::hasX()
|
||||
{
|
||||
if (cost.size() <= (size_t)Constants::NB_Colors)
|
||||
{
|
||||
DebugTrace("Seems ManaCost was not properly initialized");
|
||||
return 0;
|
||||
}
|
||||
if (xColor > 0)
|
||||
@@ -504,7 +508,6 @@ void ManaCost::specificX(int color)
|
||||
{
|
||||
if (cost.size() <= (size_t)Constants::NB_Colors)
|
||||
{
|
||||
DebugTrace("Seems ManaCost was not properly initialized");
|
||||
return;
|
||||
}
|
||||
xColor = color;
|
||||
@@ -515,7 +518,6 @@ int ManaCost::hasSpecificX()
|
||||
{
|
||||
if (cost.size() <= (size_t)Constants::NB_Colors)
|
||||
{
|
||||
DebugTrace("Seems ManaCost was not properly initialized");
|
||||
return 0;
|
||||
}
|
||||
if(xColor > 0)
|
||||
@@ -556,7 +558,7 @@ void ManaCost::init()
|
||||
Retrace = NULL;
|
||||
morph = NULL;
|
||||
suspend = NULL;
|
||||
Bestow = NULL;
|
||||
Bestow = NULL;
|
||||
manaUsedToCast = NULL;
|
||||
isMulti = false;
|
||||
xColor = -1;
|
||||
@@ -581,7 +583,7 @@ void ManaCost::resetCosts()
|
||||
SAFE_DELETE(Retrace);
|
||||
SAFE_DELETE(morph);
|
||||
SAFE_DELETE(suspend);
|
||||
SAFE_DELETE(Bestow);
|
||||
SAFE_DELETE(Bestow);
|
||||
}
|
||||
|
||||
void ManaCost::copy(ManaCost * _manaCost)
|
||||
@@ -599,6 +601,7 @@ void ManaCost::copy(ManaCost * _manaCost)
|
||||
hybrids = _manaCost->hybrids;
|
||||
|
||||
SAFE_DELETE(extraCosts);
|
||||
|
||||
if (_manaCost->extraCosts)
|
||||
{
|
||||
extraCosts = _manaCost->extraCosts->clone();
|
||||
@@ -647,12 +650,12 @@ void ManaCost::copy(ManaCost * _manaCost)
|
||||
suspend = NEW ManaCost();
|
||||
suspend->copy(_manaCost->suspend);
|
||||
}
|
||||
SAFE_DELETE(Bestow);
|
||||
if (_manaCost->Bestow)
|
||||
{
|
||||
Bestow = NEW ManaCost();
|
||||
Bestow->copy(_manaCost->Bestow);
|
||||
}
|
||||
SAFE_DELETE(Bestow);
|
||||
if (_manaCost->Bestow)
|
||||
{
|
||||
Bestow = NEW ManaCost();
|
||||
Bestow->copy(_manaCost->Bestow);
|
||||
}
|
||||
xColor = _manaCost->xColor;
|
||||
}
|
||||
|
||||
@@ -1117,7 +1120,7 @@ void ManaPool::Empty()
|
||||
SAFE_DELETE(Retrace);
|
||||
SAFE_DELETE(morph);
|
||||
SAFE_DELETE(suspend);
|
||||
SAFE_DELETE(Bestow);
|
||||
SAFE_DELETE(Bestow);
|
||||
SAFE_DELETE(manaUsedToCast);
|
||||
init();
|
||||
WEvent * e = NEW WEventEmptyManaPool(this);
|
||||
@@ -1147,8 +1150,8 @@ int ManaPool::remove(int color, int value)
|
||||
|
||||
int ManaPool::add(int color, int value, MTGCardInstance * source, bool extra)
|
||||
{
|
||||
if (color == Constants::MTG_COLOR_ARTIFACT)
|
||||
color = Constants::MTG_COLOR_WASTE;
|
||||
if (color == Constants::MTG_COLOR_ARTIFACT)
|
||||
color = Constants::MTG_COLOR_WASTE;
|
||||
int result = ManaCost::add(color, value);
|
||||
for (int i = 0; i < value; ++i)
|
||||
{
|
||||
@@ -1168,15 +1171,15 @@ int ManaPool::add(ManaCost * _cost, MTGCardInstance * source)
|
||||
{
|
||||
if (!_cost)
|
||||
return 0;
|
||||
//while colorless is still exactly the same, there are now cards that require
|
||||
//true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the
|
||||
//new type. keeping the old type intact for payment methods {1}{c} ....
|
||||
int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT);
|
||||
if (replaceArtifact)
|
||||
{
|
||||
_cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact);
|
||||
_cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact);
|
||||
}
|
||||
//while colorless is still exactly the same, there are now cards that require
|
||||
//true colorless mana, ei:eldrazi. so whenever we add mana, we now replace it with the
|
||||
//new type. keeping the old type intact for payment methods {1}{c} ....
|
||||
int replaceArtifact = _cost->getCost(Constants::MTG_COLOR_ARTIFACT);
|
||||
if (replaceArtifact)
|
||||
{
|
||||
_cost->add(Constants::MTG_COLOR_WASTE, replaceArtifact);
|
||||
_cost->remove(Constants::MTG_COLOR_ARTIFACT, replaceArtifact);
|
||||
}
|
||||
int result = ManaCost::add(_cost);
|
||||
for (int i = 0; i < Constants::NB_Colors; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user