Fixed some primitives, added some new primitives from MAT set, added new triggers to handle better counters, improved a lot of abilities for replacing atoi with WParserInt class, fixed bug on change types on xone changing, fixed bug on manacost during mutate and flip actions, fixed other minor bugs.

This commit is contained in:
Vittorio Alfieri
2023-05-21 18:52:16 +02:00
parent c3e8379258
commit dd28f274d1
11 changed files with 482 additions and 90 deletions

View File

@@ -2599,6 +2599,7 @@ AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, M
nb = checkcounter->nb;
delete checkcounter;
}
int totalcounters = 0;
if (nb > 0)
{
if(_target->has(Constants::COUNTERSHROUD)) // Added to avoid the counter increasement (e.g. "Solemnity").
@@ -2631,8 +2632,15 @@ AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, M
if(!maxNb || (maxNb && currentAmount < maxNb))
{
_target->counters->addCounter(name.c_str(), power, toughness, noevent, false, source);
totalcounters++;
}
}
if (!noevent)
{
WEvent * w = NEW WEventTotalCounters(_target->counters, name.c_str(), power, toughness, true, false, totalcounters, source);
dynamic_cast<WEventTotalCounters*>(w)->targetCard = _target->counters->target;
_target->getObserver()->receiveEvent(w);
}
}
else
{
@@ -2641,6 +2649,13 @@ AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, M
while (_target->next)
_target = _target->next;
_target->counters->removeCounter(name.c_str(), power, toughness, noevent, false, source);
totalcounters++;
}
if (!noevent)
{
WEvent * e = NEW WEventTotalCounters(_target->counters, name.c_str(), power, toughness, false, true, totalcounters, source);
dynamic_cast<WEventTotalCounters*>(e)->targetCard = _target->counters->target;
_target->getObserver()->receiveEvent(e);
}
}
@@ -4535,6 +4550,7 @@ int AANewTarget::resolve()
source->types[0] = 7;
source->types[1] = 1;
}
source->mPropertiesChangedSinceLastUpdate = false;
if(source->hasType(Subtypes::TYPE_LEGENDARY)){ // Check if the mutated card is a duplicated legendary card
MTGNewLegend *testlegend = NEW MTGNewLegend(source->getObserver(),source->getObserver()->mLayers->actionLayer()->getMaxId());
testlegend->CheckLegend(source);
@@ -4825,7 +4841,6 @@ int AATurnSide::resolve()
_target->magicText = sideCard->magicText;
_target->colors = sideCard->colors;
_target->isFlipped = (_target->isFlipped > 0)?0:1;
_target->mPropertiesChangedSinceLastUpdate = true;
SAFE_DELETE(sideCard);
return 1;
}

View File

