Transform Trigger, Turnlimit for TrCardAddedtoZone

Cleaned primitives, and fix SOI cards (remove workarounds) todo(recheck
BFZ and OGW)
This commit is contained in:
Anthony Calosa
2016-08-10 01:54:24 +08:00
parent ab49ea07e8
commit 151905c5f3
12 changed files with 481 additions and 336 deletions
@@ -96,6 +96,19 @@ auto=counter(1/1,X)
auto={3}:counter(1/1)
#Not all player can use ability
[/card]
#need doubler damage ability...
[card]
name=Goldnight Castigator
abilities=flying,haste
auto=@damaged(controller):damage:thatmuch controller
auto=@damaged(this):damage:thatmuch all(this)
text=Flying, haste -- If a source would deal damage to you, it deals double that damage to you instead. -- If a source would deal damage to Goldnight Castigator, it deals double that damage to Goldnight Castigator instead.
mana={2}{R}{R}
type=Creature
subtype=Angel
power=4
toughness=9
[/card]
[card]
name=Govern the Guildless
target=creature[-multicolor]
@@ -235,6 +248,18 @@ type=Sorcery
text=Draw cards equal to the number of cards in target opponent's hand. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)
[/card]
[card]
name=Relentless Dead
auto=@movedTo(this|graveyard) from(battlefield):transforms((,newability[{B}:moveto(myhand)])) ueot
auto=@movedTo(this|graveyard) from(battlefield):transforms((,newability[{X}:moveto(myhand) target(zombie[manacost=X]|mygraveyard)])) ueot
text=Menace (This creature can't be blocked except by two or more creatures.) -- When Relentless Dead dies, you may pay {B}. If you do, return it to its owner's hand. -- When Relentless Dead dies, you may pay {X}. If you do, return another target Zombie creature card with converted mana cost X from your graveyard to the battlefield.
mana={B}{B}
abilities=menace
type=Creature
subtype=Zombie
power=2
toughness=2
[/card]
[card]
name=Sacellum Godspeaker
auto={T}:foreach(creaure[power>4]|myhand) add{G}
text={T}: Reveal any number of creature cards with power 5 or greater from your hand. Add {G} to your mana pool for each card revealed this way.
File diff suppressed because it is too large Load Diff
+51 -14
View File
@@ -903,19 +903,29 @@ private:
}
else if (s == "gravecardtypes")//Tarmogoyf
{
for (int i = 0; i < 2; i++)
intValue = 0;
int pc = 0, tc = 0, sc = 0, lc = 0, ic = 0, ec = 0, cc = 0, ac = 0;
for (int j = 0; j < 2; j++)
{
MTGGameZone * checkZone = card->getObserver()->players[i]->game->graveyard;
intValue =
cardHasTypeinZone("planeswalker",checkZone) +
cardHasTypeinZone("tribal",checkZone) +
cardHasTypeinZone("sorcery",checkZone) +
cardHasTypeinZone("land",checkZone) +
cardHasTypeinZone("instant",checkZone) +
cardHasTypeinZone("enchantment",checkZone) +
cardHasTypeinZone("creature",checkZone) +
cardHasTypeinZone("artifact",checkZone);
MTGGameZone * checkZone = card->getObserver()->players[j]->game->graveyard;
if(cardHasTypeinZone("planeswalker",checkZone))
pc = 1;
if(cardHasTypeinZone("tribal",checkZone))
tc = 1;
if(cardHasTypeinZone("sorcery",checkZone))
sc = 1;
if(cardHasTypeinZone("land",checkZone))
lc = 1;
if(cardHasTypeinZone("instant",checkZone))
ic = 1;
if(cardHasTypeinZone("enchantment",checkZone))
ec = 1;
if(cardHasTypeinZone("creature",checkZone))
cc = 1;
if(cardHasTypeinZone("artifact",checkZone))
ac = 1;
}
intValue = pc+tc+sc+lc+ic+ec+cc+ac;
}
else if (s == "powertotalinplay")//Count Total Power of Creatures you control... Formidable
{
@@ -1133,10 +1143,13 @@ public:
TargetChooser * toTcCard, *fromTcCard;
bool sourceUntapped;
bool isSuspended;
bool limitOnceATurn;
int triggeredTurn;
TrCardAddedToZone(GameObserver* observer, int id, MTGCardInstance * source, TargetZoneChooser * toTcZone, TargetChooser * toTcCard,
TargetZoneChooser * fromTcZone = NULL, TargetChooser * fromTcCard = NULL,bool once = false,bool sourceUntapped = false,bool isSuspended = false) :
Trigger(observer, id, source, once), toTcZone(toTcZone), fromTcZone(fromTcZone), toTcCard(toTcCard), fromTcCard(fromTcCard),sourceUntapped(sourceUntapped),isSuspended(isSuspended)
TargetZoneChooser * fromTcZone = NULL, TargetChooser * fromTcCard = NULL,bool once = false,bool sourceUntapped = false,bool isSuspended = false, bool limitOnceATurn = false) :
Trigger(observer, id, source, once), toTcZone(toTcZone), fromTcZone(fromTcZone), toTcCard(toTcCard), fromTcCard(fromTcCard),sourceUntapped(sourceUntapped),isSuspended(isSuspended),limitOnceATurn(limitOnceATurn)
{
triggeredTurn = -1;
};
@@ -1146,6 +1159,8 @@ public:
if (!e) return 0;
if(sourceUntapped && source->isTapped() == 1)
return 0;
if (limitOnceATurn && triggeredTurn == game->turn)
return 0;
if(isSuspended && !source->suspended)
return 0;
if (!toTcZone->targetsZone(e->to)) return 0;
@@ -1160,7 +1175,7 @@ public:
{
return 0;
}
triggeredTurn = game->turn;
return 1;
}
@@ -1230,6 +1245,28 @@ public:
}
};
class TrCardTransformed: public Trigger
{
public:
TrCardTransformed(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false) :
Trigger(observer, id, source, once, tc)
{
}
int triggerOnEventImpl(WEvent * event)
{
WEventCardTransforms * e = dynamic_cast<WEventCardTransforms *> (event);
if (!e) return 0;
if (!tc->canTarget(e->card)) return 0;
return 1;
}
TrCardTransformed * clone() const
{
return NEW TrCardTransformed(*this);
}
};
class TrCombatTrigger: public Trigger
{
public:
+2 -1
View File
@@ -257,7 +257,8 @@ class Constants
FLYERSONLY = 135,//can attack only if it has flying
TEMPFLASHBACK = 136,
NOLEGENDRULE =137,
NB_BASIC_ABILITIES = 138,
CANTTRANSFORM =138,
NB_BASIC_ABILITIES = 139,
RARITY_S = 'S', //Special Rarity
RARITY_M = 'M', //Mythics
+1
View File
@@ -101,6 +101,7 @@ public:
ManaCost(const ManaCost& manaCost);
ManaCost& operator= (const ManaCost& manaCost);
void copy(ManaCost * _manaCost);
void changeCostTo(ManaCost * _manaCost);
int isNull();
int getConvertedCost();
string toString();
+15 -7
View File
@@ -1653,6 +1653,11 @@ AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, M
if (target)
{
MTGCardInstance * _target = (MTGCardInstance *) target;
if(_target->isFlipped && _target->hasType(Subtypes::TYPE_PLANESWALKER))//is flipping pw
{
this->forceDestroy = 1;
return 0;
}
AbilityFactory af(game);
if(counterstring.size())
{
@@ -3223,7 +3228,7 @@ int AAFlip::resolve()
MTGCardInstance * _target = (MTGCardInstance *) target;
if (_target)
{
if((_target->isACopier||_target->isToken) && !isflipcard && !forcedcopy)
if((_target->isACopier||_target->isToken||_target->has(Constants::CANTTRANSFORM)) && !isflipcard && !forcedcopy)
{
game->removeObserver(this);
return 0;
@@ -3240,6 +3245,9 @@ int AAFlip::resolve()
MTGCard * fcard = MTGCollection()->getCardByName(flipStats);
if(!fcard) return 0;
MTGCardInstance * myFlip = NEW MTGCardInstance(fcard, _target->controller()->game);
MTGCardInstance * myParent = NULL;
if(_target->target)
myParent = _target->target;
_target->name = myFlip->name;
_target->setName(myFlip->name);
if(!isflipcard)//transform card
@@ -3252,12 +3260,7 @@ int AAFlip::resolve()
_target->types = myFlip->types;
_target->text = myFlip->text;
_target->formattedText = myFlip->formattedText;
//_target->basicAbilities = myFlip->basicAbilities;
for(int k = 0; k < Constants::NB_BASIC_ABILITIES; k++)
{
if(myFlip->model->data->basicAbilities[k])
_target->basicAbilities[k] = myFlip->model->data->basicAbilities[k];
}
_target->basicAbilities = myFlip->model->data->basicAbilities;
_target->modbasicAbilities = myFlip->modbasicAbilities;
cdaDamage = _target->damageCount;
_target->copiedID = myFlip->getMTGId();//for copier
@@ -3333,6 +3336,11 @@ int AAFlip::resolve()
{//pbonus & tbonus are already computed except damage taken...
_target->life -= cdaDamage;
}
if(_target->hasSubtype(Subtypes::TYPE_EQUIPMENT))
{
if(myParent)
_target->target = myParent;
}
SAFE_DELETE(myFlip);
_target->mPropertiesChangedSinceLastUpdate = true;
if(!isflipcard)
+1 -1
View File
@@ -499,7 +499,7 @@ void CardGui::Render()
renderer->RenderQuad(fakemask.get(), actX, (actY-yy), actT, (26 * (actZ*zz) + 1) / 16, 38 * (actZ*zz) / 16);
}
}
if(tc && tc->source && tc->source->view && tc->source->view->actY >= 1.3 && card == tc->source)//paint the source green while infocus.
if(tc && tc->source && tc->source->view && tc->source->view->actZ >= 1.3 && card == tc->source)//paint the source green while infocus.
{
if(fakemask)
{
+14 -14
View File
@@ -1184,56 +1184,56 @@ void GameObserver::Affinity()
//kicker is an addon to normal cost, suspend is not casting. add cost as needed EXACTLY as seen below.
card->getManaCost()->resetCosts();
ManaCost *newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost()));
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost()));
card->getManaCost()->copy(newCost);
card->getManaCost()->changeCostTo(newCost);
SAFE_DELETE(newCost);
if (card->getManaCost()->getAlternative())
{
card->getManaCost()->getAlternative()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative()));
card->getManaCost()->getAlternative()->copy(newCost);
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative()));
card->getManaCost()->getAlternative()->changeCostTo(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getBestow())
{
card->getManaCost()->getBestow()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow()));
card->getManaCost()->getBestow()->copy(newCost);
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow()));
card->getManaCost()->getBestow()->changeCostTo(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getRetrace())
{
card->getManaCost()->getRetrace()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace()));
card->getManaCost()->getRetrace()->copy(newCost);
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace()));
card->getManaCost()->getRetrace()->changeCostTo(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getBuyback())
{
card->getManaCost()->getBuyback()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback()));
card->getManaCost()->getBuyback()->copy(newCost);
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback()));
card->getManaCost()->getBuyback()->changeCostTo(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getFlashback())
{
card->getManaCost()->getFlashback()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback()));
card->getManaCost()->getFlashback()->copy(newCost);
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback()));
card->getManaCost()->getFlashback()->changeCostTo(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getMorph())
{
card->getManaCost()->getMorph()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph()));
card->getManaCost()->getMorph()->copy(newCost);
newCost->changeCostTo(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph()));
card->getManaCost()->getMorph()->changeCostTo(newCost);
SAFE_DELETE(newCost);
}
+23 -1
View File
@@ -371,6 +371,24 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe
return 0;
}
check = restriction[i].find("notdelirum");
if (check != string::npos)
{
Player * checkCurrent = card->controller();
MTGGameZone * grave = checkCurrent->game->graveyard;
int checkTypesAmount = 0;
if(grave->hasType("creature")) checkTypesAmount++;
if (grave->hasType("enchantment")) checkTypesAmount++;
if (grave->hasType("sorcery")) checkTypesAmount++;
if (grave->hasType("instant")) checkTypesAmount++;
if (grave->hasType("land")) checkTypesAmount++;
if (grave->hasType("artifact")) checkTypesAmount++;
if (grave->hasType("planeswalker")) checkTypesAmount++;
if (checkTypesAmount > 3)
return 0;
}
check = restriction[i].find("miracle");
if(check != string::npos)
{
@@ -824,7 +842,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
fromTc->targetter = NULL; //avoid protection from
}
TriggeredAbility * mover = NEW TrCardAddedToZone(observer, id, card, (TargetZoneChooser *) toTc,
toTcCard, (TargetZoneChooser *) fromTc, fromTcCard, once, sourceUntapped, isSuspended);
toTcCard, (TargetZoneChooser *) fromTc, fromTcCard, once, sourceUntapped, isSuspended, limitOnceATurn);
if(neverRemove)
{
mover->forcedAlive = 1;
@@ -845,6 +863,10 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell
if (TargetChooser *tc = parseSimpleTC(s,"tappedformana", card))
return NEW TrCardTappedformana(observer, id, card, tc, true,once);
//Card Transforms
if (TargetChooser *tc = parseSimpleTC(s,"transformed", card))
return NEW TrCardTransformed(observer, id, card, tc,once);
//CombatTrigger
//Card card attacked and is blocked
found = s.find("combat(");
+2 -6
View File
@@ -98,12 +98,7 @@ void MTGCardInstance::copy(MTGCardInstance * card)
{
MTGCard * source = card->model;
CardPrimitive * data = source->data;
for(int k = 0; k < Constants::NB_BASIC_ABILITIES; k++)
{
if(card->model->data->basicAbilities[k])
basicAbilities[k] = card->model->data->basicAbilities[k];
}
basicAbilities = card->model->data->basicAbilities;
modbasicAbilities = card->modbasicAbilities;
for (size_t i = 0; i < data->types.size(); i++)
{
@@ -149,6 +144,7 @@ void MTGCardInstance::copy(MTGCardInstance * card)
backupTargets = this->backupTargets;
storedCard = oldStored;
miracle = false;
mPropertiesChangedSinceLastUpdate = true;
}
MTGCardInstance::~MTGCardInstance()
+2 -1
View File
@@ -168,7 +168,8 @@ const char* Constants::MTGBasicAbilities[] = {
"shackler",
"flyersonly",
"tempflashback",
"legendruleremove"
"legendruleremove",
"canttransform"
};
map<string,int> Constants::MTGBasicAbilitiesMap;
+24
View File
@@ -666,6 +666,30 @@ void ManaCost::copy(ManaCost * _manaCost)
xColor = _manaCost->xColor;
}
void ManaCost::changeCostTo(ManaCost * _manaCost)
{
if (!_manaCost)
return;
cost.erase(cost.begin() ,cost.end());
for (int i = 0; i <= Constants::NB_Colors; i++)
{
cost.push_back(_manaCost->getCost(i));
}
hybrids = _manaCost->hybrids;
SAFE_DELETE(extraCosts);
if (_manaCost->extraCosts)
{
extraCosts = _manaCost->extraCosts->clone();
}
xColor = _manaCost->xColor;
}
int ManaCost::getCost(int color)
{
if (cost.size() <= (size_t)color)