Fixed several bugs, fixed several primitives, improved affnity for other types of cards, improved flip ability for token, added some new primitives from MAT set.
This commit is contained in:
@@ -4890,7 +4890,7 @@ int AAFlip::resolve()
|
||||
if (_target)
|
||||
{
|
||||
if(_target->mutation && _target->parentCards.size() > 0) return 0; // Mutated down cards cannot be flipped, they will follow the fate of top-card
|
||||
if(((_target->isACopier||_target->isToken) && !isflipcard && !backfromcopy) || _target->has(Constants::CANTTRANSFORM))
|
||||
if(((_target->isACopier||(_target->isToken && _target->backSide == "")) && !isflipcard && !backfromcopy) || _target->has(Constants::CANTTRANSFORM))
|
||||
{
|
||||
game->removeObserver(this);
|
||||
return 0;
|
||||
|
||||
@@ -739,15 +739,15 @@ void GameObserver::gameStateBasedEffects()
|
||||
if(card->hasType(Subtypes::TYPE_PLANESWALKER) && (!card->counters||!card->counters->hasCounter("loyalty",0,0)))
|
||||
players[i]->game->putInGraveyard(card);
|
||||
if(card->hasType(Subtypes::TYPE_BATTLE) && (!card->counters||!card->counters->hasCounter("defense",0,0))){
|
||||
if(!card->isDefeated){
|
||||
card->isDefeated = true;
|
||||
WEvent * e = NEW WEventCardDefeated(card);
|
||||
receiveEvent(e);
|
||||
if(!card->isDefeated){
|
||||
card->isDefeated = true;
|
||||
WEvent * e = NEW WEventCardDefeated(card);
|
||||
receiveEvent(e);
|
||||
}
|
||||
}
|
||||
if(!card->isCreature() && card->hasType(Subtypes::TYPE_PLANESWALKER) && card->counters->hasCounter("loyalty", 0, 0))
|
||||
if(!card->isCreature() && card->hasType(Subtypes::TYPE_PLANESWALKER) && card->counters->hasCounter("loyalty", 0, 0))
|
||||
card->life = card->counters->hasCounter("loyalty", 0, 0)->nb;
|
||||
if(!card->isCreature() && card->hasType(Subtypes::TYPE_BATTLE) && card->counters->hasCounter("defense", 0, 0))
|
||||
if(!card->isCreature() && card->hasType(Subtypes::TYPE_BATTLE) && card->counters->hasCounter("defense", 0, 0))
|
||||
card->life = card->counters->hasCounter("defense", 0, 0)->nb;
|
||||
if(card->myPair && !isInPlay(card->myPair))
|
||||
{
|
||||
@@ -1285,6 +1285,7 @@ void GameObserver::Affinity()
|
||||
bool DoReduceIncrease = false;
|
||||
if (
|
||||
(card->has(Constants::AFFINITYARTIFACTS) ||
|
||||
card->has(Constants::AFFINITYENCHANTMENTS) ||
|
||||
card->has(Constants::AFFINITYFOREST) ||
|
||||
card->has(Constants::AFFINITYGREENCREATURES) ||
|
||||
card->has(Constants::AFFINITYISLAND) ||
|
||||
@@ -1292,6 +1293,16 @@ void GameObserver::Affinity()
|
||||
card->has(Constants::AFFINITYPLAINS) ||
|
||||
card->has(Constants::AFFINITYSWAMP) ||
|
||||
card->has(Constants::CONDUITED) ||
|
||||
card->has(Constants::AFFINITYALLCREATURES) ||
|
||||
card->has(Constants::AFFINITYCONTROLLERCREATURES) ||
|
||||
card->has(Constants::AFFINITYOPPONENTCREATURES) ||
|
||||
card->has(Constants::AFFINITYALLDEADCREATURES) ||
|
||||
card->has(Constants::AFFINITYPARTY) ||
|
||||
card->has(Constants::AFFINITYBASICLANDTYPES) ||
|
||||
card->has(Constants::AFFINITYTWOBASICLANDTYPES) ||
|
||||
card->has(Constants::AFFINITYGRAVECREATURES) ||
|
||||
card->has(Constants::AFFINITYATTACKINGCREATURES) ||
|
||||
card->has(Constants::AFFINITYGRAVEINSTSORC) ||
|
||||
card->getIncreasedManaCost()->getConvertedCost() ||
|
||||
card->getReducedManaCost()->getConvertedCost() ||
|
||||
NewAffinityFound || checkAuraP)
|
||||
|
||||
@@ -1272,18 +1272,33 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos
|
||||
}
|
||||
}//end2
|
||||
if (card->has(Constants::AFFINITYARTIFACTS) ||
|
||||
card->has(Constants::AFFINITYENCHANTMENTS) ||
|
||||
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::AFFINITYALLCREATURES) ||
|
||||
card->has(Constants::AFFINITYCONTROLLERCREATURES) ||
|
||||
card->has(Constants::AFFINITYOPPONENTCREATURES) ||
|
||||
card->has(Constants::AFFINITYALLDEADCREATURES) ||
|
||||
card->has(Constants::AFFINITYPARTY) ||
|
||||
card->has(Constants::AFFINITYBASICLANDTYPES) ||
|
||||
card->has(Constants::AFFINITYTWOBASICLANDTYPES) ||
|
||||
card->has(Constants::AFFINITYGRAVECREATURES) ||
|
||||
card->has(Constants::AFFINITYATTACKINGCREATURES) ||
|
||||
card->has(Constants::AFFINITYGRAVEINSTSORC) ||
|
||||
card->has(Constants::CONDUITED))
|
||||
{//start3
|
||||
if (card->has(Constants::AFFINITYARTIFACTS))
|
||||
{
|
||||
type = "artifact";
|
||||
}
|
||||
if (card->has(Constants::AFFINITYENCHANTMENTS))
|
||||
{
|
||||
type = "enchantment";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYSWAMP))
|
||||
{
|
||||
type = "swamp";
|
||||
@@ -1309,6 +1324,22 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos
|
||||
color = 1;
|
||||
type = "creature";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYALLCREATURES) || card->has(Constants::AFFINITYCONTROLLERCREATURES) || card->has(Constants::AFFINITYOPPONENTCREATURES) || card->has(Constants::AFFINITYALLDEADCREATURES))
|
||||
{
|
||||
type = "creature";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYPARTY) || card->has(Constants::AFFINITYGRAVECREATURES) || card->has(Constants::AFFINITYATTACKINGCREATURES))
|
||||
{
|
||||
type = "creature";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYBASICLANDTYPES) || card->has(Constants::AFFINITYTWOBASICLANDTYPES))
|
||||
{
|
||||
type = "land";
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYGRAVEINSTSORC))
|
||||
{
|
||||
type = "instant,sorcery";
|
||||
}
|
||||
|
||||
Cost->copy(original);
|
||||
if (Cost->extraCosts)
|
||||
@@ -1326,7 +1357,77 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos
|
||||
}
|
||||
}
|
||||
int reduce = 0;
|
||||
if (card->has(Constants::AFFINITYGREENCREATURES))
|
||||
if (card->has(Constants::AFFINITYALLCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser("creature", NULL);
|
||||
reduce = card->controller()->game->battlefield->countByCanTarget(tc) + card->controller()->opponent()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYCONTROLLERCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser("creature", NULL);
|
||||
reduce = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYATTACKINGCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[attacking]", NULL);
|
||||
reduce = card->controller()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYOPPONENTCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser("creature", NULL);
|
||||
reduce = card->controller()->opponent()->game->battlefield->countByCanTarget(tc);
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYGRAVECREATURES))
|
||||
{
|
||||
WParsedInt* value = NEW WParsedInt("type:creature:mygraveyard",NULL, card);
|
||||
if(value)
|
||||
reduce = value->getValue();
|
||||
SAFE_DELETE(value);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYALLDEADCREATURES))
|
||||
{
|
||||
WParsedInt* value = NEW WParsedInt("bothalldeadcreature",NULL, card);
|
||||
if(value)
|
||||
reduce = value->getValue();
|
||||
SAFE_DELETE(value);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYPARTY))
|
||||
{
|
||||
WParsedInt* value = NEW WParsedInt("calculateparty",NULL, card);
|
||||
if(value)
|
||||
reduce = value->getValue();
|
||||
SAFE_DELETE(value);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYBASICLANDTYPES))
|
||||
{
|
||||
WParsedInt* value = NEW WParsedInt("pbasiclandtypes",NULL, card);
|
||||
if(value)
|
||||
reduce = value->getValue();
|
||||
SAFE_DELETE(value);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYTWOBASICLANDTYPES))
|
||||
{
|
||||
WParsedInt* value = NEW WParsedInt("pbasiclandtypes",NULL, card);
|
||||
if(value)
|
||||
reduce = value->getValue() * 2;
|
||||
SAFE_DELETE(value);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYGRAVEINSTSORC))
|
||||
{
|
||||
WParsedInt* value = NEW WParsedInt("pginstantsorcery",NULL, card);
|
||||
if(value)
|
||||
reduce = value->getValue();
|
||||
SAFE_DELETE(value);
|
||||
}
|
||||
else if (card->has(Constants::AFFINITYGREENCREATURES))
|
||||
{
|
||||
TargetChooserFactory tf(getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser("creature[green]", NULL);
|
||||
|
||||
@@ -248,7 +248,18 @@ const char* Constants::MTGBasicAbilities[] = {
|
||||
"backgroundpartner", //Can choose a backgorund partner as commander (e.g. "Faceless One").
|
||||
"bottomlibrarydeath", //It goes to bottom of library after death (e.g. "Quintorius, Loremaster").
|
||||
"noloyaltydamage", //Damage does not cause loyalty counter to be removed from a Planeswalker (e.g. "Spark Rupture").
|
||||
"nodefensedamage" //Damage does not cause defense counter to be removed from a Battle.
|
||||
"nodefensedamage", //Damage does not cause defense counter to be removed from a Battle.
|
||||
"affinityallcreatures", //Cost 1 less for each creature in all battlefields.
|
||||
"affinitycontrollercreatures", //Cost 1 less for each creature in controller battlefield.
|
||||
"affinityopponentcreatures", //Cost 1 less for each creature in opponent battlefield.
|
||||
"affinityalldeadcreatures", //Cost 1 less for each died creature in this turn.
|
||||
"affinityparty", //Cost 1 less for each creature in your party.
|
||||
"affinityenchantments", //Cost 1 less for each enchantment in your battlefield.
|
||||
"affinitybasiclandtypes", //Cost 1 less for each basic land type in your battlefield.
|
||||
"affinitytwobasiclandtypes", //Cost 2 less for each basic land type in your battlefield.
|
||||
"affinitygravecreatures", //Cost 1 less for each creature in your graveyard.
|
||||
"affinityattackingcreatures", //Cost 1 less for each attacking creature in your battlefield.
|
||||
"affinitygraveinstsorc" //Cost 1 less for each instant or sorcery in your graveyard.
|
||||
};
|
||||
|
||||
map<string,int> Constants::MTGBasicAbilitiesMap;
|
||||
|
||||
@@ -579,15 +579,17 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
||||
|
||||
// This fix issue types problem when card change zone with different card types than its original version (e.g. double face cards or cards that gained new types before to change zone).
|
||||
std::vector<int> realTypes;
|
||||
string originame = copy->name;
|
||||
string realName = copy->name;
|
||||
if(doCopy && !asCopy && !inplaytoinplay && !equal(copy->types.begin(), copy->types.end(), card->types.begin()) ){
|
||||
realTypes = copy->types;
|
||||
copy->types = card->types;
|
||||
if(copy->name == "")
|
||||
copy->name = originame;
|
||||
copy->mPropertiesChangedSinceLastUpdate = false;
|
||||
}
|
||||
|
||||
// This fix issue when card changes zone with different name than its original version (e.g. double face cards).
|
||||
if(doCopy && !asCopy && !inplaytoinplay && copy->name != card->name)
|
||||
copy->name = card->name;
|
||||
|
||||
// Copy all the counters of the original card... (solving the bug on comparison cards with counter before zone changing events)
|
||||
if(card->counters && doCopy && !asCopy && !inplaytoinplay){
|
||||
for (unsigned int i = 0; i < card->counters->counters.size(); i++){
|
||||
@@ -799,15 +801,17 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
||||
if(doCopy && !inplaytoinplay && copy->has(Constants::ISPREY))
|
||||
copy->basicAbilities[Constants::ISPREY] = 0;
|
||||
|
||||
// Reset original types when card change zone with different card types than its original version (e.g. double face cards).
|
||||
// Reset original types when card changes zone with different card types than its original version (e.g. double face cards).
|
||||
if(doCopy && !inplaytoinplay && realTypes.size()){
|
||||
copy->types = realTypes;
|
||||
realTypes.clear();
|
||||
if(copy->name == "")
|
||||
copy->name = originame;
|
||||
copy->mPropertiesChangedSinceLastUpdate = false;
|
||||
}
|
||||
|
||||
// Reset the original name when card changes zone with different name than its original version (e.g. double face cards).
|
||||
if(doCopy && !inplaytoinplay && copy->name != realName)
|
||||
copy->name = realName;
|
||||
|
||||
// Erasing counters from copy after the event has been triggered (no counter can survive to a zone changing except the perpetual ones)
|
||||
if(doCopy && !inplaytoinplay && copy->counters && copy->counters->mCount > 0){
|
||||
for (unsigned int i = 0; i < copy->counters->counters.size(); i++){
|
||||
|
||||
@@ -1520,6 +1520,51 @@ void WParsedInt::extendedParse(string s, Spell * spell, MTGCardInstance * card)
|
||||
if(card->controller()->getObserver()->currentlyActing() != card->controller())
|
||||
intValue = 1 - intValue;
|
||||
}
|
||||
else if (s == "pinstsorcount" || s == "oinstsorcount") // Return the number of instant or sorceries that were casted this turn by controller or opponent.
|
||||
{
|
||||
intValue = (s == "pinstsorcount")?card->controller()->game->stack->seenThisTurn("*[instant;sorcery]", Constants::CAST_ALL):card->controller()->opponent()->game->stack->seenThisTurn("*[instant;sorcery]", Constants::CAST_ALL);
|
||||
}
|
||||
else if ((s.find("palldead") != string::npos) || (s.find("oalldead") != string::npos)) // Return the number of cards of a specific type that died this turn for controller or opponent.
|
||||
{
|
||||
int hasdeadtype = 0;
|
||||
MTGGameZone * grave = (s.find("oalldead") != string::npos)?card->controller()->opponent()->game->graveyard:card->controller()->game->graveyard;
|
||||
Player * checkCurrent = (s.find("oalldead") != string::npos)?card->controller()->opponent():card->controller();
|
||||
string checktype = s.substr(8);
|
||||
for(unsigned int gy = 0; gy < grave->cardsSeenThisTurn.size(); gy++)
|
||||
{
|
||||
MTGCardInstance * checkCard = grave->cardsSeenThisTurn[gy];
|
||||
if(checkCard->hasType(checktype) &&
|
||||
((checkCard->previousZone == checkCurrent->game->battlefield)||
|
||||
(checkCard->previousZone == checkCurrent->opponent()->game->battlefield))//died from battlefield
|
||||
)
|
||||
{
|
||||
hasdeadtype++;
|
||||
}
|
||||
}
|
||||
intValue = hasdeadtype;
|
||||
}
|
||||
else if (s.find("bothalldead") != string::npos) // Return the number of cards of a specific type that died this turn.
|
||||
{
|
||||
int hasdeadtype = 0;
|
||||
string checktype = s.substr(11);
|
||||
for(int cp = 0; cp < 2; cp++)
|
||||
{
|
||||
Player * checkCurrent = card->getObserver()->players[cp];
|
||||
MTGGameZone * grave = checkCurrent->game->graveyard;
|
||||
for(unsigned int gy = 0; gy < grave->cardsSeenThisTurn.size(); gy++)
|
||||
{
|
||||
MTGCardInstance * checkCard = grave->cardsSeenThisTurn[gy];
|
||||
if(checkCard->hasType(checktype) &&
|
||||
((checkCard->previousZone == checkCurrent->game->battlefield)||
|
||||
(checkCard->previousZone == checkCurrent->opponent()->game->battlefield))//died from battlefield
|
||||
)
|
||||
{
|
||||
hasdeadtype++;
|
||||
}
|
||||
}
|
||||
}
|
||||
intValue = hasdeadtype;
|
||||
}
|
||||
else if(!intValue)//found nothing, try parsing a atoi
|
||||
{
|
||||
intValue = atoi(s.c_str());
|
||||
|
||||
Reference in New Issue
Block a user