Added/Fixed primitives, updated the "missing_cards_by_sets" folder, added a new option "keepname" to keep the original name after the copy (e.g. Olag, Ludevic's Hubris), implemented a fix to avoid triggering of oneshot abilities when "flip" ability is used to return from a copy, fixed an issue with colors and "transforms" keyword, implemented a fix to avoid crashes when the card paying extracost has also a cost alteration (e.g. combo with "Pirate's Pillage" and "Ruby Medallion"), added a new keyword "totmanaspent" to return the real amount of mana spent to cast a card (e.g. Memory Deluge), added new keywords "pnumofidentitycols" and "onumofidentitycols" to return the total amount of commander identity colors for controller or opponent (e.g. War Room), improved "totcnt" keyword, added new keywords "totalcololorsinplay" and "oppototalcololorsinplay" to return the total amount of colors on controller or opponent battlefield (e.g. Moonveil Regent), added new keywords "pcoven" and "ocoven" to return if a player controls three or more creatures with different powers (e.g. Augur of Autumn).
This commit is contained in:
@@ -2031,6 +2031,10 @@ int AACopier::resolve()
|
||||
/*since we look for the real card it will not copy granted haste ability however for token we copy all*/
|
||||
/*but how to do backup for token so we just copy the backup???*/
|
||||
bool nolegend = options.find("nolegend") != string::npos; // Check if the copy has to be legendary or not. (e.g. Echoing Equation)
|
||||
string keepname = "";
|
||||
if(options.find("keepname") != string::npos){ // Keep the original name after the copy. (e.g. "Olag, Ludevic's Hubris")
|
||||
keepname = source->getName();
|
||||
}
|
||||
if(tokencopied && !_target->isACopier && !_target->getMTGId())
|
||||
{
|
||||
source->copy(_target->tokCard, nolegend);
|
||||
@@ -2138,6 +2142,8 @@ int AACopier::resolve()
|
||||
andAbilityClone->addToGame();
|
||||
}
|
||||
}
|
||||
if(keepname != "")
|
||||
source->name = keepname; // Keep the original name after the copy. (e.g. "Olag, Ludevic's Hubris")
|
||||
}
|
||||
currentAbilities.clear();
|
||||
return 1;
|
||||
@@ -4822,21 +4828,25 @@ int AAFlip::resolve()
|
||||
{
|
||||
if (a->oneShot)
|
||||
{
|
||||
if(_target->hasType(Subtypes::TYPE_PLANESWALKER)){ // Fix to don't let planeswalker die on flip (since the counter ability is not resolving correctly during flip).
|
||||
AACounter * tmp = dynamic_cast<AACounter *>(a);
|
||||
if(tmp && tmp->counterstring.find("loyalty") != string::npos){
|
||||
for (int j = 0; j < tmp->nb; j++)
|
||||
_target->counters->addCounter("loyalty", 0, 0, true);
|
||||
if(!backfromcopy){ // Fix to avoid triggering of oneshot abilities when flip is used to return from a copy.
|
||||
if(_target->hasType(Subtypes::TYPE_PLANESWALKER)){ // Fix to don't let planeswalker die on flip (since the counter ability is not resolving correctly during flip).
|
||||
AACounter * tmp = dynamic_cast<AACounter *>(a);
|
||||
if(tmp && tmp->counterstring.find("loyalty") != string::npos){
|
||||
for (int j = 0; j < tmp->nb; j++)
|
||||
_target->counters->addCounter("loyalty", 0, 0, true);
|
||||
} else a->resolve();
|
||||
} else a->resolve();
|
||||
} else a->resolve();
|
||||
}
|
||||
SAFE_DELETE(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
a->addToGame();
|
||||
MayAbility * dontAdd = dynamic_cast<MayAbility*>(a);
|
||||
if(!dontAdd)
|
||||
if(!dontAdd){
|
||||
a->addToGame();
|
||||
_target->cardsAbilities.push_back(a);
|
||||
} else if(!backfromcopy) // Fix to avoid triggering of may abilities when flip is used to return from a copy (e.g. Mirror of the Forebears).
|
||||
a->addToGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10270,11 +10280,17 @@ void PopulateColorIndexVector(list<int>& colors, const string& colorStringList,
|
||||
vector<string> abilitiesList = split(colorStringList, delimiter);
|
||||
for (vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
|
||||
{
|
||||
// if the text is not a basic ability but contains a valid color add it to the color vector
|
||||
if((*iter).find("newcolors[") != string::npos){
|
||||
size_t start_pos = (*iter).find("newcolors[");
|
||||
(*iter).replace(start_pos, 10, "");
|
||||
start_pos = (*iter).find("]");
|
||||
(*iter).replace(start_pos, 1, "");
|
||||
}
|
||||
for (int colorIndex = Constants::MTG_COLOR_ARTIFACT; colorIndex < Constants::NB_Colors; ++colorIndex)
|
||||
{
|
||||
// if the text is not a basic ability but contains a valid color add it to the color vector
|
||||
if ((Constants::GetBasicAbilityIndex(*iter) == -1)
|
||||
&& ((*iter).find(Constants::MTGColorStrings[colorIndex]) != string::npos))
|
||||
// We match now exactly the color to avoid wrong color assignment from gained abilities (e.g. protection from blue)
|
||||
if ((Constants::GetBasicAbilityIndex(*iter) == -1) && ((*iter) == Constants::MTGColorStrings[colorIndex]))
|
||||
colors.push_back(colorIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1172,8 +1172,8 @@ void GameObserver::Affinity()
|
||||
{
|
||||
for (int dd = 0; dd < 2; dd++)
|
||||
{
|
||||
MTGGameZone * dzones[] = { players[dd]->game->graveyard, players[dd]->game->hand, players[dd]->game->library, players[dd]->game->exile };
|
||||
for (int kk = 0; kk < 4; kk++)
|
||||
MTGGameZone * dzones[] = { players[dd]->game->graveyard, players[dd]->game->hand, players[dd]->game->library, players[dd]->game->commandzone, players[dd]->game->exile };
|
||||
for (int kk = 0; kk < 5; kk++)
|
||||
{
|
||||
MTGGameZone * zone = dzones[kk];
|
||||
for (int cc = zone->nb_cards - 1; cc >= 0; cc--)
|
||||
@@ -1280,6 +1280,9 @@ void GameObserver::Affinity()
|
||||
if (!DoReduceIncrease)
|
||||
continue;
|
||||
|
||||
if (mExtraPayment != NULL && card == mExtraPayment->source) // Fix to avoid crash when the card paying extracost has also a cost alteration (e.g. combo with "Pirate's Pillage" and "Ruby Medallion").
|
||||
continue;
|
||||
|
||||
//above we check if there are even any cards that effect cards manacost
|
||||
//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.
|
||||
|
||||
@@ -424,13 +424,35 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card)
|
||||
intValue = card->previous->previous->sunburst;
|
||||
}
|
||||
}
|
||||
else if (s == "converge")
|
||||
else if (s == "converge" || s == "totmanaspent")
|
||||
{
|
||||
intValue = 0;
|
||||
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||
{
|
||||
if(card->getManaCost()->getManaUsedToCast()->hasColor(i))
|
||||
intValue +=1;
|
||||
if(s == "converge"){
|
||||
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i){
|
||||
if(card->getManaCost()->getManaUsedToCast() && card->getManaCost()->getManaUsedToCast()->hasColor(i))
|
||||
intValue +=1;
|
||||
}
|
||||
} else if(s == "totmanaspent") { // Return the real amount of mana spent to cast the card (e.g. Memory Deluge)
|
||||
if(card->getManaCost()->getManaUsedToCast())
|
||||
intValue = card->getManaCost()->getManaUsedToCast()->getConvertedCost();
|
||||
else {
|
||||
if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE] == 1 && card->getManaCost()->getRetrace())
|
||||
intValue = card->getManaCost()->getRetrace()->getConvertedCost();
|
||||
else if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_FLASHBACK] == 1 && card->getManaCost()->getFlashback())
|
||||
intValue = card->getManaCost()->getFlashback()->getConvertedCost();
|
||||
else if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_ALTERNATIVE] == 1 && card->getManaCost()->getAlternative())
|
||||
intValue = card->getManaCost()->getAlternative()->getConvertedCost();
|
||||
else if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BESTOW] == 1 && card->getManaCost()->getBestow())
|
||||
intValue = card->getManaCost()->getBestow()->getConvertedCost();
|
||||
else if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BUYBACK] == 1 && card->getManaCost()->getBuyback())
|
||||
intValue = card->getManaCost()->getBuyback()->getConvertedCost();
|
||||
else if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_MORPH] == 1 && card->getManaCost()->getMorph())
|
||||
intValue = card->getManaCost()->getMorph()->getConvertedCost();
|
||||
else if(card->alternateCostPaid[ManaCost::MANA_PAID_WITH_SUSPEND] == 1 && card->getManaCost()->getSuspend())
|
||||
intValue = card->getManaCost()->getSuspend()->getConvertedCost();
|
||||
else
|
||||
intValue = card->getManaCost()->getConvertedCost();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s == "penergy" || s == "oenergy")
|
||||
@@ -469,9 +491,52 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card)
|
||||
{
|
||||
intValue = (s == "countmycrespell")?card->controller()->game->stack->seenThisTurn("creature", Constants::CAST_ALL):card->controller()->game->stack->seenThisTurn("*[-creature]", Constants::CAST_ALL);
|
||||
}
|
||||
else if(s == "pnumofcommandcast" || s == "onumofcommandcast")
|
||||
else if(s == "numofcommandcast" || s == "pnumofcommandcast" || s == "onumofcommandcast" || s == "pnumofidentitycols" || s == "onumofidentitycols")
|
||||
{
|
||||
intValue = (s == "pnumofcommandcast")?card->controller()->numOfCommandCast:card->controller()->opponent()->numOfCommandCast;
|
||||
intValue = 0;
|
||||
if(s == "pnumofcommandcast") //Return how many times controller casted a commander (e.g. Skull Storm).
|
||||
intValue = card->controller()->numOfCommandCast;
|
||||
else if(s == "onumofcommandcast") //Return how many times controller casted a commander (e.g. Commander's Insight).
|
||||
intValue = card->controller()->opponent()->numOfCommandCast;
|
||||
else if(s == "numofcommandcast") //Return how many times this commander has been casted from command zone (e.g. Opal Palace).
|
||||
intValue = card->numofcastfromcommandzone;
|
||||
else if (s == "pnumofidentitycols" || s == "onumofidentitycols") //Return the total amount of commander identity colors for controller or opponent (e.g. War Room)
|
||||
{
|
||||
intValue = 0;
|
||||
bool blueFound = false;
|
||||
bool redFound = false;
|
||||
bool whiteFound = false;
|
||||
bool greenFound = false;
|
||||
bool blackFound = false;
|
||||
Player* p = card->controller();
|
||||
if (s == "onumofidentitycols")
|
||||
p = card->controller()->opponent();
|
||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile, p->game->commandzone, p->game->sideboard };
|
||||
for(int i = 0; i < 7; i++){
|
||||
for(int j = 0; j < zones[i]->nb_cards; j++){
|
||||
if(zones[i]->cards[j]->has(Constants::ISCOMMANDER) && zones[i]->cards[j]->hasColor(Constants::MTG_COLOR_RED) && !redFound){
|
||||
intValue++;
|
||||
redFound = true;
|
||||
}
|
||||
if(zones[i]->cards[j]->has(Constants::ISCOMMANDER) && zones[i]->cards[j]->hasColor(Constants::MTG_COLOR_BLACK) && !blackFound){
|
||||
intValue++;
|
||||
blackFound = true;
|
||||
}
|
||||
if(zones[i]->cards[j]->has(Constants::ISCOMMANDER) && zones[i]->cards[j]->hasColor(Constants::MTG_COLOR_BLUE) && !blueFound){
|
||||
intValue++;
|
||||
blueFound = true;
|
||||
}
|
||||
if(zones[i]->cards[j]->has(Constants::ISCOMMANDER) && zones[i]->cards[j]->hasColor(Constants::MTG_COLOR_GREEN) && !greenFound){
|
||||
intValue++;
|
||||
greenFound = true;
|
||||
}
|
||||
if(zones[i]->cards[j]->has(Constants::ISCOMMANDER) && zones[i]->cards[j]->hasColor(Constants::MTG_COLOR_WHITE) && !whiteFound){
|
||||
intValue++;
|
||||
whiteFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s == "isflipped" || s == "iscopied") // Return 1 if card has been flipped -- Return 1 if card has copied another card
|
||||
{
|
||||
@@ -1230,7 +1295,12 @@ void WParsedInt::extendedParse(string s, Spell * spell, MTGCardInstance * card)
|
||||
{
|
||||
intValue = 0;
|
||||
for (int j = card->controller()->game->inPlay->nb_cards - 1; j >= 0; --j){
|
||||
if ((s.find("totcntcre") != string::npos || s.find("totcntall") != string::npos) && card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE)){
|
||||
if ((s.find("totcntcre") != string::npos && card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE)) ||
|
||||
(s.find("totcntpla") != string::npos && card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_PLANESWALKER)) ||
|
||||
(s.find("totcntart") != string::npos && card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_ARTIFACT)) ||
|
||||
(s.find("totcntenc") != string::npos && card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_ENCHANTMENT)) ||
|
||||
(s.find("totcntlan") != string::npos && card->controller()->game->inPlay->cards[j]->hasType(Subtypes::TYPE_LAND)) ||
|
||||
s.find("totcntall") != string::npos){
|
||||
if (card->controller()->game->inPlay->cards[j]->counters){
|
||||
Counters * counters = card->controller()->game->inPlay->cards[j]->counters;
|
||||
for(size_t i = 0; i < counters->counters.size(); ++i){
|
||||
@@ -1324,6 +1394,60 @@ void WParsedInt::extendedParse(string s, Spell * spell, MTGCardInstance * card)
|
||||
else if (s == "totaldmg")
|
||||
intValue = (card->damageToController + card->damageToCreature + card->damageToOpponent);
|
||||
}
|
||||
else if (s.find("totalcololorsinplay") != string::npos || s.find("oppototalcololorsinplay") != string::npos) //Return the total amount of colors on controller or opponent battlefield (e.g. Moonveil Regent)
|
||||
{
|
||||
intValue = 0;
|
||||
bool blueFound = false;
|
||||
bool redFound = false;
|
||||
bool whiteFound = false;
|
||||
bool greenFound = false;
|
||||
bool blackFound = false;
|
||||
Player* p = card->controller();
|
||||
if (s == "oppototalcololorsinplay")
|
||||
p = card->controller()->opponent();
|
||||
for( int j = 0; j < p->inPlay()->nb_cards; j++){
|
||||
if(p->inPlay()->cards[j]->hasColor(Constants::MTG_COLOR_RED) && !redFound){
|
||||
intValue++;
|
||||
redFound = true;
|
||||
}
|
||||
if(p->inPlay()->cards[j]->hasColor(Constants::MTG_COLOR_BLACK) && !blackFound){
|
||||
intValue++;
|
||||
blackFound = true;
|
||||
}
|
||||
if(p->inPlay()->cards[j]->hasColor(Constants::MTG_COLOR_BLUE) && !blueFound){
|
||||
intValue++;
|
||||
blueFound = true;
|
||||
}
|
||||
if(p->inPlay()->cards[j]->hasColor(Constants::MTG_COLOR_GREEN) && !greenFound){
|
||||
intValue++;
|
||||
greenFound = true;
|
||||
}
|
||||
if(p->inPlay()->cards[j]->hasColor(Constants::MTG_COLOR_WHITE) && !whiteFound){
|
||||
intValue++;
|
||||
whiteFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(s.find("pcoven") != string::npos || s.find("ocoven") != string::npos){ //Player or opponent controls three or more creatures with different powers (e.g. Augur of Autumn)
|
||||
intValue = 0;
|
||||
bool opponent = (s.find("ocoven")!=string::npos)?true:false;
|
||||
Player* p = card->controller();
|
||||
if (opponent)
|
||||
p = card->controller()->opponent();
|
||||
for(unsigned int i = 0; i < p->game->inPlay->cards.size() && intValue == 0; i++){
|
||||
if(p->game->inPlay->cards[i]->hasType(Subtypes::TYPE_CREATURE)){
|
||||
for(unsigned int j = i+1; j < p->game->inPlay->cards.size() && intValue == 0; j++){
|
||||
if(p->game->inPlay->cards[j]->hasType(Subtypes::TYPE_CREATURE) && p->game->inPlay->cards[j]->power != p->game->inPlay->cards[i]->power){
|
||||
for(unsigned int k = j+1; k < p->game->inPlay->cards.size() && intValue == 0; k++){
|
||||
if(p->game->inPlay->cards[k]->hasType(Subtypes::TYPE_CREATURE) && (p->game->inPlay->cards[k]->power != p->game->inPlay->cards[i]->power && p->game->inPlay->cards[k]->power != p->game->inPlay->cards[j]->power)){
|
||||
intValue = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!intValue)//found nothing, try parsing a atoi
|
||||
{
|
||||
intValue = atoi(s.c_str());
|
||||
|
||||
Reference in New Issue
Block a user