Add support for Amonkhet Mechanics
and fix some cards. Added exerted trigger, event and add removemc keyword inside transforms ability so we can soft code Embalm and Eternalize...
This commit is contained in:
@@ -41166,8 +41166,7 @@ type=Enchantment
|
|||||||
[card]
|
[card]
|
||||||
name=Flagstones of Trokair
|
name=Flagstones of Trokair
|
||||||
auto={T}:Add{W}
|
auto={T}:Add{W}
|
||||||
aicode=activate moveTo(myBattlefield) and!(tap(noevent))! target(plains|myLibrary)
|
auto=@movedTo(this|graveyard) from(battlefield):name(search card) ability$!moveTo(myBattlefield) and!(tap(noevent))! target(plains|myLibrary)!$ controller
|
||||||
auto=@movedTo(this|graveyard) from(battlefield):name(search card) reveal:plibrarycount optionone name(choose card) target(plains|reveal) moveto(ownerlibrary) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) and!( all(*|reveal) moveto(ownerlibrary) and!(shuffle)! )! optiontwoend afterrevealed all(tobecast|mylibrary) moveto(ownerlibrary) and!(moveTo(myBattlefield) and!(tap(noevent))!)! afterrevealedend revealend
|
|
||||||
text={T}: Add {W} to your mana pool. -- When Flagstones of Trokair is put into a graveyard from the battlefield, you may search your library for a Plains card and put it onto the battlefield tapped. If you do, shuffle your library.
|
text={T}: Add {W} to your mana pool. -- When Flagstones of Trokair is put into a graveyard from the battlefield, you may search your library for a Plains card and put it onto the battlefield tapped. If you do, shuffle your library.
|
||||||
type=Legendary Land
|
type=Legendary Land
|
||||||
[/card]
|
[/card]
|
||||||
@@ -64909,7 +64908,7 @@ toughness=5
|
|||||||
name=Krosan Verge
|
name=Krosan Verge
|
||||||
auto=tap(noevent)
|
auto=tap(noevent)
|
||||||
auto={T}:Add{1}
|
auto={T}:Add{1}
|
||||||
auto={2}{T}{S}:name(sacrifice to search) ability$! name(search forest) notatarget(forest|mylibrary) moveto(ownerbattlefield) and!(tap(noevent))! !$ controller && ability$! name(search plains) notatarget(plains|mylibrary) moveto(ownerbattlefield) and!(tap(noevent))! !$ controller
|
auto={2}{T}{S}:name(sacrifice to search) transforms((,newability[ability$! name(search forest) notatarget(forest|mylibrary) moveto(ownerbattlefield) and!(tap(noevent))! !$ controller],newability[ability$! name(search plains) notatarget(plains|mylibrary) moveto(ownerbattlefield) and!(tap(noevent))! !$ controller])) oneshot
|
||||||
text=Krosan Verge enters the battlefield tapped. -- {T}: Add {1} to your mana pool. -- {2}, {T}, Sacrifice Krosan Verge: Search your library for a Forest card and a Plains card and put them onto the battlefield tapped. Then shuffle your library.
|
text=Krosan Verge enters the battlefield tapped. -- {T}: Add {1} to your mana pool. -- {2}, {T}, Sacrifice Krosan Verge: Search your library for a Forest card and a Plains card and put them onto the battlefield tapped. Then shuffle your library.
|
||||||
type=Land
|
type=Land
|
||||||
[/card]
|
[/card]
|
||||||
@@ -79818,7 +79817,7 @@ name=Niblis of the Breath
|
|||||||
abilities=flying
|
abilities=flying
|
||||||
auto={U}{T}:may tap target(creature)
|
auto={U}{T}:may tap target(creature)
|
||||||
auto={U}{T}:may untap target(creature)
|
auto={U}{T}:may untap target(creature)
|
||||||
text=Flying -- Whenever Niblis of the Urn attacks, you may tap target creature.
|
text=Flying -- {U}, {T}: You may tap or untap target creature.
|
||||||
mana={2}{U}
|
mana={2}{U}
|
||||||
type=Creature
|
type=Creature
|
||||||
subtype=Spirit
|
subtype=Spirit
|
||||||
@@ -90652,8 +90651,8 @@ toughness=5
|
|||||||
[card]
|
[card]
|
||||||
name=Quarantine Field
|
name=Quarantine Field
|
||||||
auto=counter(0/0,xx,Isolation)
|
auto=counter(0/0,xx,Isolation)
|
||||||
auto=(blink)forsrc target(<prexx>*[-land]|opponentbattlefield)
|
auto=this(variable{xx} >0) (blink)forsrc target(<upto:counter{0%0.1.Isolation}>*[-land]|opponentbattlefield)
|
||||||
text=Quarantine Field enters the battlefield with X isolation counters on it. -- When Quarantine Field enters the battlefield, for each isolation counter on it, exile up to one target nonland permanent an opponent controls until Quarantine Field leaves the battlefield. (WORKAROUND ONLY EXILES UP TO X AND NOT FOR EACH COUNTER)
|
text=Quarantine Field enters the battlefield with X isolation counters on it. -- When Quarantine Field enters the battlefield, for each isolation counter on it, exile up to one target nonland permanent an opponent controls until Quarantine Field leaves the battlefield.
|
||||||
mana={X}{X}{W}{W}
|
mana={X}{X}{W}{W}
|
||||||
type=Enchantment
|
type=Enchantment
|
||||||
[/card]
|
[/card]
|
||||||
@@ -109371,7 +109370,7 @@ type=Instant
|
|||||||
[/card]
|
[/card]
|
||||||
[card]
|
[card]
|
||||||
name=Solitary Confinement
|
name=Solitary Confinement
|
||||||
auto=upcost[{D(*|myhand)}] sacrifice
|
auto=@each my upkeep :name(discard or sacrifice) ability$!if type(*|myhand)~morethan~0 then choice reject notatarget(*|myhand) _ choice sacrifice all(mystored)!$ controller
|
||||||
auto=phasealter(remove,draw,controller)
|
auto=phasealter(remove,draw,controller)
|
||||||
abilities=playershroud
|
abilities=playershroud
|
||||||
auto=preventalldamage to(controller)
|
auto=preventalldamage to(controller)
|
||||||
|
|||||||
@@ -1406,6 +1406,28 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TrCardExerted: public Trigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TrCardExerted(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false) :
|
||||||
|
Trigger(observer, id, source, once, tc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int triggerOnEventImpl(WEvent * event)
|
||||||
|
{
|
||||||
|
WEventCardExerted * e = dynamic_cast<WEventCardExerted *> (event);
|
||||||
|
if (!e) return 0;
|
||||||
|
if (!tc->canTarget(e->card)) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrCardExerted * clone() const
|
||||||
|
{
|
||||||
|
return NEW TrCardExerted(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class TrCombatTrigger: public Trigger
|
class TrCombatTrigger: public Trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -5174,6 +5196,7 @@ public:
|
|||||||
list<int> oldcolors;
|
list<int> oldcolors;
|
||||||
list<int> oldtypes;
|
list<int> oldtypes;
|
||||||
vector<int> dontremove;
|
vector<int> dontremove;
|
||||||
|
bool removemc;
|
||||||
bool addNewColors;
|
bool addNewColors;
|
||||||
bool remove;
|
bool remove;
|
||||||
bool removeCreatureSubtypes;
|
bool removeCreatureSubtypes;
|
||||||
@@ -7290,6 +7313,57 @@ public:
|
|||||||
return NEW AProvoke(*this);
|
return NEW AProvoke(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//exert
|
||||||
|
class AExert: public InstantAbility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MTGAbility * andAbility;
|
||||||
|
AExert(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target) :
|
||||||
|
InstantAbility(observer, _id, _source)
|
||||||
|
{
|
||||||
|
target = _target;
|
||||||
|
andAbility = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolve()
|
||||||
|
{
|
||||||
|
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||||
|
if (card)
|
||||||
|
{
|
||||||
|
card->exerted = true;
|
||||||
|
WEvent * e = NEW WEventCardExerted(card);
|
||||||
|
game->receiveEvent(e);
|
||||||
|
if(andAbility)
|
||||||
|
{
|
||||||
|
MTGAbility * andAbilityClone = andAbility->clone();
|
||||||
|
andAbilityClone->target = card;
|
||||||
|
if(andAbility->oneShot)
|
||||||
|
{
|
||||||
|
andAbilityClone->resolve();
|
||||||
|
SAFE_DELETE(andAbilityClone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
andAbilityClone->addToGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const string getMenuText()
|
||||||
|
{
|
||||||
|
return "Exert";
|
||||||
|
}
|
||||||
|
virtual ostream& toString(ostream& out) const
|
||||||
|
{
|
||||||
|
out << "AAExert ::: (";
|
||||||
|
return InstantAbility::toString(out) << ")";
|
||||||
|
}
|
||||||
|
AExert * clone() const
|
||||||
|
{
|
||||||
|
return NEW AExert(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
//------------------
|
//------------------
|
||||||
//trigger regen
|
//trigger regen
|
||||||
class ATriggerRegen: public InstantAbility
|
class ATriggerRegen: public InstantAbility
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ public:
|
|||||||
bool blinked;
|
bool blinked;
|
||||||
bool isExtraCostTarget;
|
bool isExtraCostTarget;
|
||||||
bool morphed;
|
bool morphed;
|
||||||
|
bool exerted;
|
||||||
bool turningOver;
|
bool turningOver;
|
||||||
bool isMorphed;
|
bool isMorphed;
|
||||||
bool isFlipped;
|
bool isFlipped;
|
||||||
|
|||||||
@@ -205,6 +205,12 @@ struct WEventCardCycle : public WEventCardUpdate {
|
|||||||
virtual Targetable * getTarget(int target);
|
virtual Targetable * getTarget(int target);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//event when card is exerted.
|
||||||
|
struct WEventCardExerted : public WEventCardUpdate {
|
||||||
|
WEventCardExerted(MTGCardInstance * card);
|
||||||
|
virtual Targetable * getTarget(int target);
|
||||||
|
};
|
||||||
|
|
||||||
//Event when a card's "defenser" status changes
|
//Event when a card's "defenser" status changes
|
||||||
//before : attacker that card was blocking previously
|
//before : attacker that card was blocking previously
|
||||||
//after: attacker that card is blocking now
|
//after: attacker that card is blocking now
|
||||||
|
|||||||
@@ -1040,7 +1040,7 @@ void ActionStack::Update(float dt)
|
|||||||
if (getCurrentTutorial() && (observer->players[0]->isHuman() || observer->players[1]->isHuman() ) )
|
if (getCurrentTutorial() && (observer->players[0]->isHuman() || observer->players[1]->isHuman() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (observer->mLayers->actionLayer()->menuObject || observer->LPWeffect)
|
if (observer->mLayers->actionLayer()->menuObject)// || observer->LPWeffect) //test fix for hang for both legendary with action/reveal
|
||||||
if(observer->players[0]->isHuman() || observer->players[1]->isHuman())
|
if(observer->players[0]->isHuman() || observer->players[1]->isHuman())
|
||||||
return;//dont do any of this if a menuobject exist.
|
return;//dont do any of this if a menuobject exist.
|
||||||
|
|
||||||
|
|||||||
@@ -6046,6 +6046,7 @@ ATransformer::ATransformer(GameObserver* observer, int id, MTGCardInstance * sou
|
|||||||
}
|
}
|
||||||
myCurrentTurn = 1000;
|
myCurrentTurn = 1000;
|
||||||
//this subkeyword adds a color without removing the existing colors.
|
//this subkeyword adds a color without removing the existing colors.
|
||||||
|
removemc = (sabilities.find("removemc") != string::npos);
|
||||||
addNewColors = (sabilities.find("newcolors") != string::npos);
|
addNewColors = (sabilities.find("newcolors") != string::npos);
|
||||||
remove = (stypes.find("removealltypes") != string::npos);
|
remove = (stypes.find("removealltypes") != string::npos);
|
||||||
removeCreatureSubtypes = (stypes.find("removecreaturesubtypes") != string::npos);
|
removeCreatureSubtypes = (stypes.find("removecreaturesubtypes") != string::npos);
|
||||||
@@ -6235,6 +6236,9 @@ for (it = types.begin(); it != types.end(); it++)
|
|||||||
_target->addbaseT(val->getValue());
|
_target->addbaseT(val->getValue());
|
||||||
delete val;
|
delete val;
|
||||||
}
|
}
|
||||||
|
//remove manacost
|
||||||
|
if(removemc)
|
||||||
|
_target->getManaCost()->resetCosts();
|
||||||
|
|
||||||
return MTGAbility::addToGame();
|
return MTGAbility::addToGame();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1070,6 +1070,10 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
|
|||||||
if (TargetChooser *tc = parseSimpleTC(s,"phasedin", card))
|
if (TargetChooser *tc = parseSimpleTC(s,"phasedin", card))
|
||||||
return NEW TrCardPhasesIn(observer, id, card, tc,once);
|
return NEW TrCardPhasesIn(observer, id, card, tc,once);
|
||||||
|
|
||||||
|
//Card Exerted
|
||||||
|
if (TargetChooser *tc = parseSimpleTC(s,"exerted", card))
|
||||||
|
return NEW TrCardExerted(observer, id, card, tc,once);
|
||||||
|
|
||||||
//CombatTrigger
|
//CombatTrigger
|
||||||
//Card card attacked and is blocked
|
//Card card attacked and is blocked
|
||||||
found = s.find("combat(");
|
found = s.find("combat(");
|
||||||
@@ -2928,7 +2932,20 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
((AManifest*)a)->withenchant = true;
|
((AManifest*)a)->withenchant = true;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
//exert
|
||||||
|
found = s.find("exert");
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
MTGAbility * a = NEW AExert(observer, id, card, target);
|
||||||
|
a->oneShot = 1;
|
||||||
|
if(storedAndAbility.size())
|
||||||
|
{
|
||||||
|
string stored = storedAndAbility;
|
||||||
|
storedAndAbility.clear();
|
||||||
|
((AExert*)a)->andAbility = parseMagicLine(stored, id, spell, card);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
//provoke
|
//provoke
|
||||||
found = s.find("provoke");
|
found = s.find("provoke");
|
||||||
if (found != string::npos)
|
if (found != string::npos)
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ void MTGCardInstance::initMTGCI()
|
|||||||
blinked = false;
|
blinked = false;
|
||||||
isExtraCostTarget = false;
|
isExtraCostTarget = false;
|
||||||
morphed = false;
|
morphed = false;
|
||||||
|
exerted = false;
|
||||||
turningOver = false;
|
turningOver = false;
|
||||||
isMorphed = false;
|
isMorphed = false;
|
||||||
MeldedFrom = "";
|
MeldedFrom = "";
|
||||||
|
|||||||
@@ -554,6 +554,13 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//remove exerted if changing controls
|
||||||
|
if((to == g->players[0]->game->battlefield && from == g->players[1]->game->battlefield)||
|
||||||
|
(to == g->players[1]->game->battlefield && from == g->players[0]->game->battlefield))
|
||||||
|
{
|
||||||
|
if(ret->exerted)
|
||||||
|
ret->exerted = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!asCopy)
|
if(!asCopy)
|
||||||
{
|
{
|
||||||
@@ -1125,6 +1132,17 @@ void MTGInPlay::untapAll()
|
|||||||
card->setUntapping();
|
card->setUntapping();
|
||||||
if (!card->basicAbilities[(int)Constants::DOESNOTUNTAP] && !card->basicAbilities[(int)Constants::SHACKLER])
|
if (!card->basicAbilities[(int)Constants::DOESNOTUNTAP] && !card->basicAbilities[(int)Constants::SHACKLER])
|
||||||
{
|
{
|
||||||
|
if(card->exerted)
|
||||||
|
{
|
||||||
|
card->exerted = false;
|
||||||
|
if (card->frozen >= 1)
|
||||||
|
{
|
||||||
|
card->frozen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
card->exerted = false;
|
||||||
if (card->frozen < 1)
|
if (card->frozen < 1)
|
||||||
{
|
{
|
||||||
card->attemptUntap();
|
card->attemptUntap();
|
||||||
@@ -1136,6 +1154,7 @@ void MTGInPlay::untapAll()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2)
|
MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2)
|
||||||
|
|||||||
@@ -121,6 +121,11 @@ WEventCardUpdate(card)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WEventCardExerted::WEventCardExerted(MTGCardInstance * card) :
|
||||||
|
WEventCardUpdate(card)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
WEventVampire::WEventVampire(MTGCardInstance * card,MTGCardInstance * source,MTGCardInstance * victem) :
|
WEventVampire::WEventVampire(MTGCardInstance * card,MTGCardInstance * source,MTGCardInstance * victem) :
|
||||||
WEventCardUpdate(card),source(source),victem(victem)
|
WEventCardUpdate(card),source(source),victem(victem)
|
||||||
{
|
{
|
||||||
@@ -377,6 +382,12 @@ Targetable * WEventCardCycle::getTarget(int target)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Targetable * WEventCardExerted::getTarget(int target)
|
||||||
|
{
|
||||||
|
if (target) return card;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Targetable * WEventCardAttackedNotBlocked::getTarget(int target)
|
Targetable * WEventCardAttackedNotBlocked::getTarget(int target)
|
||||||
{
|
{
|
||||||
if (target) return card;
|
if (target) return card;
|
||||||
|
|||||||
Reference in New Issue
Block a user