@@ -274,7 +274,11 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe
int Turn = 0;
size_t start = restriction[i].find(":", check);
size_t end = restriction[i].find(" ", check);
Turn = atoi(restriction[i].substr(start + 1, end - start - 1).c_str());
WParsedInt* parser = NEW WParsedInt(restriction[i].substr(start + 1, end - start - 1), card);
if(parser){
Turn = parser->intValue;
SAFE_DELETE(parser);
}
if(observer->turn < Turn-1)
return 0;
}
@@ -1343,28 +1347,100 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
}
//poisoned player - controller of card
if (TargetChooser * tc = parseSimpleTC(s, "poisonedof", card))
return NEW TrplayerPoisoned(observer, id, card, tc, once, true, false);
if (TargetChooser * tc = parseSimpleTC(s, "poisonedof", card)){
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
return NEW TrplayerPoisoned(observer, id, card, tc, once, true, false, plus);
}
//poisoned player - opponent of card controller
if (TargetChooser * tc = parseSimpleTC(s, "poisonedfoeof", card))
return NEW TrplayerPoisoned(observer, id, card, tc, once, false, true);
if (TargetChooser * tc = parseSimpleTC(s, "poisonedfoeof", card)){
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
return NEW TrplayerPoisoned(observer, id, card, tc, once, false, true, plus);
}
//energized player - controller of card
if (TargetChooser * tc = parseSimpleTC(s, "energizedof", card))
return NEW TrplayerEnergized(observer, id, card, tc, once, true, false);
if (TargetChooser * tc = parseSimpleTC(s, "energizedof", card)){
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
return NEW TrplayerEnergized(observer, id, card, tc, once, true, false, plus);
}
//energized player - opponent of card controller
if (TargetChooser * tc = parseSimpleTC(s, "energizedfoeof", card))
return NEW TrplayerEnergized(observer, id, card, tc, once, false, true);
if (TargetChooser * tc = parseSimpleTC(s, "energizedfoeof", card)){
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
return NEW TrplayerEnergized(observer, id, card, tc, once, false, true, plus);
}
//experienced player - controller of card
if (TargetChooser * tc = parseSimpleTC(s, "experiencedof", card))
return NEW TrplayerExperienced(observer, id, card, tc, once, true, false);
if (TargetChooser * tc = parseSimpleTC(s, "experiencedof", card)){
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
return NEW TrplayerExperienced(observer, id, card, tc, once, true, false, plus);
}
//experienced player - opponent of card controller
if (TargetChooser * tc = parseSimpleTC(s, "experiencedfoeof", card))
return NEW TrplayerExperienced(observer, id, card, tc, once, false, true);
if (TargetChooser * tc = parseSimpleTC(s, "experiencedfoeof", card)){
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
return NEW TrplayerExperienced(observer, id, card, tc, once, false, true, plus);
}
//becomes monarch - controller of card
if (TargetChooser * tc = parseSimpleTC(s, "becomesmonarchof", card))
@@ -1658,6 +1734,62 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
return NEW TrTargeted(observer, id, card, tc, fromTc, 0, once, limitOnceATurn);
}
if (s.find("totalcounteradded(") != string::npos)
{
vector<string>splitCounter = parseBetween(s,"totalcounteradded(",")");
Counter * counter = NULL;
bool duplicate = false;
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
else if(s.find("(duplicateall)") != string::npos)
duplicate = true;
else if(s.find("(any)") == string::npos)
counter = parseCounter(splitCounter[1],card,NULL);
TargetChooser * tc = parseSimpleTC(s, "from", card);
TargetChooser *exception = parseSimpleTC(s, "except", card); // Added a new keyword except to specify a counter add/remove exception in order to avoid counter loop (eg. Doubling Season)
if(exception)
return NEW TrTotalCounter(observer, id, card, counter, tc, 1, once, duplicate, plus, limitOnceATurn, exception->source);
else
return NEW TrTotalCounter(observer, id, card, counter, tc, 1, once, duplicate, plus, limitOnceATurn);
}
if (s.find("totalcounterremoved(") != string::npos)
{
vector<string>splitCounter = parseBetween(s,"totalcounterremoved(",")");
Counter * counter = NULL;
bool duplicate = false;
int plus = 0;
if(s.find("plus(1)") != string::npos)
plus = 1;
else if(s.find("plus(2)") != string::npos)
plus = 2;
else if(s.find("plus(3)") != string::npos)
plus = 3;
else if(s.find("plus(4)") != string::npos)
plus = 4;
else if(s.find("plus(5)") != string::npos)
plus = 5;
else if(s.find("(duplicateall)") != string::npos)
duplicate = true;
else if(s.find("(any)") == string::npos)
counter = parseCounter(splitCounter[1],card,NULL);
TargetChooser * tc = parseSimpleTC(s, "from", card);
TargetChooser *exception = parseSimpleTC(s, "except", card); // Added a new keyword except to specify a counter add/remove exception in order to avoid counter loop (eg. Doubling Season)
if(exception)
return NEW TrTotalCounter(observer, id, card, counter, tc, 0, once, duplicate, plus, limitOnceATurn, exception->source);
else
return NEW TrTotalCounter(observer, id, card, counter, tc, 0, once, duplicate, plus, limitOnceATurn);
}
if (s.find("counteradded(") != string::npos)
{
vector<string>splitCounter = parseBetween(s,"counteradded(",")");
@@ -3491,8 +3623,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitPlaceFromTop = parseBetween(s, "placefromthetop(", ")");
if (splitPlaceFromTop.size())
{
int position = 0;
WParsedInt* parser = NEW WParsedInt(splitPlaceFromTop[1], card);
int position = parser->intValue;
if(parser){
position = parser->intValue;
SAFE_DELETE(parser);
}
MTGAbility * a = NEW AALibraryPosition(observer, id, card, target, NULL, position);
a->oneShot = 1;
//andability
@@ -3967,7 +4103,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitPoison = parseBetween(s, "alterpoison:", " ", false);
if (splitPoison.size())
{
int poison = atoi(splitPoison[1].c_str());
int poison = 0;
WParsedInt* parser = NEW WParsedInt(splitPoison[1], card);
if(parser){
poison = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterPoison(observer, id, card, t, poison, NULL, who);
a->oneShot = 1;
@@ -3978,7 +4119,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitEnergy = parseBetween(s, "alterenergy:", " ", false);
if (splitEnergy.size())
{
int energy = atoi(splitEnergy[1].c_str());
int energy = 0;
WParsedInt* parser = NEW WParsedInt(splitEnergy[1], card);
if(parser){
energy = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterEnergy(observer, id, card, t, energy, NULL, who);
a->oneShot = 1;
@@ -3989,7 +4135,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitExperience = parseBetween(s, "alterexperience:", " ", false);
if (splitExperience.size())
{
int exp = atoi(splitExperience[1].c_str());
int exp = 0;
WParsedInt* parser = NEW WParsedInt(splitExperience[1], card);
if(parser){
exp = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterExperience(observer, id, card, t, exp, NULL, who);
a->oneShot = 1;
@@ -4000,7 +4151,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitDungeonCompleted = parseBetween(s, "completedungeon:", " ", false);
if (splitDungeonCompleted.size())
{
int dungeoncompleted = atoi(splitDungeonCompleted[1].c_str());
int dungeoncompleted = 0;
WParsedInt* parser = NEW WParsedInt(splitDungeonCompleted[1], card);
if(parser){
dungeoncompleted = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterDungeonCompleted(observer, id, card, t, dungeoncompleted, NULL, who);
a->oneShot = 1;
@@ -4011,7 +4167,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitYidaroCounter = parseBetween(s, "alteryidarocount:", " ", false);
if (splitYidaroCounter.size())
{
int yidarocount = atoi(splitYidaroCounter[1].c_str());
int yidarocount = 0;
WParsedInt* parser = NEW WParsedInt(splitYidaroCounter[1], card);
if(parser){
yidarocount = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterYidaroCount(observer, id, card, t, yidarocount, NULL, who);
a->oneShot = 1;
@@ -4042,7 +4203,11 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitMutated = parseBetween(s, "altermutationcounter:", " ", false);
if (splitMutated.size())
{
card->mutation += atoi(splitMutated[1].c_str());
WParsedInt* parser = NEW WParsedInt(splitMutated[1], card);
if(parser){
card->mutation += parser->intValue;
SAFE_DELETE(parser);
}
WEvent * e = NEW WEventCardMutated(card);
card->getObserver()->receiveEvent(e);
}
@@ -4051,12 +4216,20 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitMutatedOver = parseBetween(s, "mutationover:", " ", false);
if (splitMutatedOver.size())
{
card->mutation += atoi(splitMutatedOver[1].c_str());
WParsedInt* parser = NEW WParsedInt(splitMutated[1], card);
if(parser){
card->mutation += parser->intValue;
SAFE_DELETE(parser);
}
}
vector<string> splitMutatedUnder = parseBetween(s, "mutationunder:", " ", false);
if (splitMutatedUnder.size())
{
card->mutation += atoi(splitMutatedUnder[1].c_str());
WParsedInt* parser = NEW WParsedInt(splitMutated[1], card);
if(parser){
card->mutation += parser->intValue;
SAFE_DELETE(parser);
}
}
//perform boast
@@ -4093,7 +4266,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitSurveilOffset = parseBetween(s, "altersurvoffset:", " ", false);
if (splitSurveilOffset.size())
{
int surveilOffset = atoi(splitSurveilOffset[1].c_str());
int surveilOffset = 0;
WParsedInt* parser = NEW WParsedInt(splitSurveilOffset[1], card);
if(parser){
surveilOffset = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterSurveilOffset(observer, id, card, t, surveilOffset, NULL, who);
a->oneShot = 1;
@@ -4104,7 +4282,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitDevotionOffset = parseBetween(s, "alterdevoffset:", " ", false);
if (splitDevotionOffset.size())
{
int devotionOffset = atoi(splitDevotionOffset[1].c_str());
int devotionOffset = 0;
WParsedInt* parser = NEW WParsedInt(splitDevotionOffset[1], card);
if(parser){
devotionOffset = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AAAlterDevotionOffset(observer, id, card, t, devotionOffset, NULL, who);
a->oneShot = 1;
@@ -4115,7 +4298,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitPrevent = parseBetween(s, "prevent:", " ", false);
if (splitPrevent.size())
{
int preventing = atoi(splitPrevent[1].c_str());
int preventing = 0;
WParsedInt* parser = NEW WParsedInt(splitPrevent[1], card);
if(parser){
preventing = parser->intValue;
SAFE_DELETE(parser);
}
Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AADamagePrevent(observer, id, card, t, preventing, NULL, who);
a->oneShot = 1;
@@ -4139,7 +4327,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
{
Damageable * t = spell ? spell->getNextDamageableTarget() : NULL;
vector<string> ccParameters = split( splitAuraIncreaseReduce[1], ':');
int amount = atoi(ccParameters[1].c_str());
int amount = 0;
WParsedInt* parser = NEW WParsedInt(ccParameters[1], card);
if(parser){
amount = parser->intValue;
SAFE_DELETE(parser);
}
int color = Constants::GetColorStringIndex(ccParameters[0]);
if(ccParameters[0] == "colorless")
color = 0;
@@ -4155,7 +4348,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitSetHand = parseBetween(s, "sethand:", " ", false);
if (splitSetHand.size())
{
int hand = atoi(splitSetHand[1].c_str());
int hand = 0;
WParsedInt* parser = NEW WParsedInt(splitSetHand[1], card);
if(parser){
hand = parser->intValue;
SAFE_DELETE(parser);
}
Damageable * t = spell ? spell->getNextDamageableTarget() : NULL;
MTGAbility * a = NEW AASetHand(observer, id, card, t, hand, NULL, who);
a->oneShot = 1;
@@ -4364,7 +4562,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
DebugTrace("MTGAbility Parse error in rampage" << s);
return NULL;
}
int MaxOpponent = atoi(rampageParameters[1].c_str());
int MaxOpponent = 0;
WParsedInt* parser = NEW WParsedInt(rampageParameters[1], card);
if(parser){
MaxOpponent = parser->intValue;
SAFE_DELETE(parser);
}
return NEW ARampageAbility(observer, id, card, power, toughness, MaxOpponent);
}
@@ -4546,8 +4749,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitRemoveSpecificCounters = parseBetween(s, "removesinglecountertype(", ")");
if (splitRemoveSpecificCounters.size())
{
int nb = 0;
WParsedInt* parser = NEW WParsedInt(splitRemoveSpecificCounters[1], card);
int nb = parser->intValue;
if(parser){
nb = parser->intValue;
SAFE_DELETE(parser);
}
MTGAbility * a = NEW AARemoveSingleCounter(observer, id, card, target, NULL, nb);
a->oneShot = 1;
a->canBeInterrupted = false;
@@ -4656,8 +4863,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitBloodthirst = parseBetween(s, "bloodthirst:", " ", false);
if (splitBloodthirst.size())
{
int nb = 0;
WParsedInt* parser = NEW WParsedInt(splitBloodthirst[1], card);
int nb = parser->intValue;
if(parser){
nb = parser->intValue;
SAFE_DELETE(parser);
}
return NEW ABloodThirst(observer, id, card, target, nb);
}
@@ -4665,8 +4876,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitVanishing = parseBetween(s, "vanishing:", " ", false);
if (splitVanishing.size())
{
int nb = 0;
WParsedInt* parser = NEW WParsedInt(splitVanishing[1], card);
int nb = parser->intValue;
if(parser){
nb = parser->intValue;
SAFE_DELETE(parser);
}
return NEW AVanishing(observer, id, card, NULL, restrictions, nb, "time");
}
@@ -4674,8 +4889,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitFading = parseBetween(s, "fading:", " ", false);
if (splitFading.size())
{
int nb = 0;
WParsedInt* parser = NEW WParsedInt(splitFading[1], card);
int nb = parser->intValue;
if(parser){
nb = parser->intValue;
SAFE_DELETE(parser);
}
return NEW AVanishing(observer, id, card, NULL, restrictions, nb, "fade");
}
@@ -4863,8 +5082,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
if(splitChangeCost[1].size())
{
vector<string> ccParameters = split( splitChangeCost[1], ':');
WParsedInt * value = NEW WParsedInt(ccParameters[1].c_str(), NULL, card);
int amount = value->getValue();
int amount = 0;
WParsedInt * value = NEW WParsedInt(ccParameters[1], NULL, card);
if(value){
amount = value->getValue();
SAFE_DELETE(value);
}
int color = Constants::GetColorStringIndex(ccParameters[0]);
if(ccParameters[0] == "colorless")
color = 0;
@@ -5120,7 +5343,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
vector<string> splitMaxlevel = parseBetween(s, "maxlevel:", " ", false);
if (splitMaxlevel.size())
{
MTGAbility * a = NEW AAWhatsMax(observer, id, card, card, NULL, atoi(splitMaxlevel[1].c_str()));
int level = 0;
WParsedInt* parser = NEW WParsedInt(splitMaxlevel[1], card);
if(parser){
level = parser->intValue;
SAFE_DELETE(parser);
}
MTGAbility * a = NEW AAWhatsMax(observer, id, card, card, NULL, level);
a->oneShot = 1;
return a;
}
@@ -6508,8 +6737,12 @@ MTGAbility * AbilityFactory::getManaReduxAbility(string s, int id, Spell *, MTGC
return NULL;
}
// figure out the mana cost
WParsedInt * value = NEW WParsedInt(manaCost.c_str(), NULL, card);
int amount = value->getValue();
int amount = 0;
WParsedInt * value = NEW WParsedInt(manaCost, NULL, card);
if(value){
amount = value->getValue();
SAFE_DELETE(value);
}
return NEW AAlterCost(observer, id, card, target, amount, color);
}

View File

@@ -577,18 +577,22 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
if(card->name == copy->name && !card->hasType(Subtypes::TYPE_LEGENDARY) && copy->hasType(Subtypes::TYPE_LEGENDARY)) // This fix issue when cloning a card with nolegend option (e.g. Double Major)
copy->removeType(Subtypes::TYPE_LEGENDARY);
// This fix issue types problem when card change zone with different card types than its original version (e.g. double face cards).
std::vector<int> realTypes;
if(card->name == copy->backSide){ // This fix issue types problem when card dies as its backside (e.g. "Incubator" and "Phyrexian").
string originame = copy->name;
if(doCopy && !asCopy && !inplaytoinplay){
for (int i = ((int)copy->types.size())-1; i >= 0; --i){
realTypes.push_back(copy->types[i]);
copy->removeType(copy->types[i]);
}
copy->name = originame;
for (int i = 0; i < ((int)card->types.size()); i++)
copy->addType(card->types[i]);
if(copy->types[0] == 1 && copy->types[1] == 7){ // Fix order for Legendary Creatures
copy->types[0] = 7;
copy->types[1] = 1;
}
copy->mPropertiesChangedSinceLastUpdate = false;
}
// Copy all the counters of the original card... (solving the bug on comparison cards with counter before zone changing events)
@@ -802,14 +806,18 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
if(doCopy && !inplaytoinplay && copy->has(Constants::ISPREY))
copy->basicAbilities[Constants::ISPREY] = 0;
if(realTypes.size() && card->name == copy->backSide){ // Reset original types when card dies as its backside (e.g. "Incubator" and "Phyrexian").
// Reset original types when card change zone with different card types than its original version (e.g. double face cards).
if(doCopy && !inplaytoinplay && realTypes.size()){
copy->types.clear();
for (int i = 0; i < ((int)realTypes.size()); i++)
for (int i = ((int)realTypes.size())-1; i >= 0; i--)
copy->addType(realTypes[i]);
if(copy->types[0] == 1 && copy->types[1] == 7){ // Fix order for Legendary Creatures
copy->types[0] = 7;
copy->types[1] = 1;
}
copy->name = originame;
copy->mPropertiesChangedSinceLastUpdate = false;
realTypes.clear();
}
// Erasing counters from copy after the event has been triggered (no counter can survive to a zone changing except the perpetual ones)

View File

@@ -170,9 +170,11 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
size_t var_start = value.find("(");
size_t var_end = value.find(")", var_start);
string varString = value.substr(var_start + 1, var_end - var_start - 1);
WParsedInt * value = NEW WParsedInt(varString.c_str(),NULL,c);
if(value)
WParsedInt * value = NEW WParsedInt(varString,NULL,c);
if(value){
manaCost->add(Constants::MTG_COLOR_ARTIFACT, value->getValue());
SAFE_DELETE(value);
}
else
break;
}
@@ -329,7 +331,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
else if(value == "chosencolor")
{
if(c)
manaCost->add(c->chooseacolor, 1);
manaCost->add(c->chooseacolor, 1);
}
else if(value == "cycle")
{

View File

@@ -43,11 +43,16 @@ WEventCardUpdate::WEventCardUpdate(MTGCardInstance * card) :
}
;
WEventCounters::WEventCounters(Counters *counter,string name,int power,int toughness,bool added,bool removed, MTGCardInstance* source) :
WEventCounters::WEventCounters(Counters *counter, string name, int power, int toughness, bool added, bool removed, MTGCardInstance* source) :
WEvent(),counter(counter),name(name),power(power),toughness(toughness),added(added),removed(removed),source(source)
{
}
WEventTotalCounters::WEventTotalCounters(Counters *counter, string name, int power, int toughness, bool added, bool removed, int totalamount, MTGCardInstance* source) :
WEvent(),counter(counter),name(name),power(power),toughness(toughness),added(added),removed(removed),totalamount(totalamount),source(source)
{
}
WEventPhaseChange::WEventPhaseChange(Phase * from, Phase * to) :
WEvent(CHANGE_PHASE), from(from), to(to)
{
@@ -409,6 +414,11 @@ Targetable * WEventCounters::getTarget(int target)
return targetCard;
}
Targetable * WEventTotalCounters::getTarget(int target)
{
return targetCard;
}
Targetable * WEventVampire::getTarget(int target)
{
switch (target)

View File

@@ -735,8 +735,12 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card)
}
else if (s.find("genrand") != string::npos) //Return a random value between 0 and a specific number (minus 1);
{
intValue = 0;
WParsedInt * value = NEW WParsedInt(s.substr(7).c_str(), NULL, card);
intValue = std::rand() % value->getValue();
if(value){
intValue = std::rand() % value->getValue();
SAFE_DELETE(value);
}
}
else if (s == "manacost") //Return the converted manacost
{