diff --git a/projects/mtg/bin/Res/rules/Commander.txt b/projects/mtg/bin/Res/rules/Commander.txt index 8047057f6..e63d6210c 100644 --- a/projects/mtg/bin/Res/rules/Commander.txt +++ b/projects/mtg/bin/Res/rules/Commander.txt @@ -53,7 +53,6 @@ auto=lord(Swamp[-noactivatedability;-nomanaability;-notapability;land]|MyBattlef auto=lord(Mountain[-noactivatedability;-nomanaability;-notapability;land]|MyBattlefield) {T}:Add{R} auto=lord(Forest[-noactivatedability;-nomanaability;-notapability;land]|MyBattlefield) {T}:Add{G} - #Mana Empties from manapool at the end of each phase auto=@each untap:removeMana(*) auto=@each upkeep:removeMana(*) @@ -68,6 +67,23 @@ auto=@each secondmain:removeMana(*) auto=@each end:removeMana(*) auto=@each cleanup:removeMana(*) +#Modal dual face card flip back rule +auto=@each untap restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each upkeep restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each draw restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each firstmain restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each combatbegins restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each attackers restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each blockers restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each combatdamage restriction{type(*[isflipped]|nonbattlezone))~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each combatEnds restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each secondmain restriction{type(*[isflipped]|nonbattlezone))~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each end restriction{compare(type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each cleanup restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@movedto(other *|nonbattlezone) restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@movedto(other *|stack) restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@movedto(other *|battlefield) restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller + #Monarch rule auto=@each my endofturn restriction{compare(pmonarch)~morethan~0}:draw:1 diff --git a/projects/mtg/bin/Res/rules/mtg.txt b/projects/mtg/bin/Res/rules/mtg.txt index 163e3be06..5c79f4692 100644 --- a/projects/mtg/bin/Res/rules/mtg.txt +++ b/projects/mtg/bin/Res/rules/mtg.txt @@ -45,7 +45,6 @@ auto=sethand:7 auto=@each my draw:draw:1 auto=maxPlay(land)1 - #Lands Mana Rules auto=lord(Plains[-noactivatedability;-nomanaability;-notapability;land]|MyBattlefield) {T}:Add{W} auto=lord(Island[-noactivatedability;-nomanaability;-notapability;land]|MyBattlefield) {T}:Add{U} @@ -53,7 +52,6 @@ auto=lord(Swamp[-noactivatedability;-nomanaability;-notapability;land]|MyBattlef auto=lord(Mountain[-noactivatedability;-nomanaability;-notapability;land]|MyBattlefield) {T}:Add{R} auto=lord(Forest[-noactivatedability;-nomanaability;-notapability;land]|MyBattlefield) {T}:Add{G} - #Mana Empties from manapool at the end of each phase auto=@each untap:removeMana(*) auto=@each upkeep:removeMana(*) @@ -68,6 +66,23 @@ auto=@each secondmain:removeMana(*) auto=@each end:removeMana(*) auto=@each cleanup:removeMana(*) +#Modal dual face card flip back rule +auto=@each untap restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each upkeep restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each draw restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each firstmain restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each combatbegins restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each attackers restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each blockers restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each combatdamage restriction{type(*[isflipped]|nonbattlezone))~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each combatEnds restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each secondmain restriction{type(*[isflipped]|nonbattlezone))~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each end restriction{compare(type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@each cleanup restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@movedto(other *|nonbattlezone) restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@movedto(other *|stack) restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller +auto=@movedto(other *|battlefield) restriction{type(*[isflipped]|nonbattlezone)~morethan~0}:ability$!all(*[isflipped]|nonbattlezone) doubleside()!$ controller + #Monarch rule auto=@each my endofturn restriction{compare(pmonarch)~morethan~0}:draw:1 diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index 62f61042c..3b07790a3 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -974,7 +974,7 @@ auto={6}{T}:name(X=6) name(X=6) transforms((,newability[replacedraw reveal:6 opt auto={7}{T}:name(X=7) name(X=7) transforms((,newability[replacedraw reveal:7 optionone name(Choose a card) target(*|reveal) moveto(myhand) and!( all(*[zpos<=6]|mylibrary) moveto(myhand) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend revealend])) ueot auto={8}{T}:name(X=8) name(X=8) transforms((,newability[replacedraw reveal:8 optionone name(Choose a card) target(*|reveal) moveto(myhand) and!( all(*[zpos<=7]|mylibrary) moveto(myhand) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend revealend])) ueot auto={9}{T}:name(X=9) name(X=9) transforms((,newability[replacedraw reveal:9 optionone name(Choose a card) target(*|reveal) moveto(myhand) and!( all(*[zpos<=8]|mylibrary) moveto(myhand) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend revealend])) ueot -auto={10}{T}:name(X=10) name(X=10) transforms((,newability[replacedraw reveal:10 optionone name(Choose a card) target(*|reveal) moveto(myhand) and!( all(*[zpos<=9]|mylibrary) moveto(myhand) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend afterreveal all(*[zpos<=10]) moveto(myhand) afterrevealend revealend])) ueot +auto={10}{T}:name(X=10) name(X=10) transforms((,newability[replacedraw reveal:10 optionone name(Choose a card) target(*|reveal) moveto(myhand) and!( all(*[zpos<=9]|mylibrary) moveto(myhand) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend afterrevealed all(*[zpos<=10]) moveto(myhand) afterrevealedend revealend])) ueot text={X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0. mana={10} type=Artifact @@ -59937,8 +59937,8 @@ name=Turntimber Symbiosis restriction=compare(isflipped)~equalto~0 anyzone={0}:doubleside(Turntimber, Serpentine Wood) autohand={0}:restriction{can play land,compare(isflipped)~equalto~1} name(Turntimber, Serpentine Wood) name(Turntimber, Serpentine Wood) flip(Turntimber, Serpentine Wood) forcetype(land) -auto=choice name(Look seven and put creature with manacost 3 or less) name(Look seven and put creature with manacost 3 or less) reveal:7 optionone name(Get Creature) target(creature[manacost<=3]|reveal) moveTo(myBattlefield) and!( counter(1/1,3) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend revealend restriction{type(creature[manacost<=3;zpos<=7]|myLibrary)~morethan~0} -auto=choice name(Look seven and put creature with manacost 4 or more) name(Look seven and put creature with manacost 4 or more) reveal:7 optionone name(Get Creature) target(creature[manacost>=4]|reveal) moveTo(myBattlefield) optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend revealend restriction{type(creature[manacost>=4;zpos<=7]|myLibrary)~morethan~0} +aicode=activate target(*[zpos=1]|mylibrary) transforms((,newability[if type(creature[zpos<=7]|mylibrary)~equalto~0 then all(*[zpos<=7]|mylibrary) moveto(myreveal) and!( bottomoflibrary )!],newability[if type(creature[zpos<=7]|mylibrary)~morethan~0 then target(creature[zpos<=7]|mylibrary) moveto(myBattlefield) and!( transforms((,newability[all(*[zpos<=7]|mylibrary) moveto(myreveal) and!( bottomoflibrary )!],newability[if cantargetcard(creature[manacost<=3]|*) then counter(1/1.3)])) oneshot )! ])) oneshot +auto=name(Look seven and put creature in play) reveal:7 optionone name(Get Creature) target(creature|reveal) moveTo(mylibrary) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put on bottom) target(*|reveal) bottomoflibrary and!( all(*|reveal) bottomoflibrary )! optiontwoend afterrevealed all(tobecast|mylibrary) moveto(myBattlefield) and!( transforms((,newability[if cantargetcard(creature[manacost<=3]|*) then counter(1/1.3)])) oneshot )! afterrevealedend revealend text=Look at the top seven cards of your library. You may put a creature card from among them onto the battlefield. If that card has converted mana cost 3 or less, it enters with three additional +1/+1 counters on it. Put the rest on the bottom of your library in a random order. // Turntimber, Serpentine Wood mana={4}{G}{G}{G} type=Sorcery diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index 0d01fc9b5..1229161b9 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -632,9 +632,11 @@ int OrderedAIAction::getEfficiency() efficiency = 90; } } - else if (dynamic_cast(a)) + else if (AATurnSide * ats = dynamic_cast(a)) { - efficiency = 0; // AI does not have to use the doubleside ability to avoid loops. + efficiency = 0; // AI does not have to use the doubleside ability to avoid loops but it can randomly choose to flip card and cast its back side. + if(std::rand() % 2) + ats->source->isFlipped = !ats->source->isFlipped; } else if (ATokenCreator * atc = dynamic_cast(a)) { diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index b9878e962..43f755e21 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -4349,12 +4349,15 @@ int AATurnSide::resolve() if(_target->mutation && _target->parentCards.size() > 0) return 0; // Mutated down cards cannot be turned, they will follow the fate of top-card MTGCard * fcard; MTGCardInstance* sideCard; + if(_target->controller()->isAI() && _target->isFlipped) _target->isFlipped = false; // If it's AI calling back we just have to reset isFLipped flag and then return. + if(!_target->isFlipped && _SideName == "") return 0; // No need to turn front if card has not been flipped before. if(!_target->isFlipped){ fcard = MTGCollection()->getCardByName(_SideName); if(!fcard) return 0; sideCard = NEW MTGCardInstance(fcard, _target->controller()->game); _target->nameOrig = _target->name; _target->name = sideCard->name; + _target->setName(sideCard->name); if(!sideCard) return 0; if(sideCard->getManaCost()){ if(_target->getManaCost()->getAlternative()){ @@ -4367,6 +4370,7 @@ int AATurnSide::resolve() fcard = MTGCollection()->getCardByName(_target->nameOrig); if(!fcard) return 0; _target->name = _target->nameOrig; + _target->setName(_target->nameOrig); _target->nameOrig = ""; sideCard = NEW MTGCardInstance(fcard, _target->controller()->game); if(!sideCard) return 0; @@ -4375,13 +4379,26 @@ int AATurnSide::resolve() _target->getManaCost()->copy(sideCard->getManaCost()); // Restore the original side cost mana symbols. } } - for (int i = ((int)_target->types.size())-1; i >= 0; --i) // Load all the types from the current side - _target->removeType(_target->types[i]); - for (int i = 0; i < ((int)sideCard->types.size()); i++) - _target->addType(sideCard->types[i]); + if(_target->owner->playMode != Player::MODE_TEST_SUITE) + { + _target->setMTGId(sideCard->getMTGId()); + _target->setId = sideCard->setId; + } + _target->power = sideCard->power; + _target->life = sideCard->life; + _target->toughness = sideCard->toughness; + _target->origpower = sideCard->origpower; + _target->origtoughness = sideCard->origtoughness; + _target->basepower = sideCard->basepower; + _target->basetoughness = sideCard->basetoughness; + _target->types = sideCard->types; _target->text = sideCard->text; _target->formattedText = sideCard->formattedText; + _target->magicText = sideCard->magicText; + _target->colors = sideCard->colors; + _target->basicAbilities = sideCard->basicAbilities; _target->isFlipped = !_target->isFlipped; + _target->mPropertiesChangedSinceLastUpdate = true; SAFE_DELETE(sideCard); return 1; } diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index 996df4074..2c086e71b 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -281,6 +281,11 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) match = NULL; } + if (isFlipped != card->isFlipped) + { + match = NULL; + } + if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped())) { match = NULL; diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index fc7937585..a92e1a5ae 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -1544,6 +1544,18 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) cd.isToken = 1; } } + //Has been flipped + else if (attribute.find("isflipped") != string::npos) + { + if (minus) + { + cd.isFlipped = false; + } + else + { + cd.isFlipped = true; + } + } //Has x in cost else if (attribute.find("hasx") != string::npos) { diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 6ed5e5d51..6c241ac8d 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -2125,8 +2125,9 @@ void GameObserver::logAction(Player* player, const string& s) { void GameObserver::logAction(MTGCardInstance* card, MTGGameZone* zone, size_t index, int result) { stringstream stream; if(zone == NULL) zone = card->currentZone; + string zoneName = (zone != NULL)?zone->getName():"UnknownZone"; // Fixed a crash when zone pointer was null. stream << "p" << ((card->controller()==players[0])?"1.":"2.") - << zone->getName()<< "[" << index << "] " + << zoneName << "[" << index << "] " << result << card->getLCName(); logAction(stream.str()); } diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 3f7ba763d..480a90f24 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -590,6 +590,18 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->isToken = 1; } } + //Has been flipped + else if (attribute.find("isflipped") != string::npos) + { + if (minus) + { + cd->isFlipped = false; + } + else + { + cd->isFlipped = true; + } + } //Has x in cost else if (attribute.find("hasx") != string::npos) {