Merge pull request #632 from kevlahnota/master

Added bypass for notatarget(it should bypass protection and shroud), extend castcard to support putinplay for aura(since aura must have target chooser when put into play by other means), added state based action for aura with invalid targets(ex. local enchantments that enchant creature, then the creature it enchants loses creature types like man lands ... mutavault.)
This commit is contained in:
Anthony Calosa
2015-09-24 19:55:13 +08:00
8 changed files with 65 additions and 18 deletions
+5 -5
View File
@@ -30262,7 +30262,7 @@ type=Instant
[/card]
[card]
name=Enduring Ideal
auto=moveto(mybattlefield) notatarget(enchantment|mylibrary) and!( transforms((,newability[if cantargetcard(aura) then retarget target(creature|mybattlefield)])) )!
auto=notatarget(enchantment|mylibrary) castcard(putinplay)
auto=if compare(epicactivated)~lessthan~1 then emblem transforms((,newability[epic controller],newability[@each my upkeep:castcard(copied named!:Enduring Ideal:!)])) forever dontremove
text=Search your library for an enchantment card and put it onto the battlefield. Then shuffle your library. -- Epic (For the rest of the game, you can't cast spells. At the beginning of each of your upkeeps, copy this spell except for its epic ability.)
mana={5}{W}{W}
@@ -39276,7 +39276,7 @@ toughness=2
[card]
name=Glimmerpoint Stag
abilities=vigilance
auto=(blink)ueot target(*)
auto=(blink)ueot target(other *)
text=Vigilance -- When Glimmerpoint Stag enters the battlefield, exile another target permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step.
mana={2}{W}{W}
type=Creature
@@ -70865,7 +70865,7 @@ type=Artifact
[card]
name=Parallax Nexus
auto=fading:5
auto={C(0/0,-1,Fade)}:target(opponent) ability$!name(exile card from hand) (blink)forsrc target(*|myhand)!$ targetedplayer
auto={C(0/0,-1,Fade)}:target(opponent) ability$!name(exile card from hand) hand(blink)forsrc target(*|myhand)!$ targetedplayer
text=Fading 5 (This enchantment enters the battlefield with five fade counters on it. At the beginning of your upkeep, remove a fade counter from it. If you can't, sacrifice it.) -- Remove a fade counter from Parallax Nexus: Target opponent exiles a card from his or her hand. Activate this ability only any time you could cast a sorcery. -- When Parallax Nexus leaves the battlefield, each player returns to his or her hand all cards he or she owns exiled with Parallax Nexus.
mana={2}{B}
type=Enchantment
@@ -88918,7 +88918,7 @@ type=Sorcery
[card]
name=Silent Sentinel
abilities=flying
auto=@combat(attacking) source(this):may moveto(mybattlefield) target(enchantment|mygraveyard) and!( transforms((,newability[if cantargetcard(aura) then retarget target(creature|mybattlefield)])) )!
auto=@combat(attacking) source(this):may target(enchantment|mygraveyard) castcard(putinplay)
text=Flying -- Whenever Silent Sentinel attacks, you may return target enchantment card from your graveyard to the battlefield.
mana={5}{W}{W}
type=Creature
@@ -95343,7 +95343,7 @@ type=Instant
[/card]
[card]
name=Starfield of Nyx
auto=@each my upkeep:may moveto(mybattlefield) target(enchantment|mygraveyard) and!( transforms((,newability[if cantargetcard(aura) then retarget target(creature|mybattlefield)])) )!
auto=@each my upkeep:may target(enchantment|mygraveyard) castcard(putinplay)
auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=1]) transforms((,newability[becomes(Creature)],setpower=1,settoughness=1)) >4
auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=2]) transforms((,newability[becomes(Creature)],setpower=2,settoughness=2)) >4
auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=3]) transforms((,newability[becomes(Creature)],setpower=3,settoughness=3)) >4
+2 -1
View File
@@ -6025,7 +6025,8 @@ public:
string nameThis;
MTGCardInstance * theNamedCard;
bool noEvent;
AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent);
bool putinplay;
AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay);
int testDestroy(){return 0;};
void Update(float dt);
+1
View File
@@ -240,6 +240,7 @@ public:
int swapT;
bool isSwitchedPT;
bool isACopier;
bool bypassTC;
void eventattacked();
void eventattackedAlone();
+28 -4
View File
@@ -5507,8 +5507,8 @@ AEquip * AEquip::clone() const
}
// casting a card for free, or casting a copy of a card.
AACastCard::AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool _restricted,bool _copied,bool asNormal,string _namedCard,string _name,bool _noEvent) :
MTGAbility(observer, _id, _source),restricted(_restricted),asCopy(_copied),normal(asNormal),cardNamed(_namedCard),nameThis(_name),noEvent(_noEvent)
AACastCard::AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool _restricted,bool _copied,bool asNormal,string _namedCard,string _name,bool _noEvent,bool putinplay) :
MTGAbility(observer, _id, _source),restricted(_restricted),asCopy(_copied),normal(asNormal),cardNamed(_namedCard),nameThis(_name),noEvent(_noEvent),putinplay(putinplay)
{
target = _target;
andAbility = NULL;
@@ -5526,6 +5526,22 @@ void AACastCard::Update(float dt)
{
theNamedCard = makeCard();
}
if(putinplay)
{
MTGCardInstance * toCheck = (MTGCardInstance*)target;
toCheck->target = NULL;
toCheck->playerTarget = NULL;
toCheck->bypassTC = true;
TargetChooserFactory tcf(game);
TargetChooser * atc = tcf.createTargetChooser(toCheck->spellTargetType,toCheck);
if (toCheck->hasType(Subtypes::TYPE_AURA) && !atc->validTargetsExist())
{
processed = true;
this->forceDestroy = 1;
return ;
}
SAFE_DELETE(atc);
}
if (restricted)
{
MTGCardInstance * toCheck = (MTGCardInstance*)target;
@@ -5633,12 +5649,18 @@ int AACastCard::resolveSpell()
MTGCardInstance * copy = NULL;
if (normal ||(!_target->hasType(Subtypes::TYPE_INSTANT) && !_target->hasType(Subtypes::TYPE_SORCERY)))
{
copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack,noEvent);
if (putinplay && (_target->hasType(Subtypes::TYPE_ARTIFACT)||_target->hasType(Subtypes::TYPE_CREATURE)||_target->hasType(Subtypes::TYPE_ENCHANTMENT)||_target->hasType(Subtypes::TYPE_PLANESWALKER)))
copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->battlefield,noEvent);
else
copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->stack,noEvent);
copy->changeController(source->controller(),true);
}
else
{
copy =_target->controller()->game->putInZone(_target, _target->currentZone, _target->controller()->game->stack,noEvent);
if (putinplay && (_target->hasType(Subtypes::TYPE_ARTIFACT)||_target->hasType(Subtypes::TYPE_CREATURE)||_target->hasType(Subtypes::TYPE_ENCHANTMENT)||_target->hasType(Subtypes::TYPE_PLANESWALKER)))
copy =_target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->battlefield,noEvent);
else
copy =_target->controller()->game->putInZone(_target, _target->currentZone, _target->controller()->game->stack,noEvent);
copy->changeController(source->controller(),true);
}
if (game->targetChooser)
@@ -5693,6 +5715,8 @@ const string AACastCard::getMenuText()
{
if(nameThis.size())
return nameThis.c_str();
if(putinplay)
return "Put Into Play";
return "Cast For Free";
}
+14
View File
@@ -617,6 +617,7 @@ void GameObserver::gameStateBasedEffects()
card->myPair->myPair = NULL;
card->myPair = NULL;
}
card->bypassTC = false; //turn off bypass
////////////////////////////////////////////////////
//Unattach Equipments that dont have valid targets//
////////////////////////////////////////////////////
@@ -642,6 +643,19 @@ void GameObserver::gameStateBasedEffects()
{
if(card->target && !isInPlay(card->target))
players[i]->game->putInGraveyard(card);
if(card->target && isInPlay(card->target))
{
if(card->spellTargetType.find("creature") != string::npos && !card->target->hasType("creature"))
players[i]->game->putInGraveyard(card);
if(card->spellTargetType.find("artifact") != string::npos && !card->target->hasType("artifact"))
players[i]->game->putInGraveyard(card);
if(card->spellTargetType.find("enchantment") != string::npos && !card->target->hasType("enchantment"))
players[i]->game->putInGraveyard(card);
if(card->spellTargetType.find("land") != string::npos && !card->target->hasType("land"))
players[i]->game->putInGraveyard(card);
if(card->spellTargetType.find("planeswalker") != string::npos && !card->target->hasType("planeswalker"))
players[i]->game->putInGraveyard(card);
}
if(card->target && isInPlay(card->target) && (card->target)->protectedAgainst(card) && !card->has(Constants::AURAWARD))//protection from quality except aura cards like flickering ward
players[i]->game->putInGraveyard(card);
}
+7 -1
View File
@@ -1330,7 +1330,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
tcString = splitTarget[1];
if (!isTarget)
{
tc->targetter->bypassTC = true;
tc->targetter = NULL;
}
else
tc->targetter->bypassTC = false;
sWithoutTc = splitTarget[0];
sWithoutTc.append(splitTarget[2]);
}
@@ -2326,6 +2331,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
bool asCopy = splitCastCard[1].find("copied") != string::npos;
bool asNormal = splitCastCard[1].find("normal") != string::npos;
bool sendNoEvent = splitCastCard[1].find("noevent") != string::npos;
bool putinplay = splitCastCard[1].find("putinplay") != string::npos;
string nameCard = "";
if(splitCastCard[1].find("named!:") != string::npos)
{
@@ -2335,7 +2341,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
nameCard = splitCastName[1];
}
}
MTGAbility *a = NEW AACastCard(observer, id, card, target,withRestrictions,asCopy,asNormal,nameCard,newName,sendNoEvent);
MTGAbility *a = NEW AACastCard(observer, id, card, target,withRestrictions,asCopy,asNormal,nameCard,newName,sendNoEvent,putinplay);
a->oneShot = false;
if(splitCastCard[1].find("trigger[to]") != string::npos)
{
+1
View File
@@ -57,6 +57,7 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to
isCDA = false;
isSwitchedPT = false;
isACopier = false;
bypassTC = false;
}
MTGCardInstance * MTGCardInstance::createSnapShot()
+7 -7
View File
@@ -855,10 +855,10 @@ bool TargetChooser::canTarget(Targetable * target, bool withoutProtections)
if (source && targetter && card->isInPlay(observer) && !withoutProtections)
{
if (card->has(Constants::SHROUD)) return false;
if (card->protectedAgainst(targetter)) return false;
if (card->CantBeTargetby(targetter)) return false;
if ((targetter->controller() != card->controller()) && card->has(Constants::OPPONENTSHROUD)) return false;
if (card->has(Constants::SHROUD)) return targetter->bypassTC;
if (card->protectedAgainst(targetter)) return targetter->bypassTC;
if (card->CantBeTargetby(targetter)) return targetter->bypassTC;
if ((targetter->controller() != card->controller()) && card->has(Constants::OPPONENTSHROUD)) return targetter->bypassTC;
}
return true;
}
@@ -1337,13 +1337,13 @@ bool PlayerTargetChooser::canTarget(Targetable * target, bool)
if ((targetter->controller() != targetter->controller()->opponent())
&& (targetter->controller()->opponent()->game->inPlay->hasAbility(Constants::CONTROLLERSHROUD))
&& targetter->controller() != target)
return false;
return targetter->bypassTC;
if ((targetter->controller()->opponent()->game->inPlay->hasAbility(Constants::PLAYERSHROUD))
&& targetter->controller()->opponent() == target)
return false;
return targetter->bypassTC;
if ((targetter->controller()->game->inPlay->hasAbility(Constants::PLAYERSHROUD))
&& targetter->controller() == target)
return false;
return targetter->bypassTC;
}
Player * pTarget = dynamic_cast<Player *>(target);