Merge pull request #848 from kevlahnota/master

Fix SOI cards
This commit is contained in:
Anthony Calosa
2016-08-10 08:28:52 +08:00
committed by GitHub
13 changed files with 488 additions and 341 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:
+3 -1
View File
@@ -257,7 +257,9 @@ class Constants
FLYERSONLY = 135,//can attack only if it has flying
TEMPFLASHBACK = 136,
NOLEGENDRULE =137,
NB_BASIC_ABILITIES = 138,
CANTTRANSFORM =138,
ASFLASH =139,
NB_BASIC_ABILITIES = 140,
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()
+3 -1
View File
@@ -168,7 +168,9 @@ const char* Constants::MTGBasicAbilities[] = {
"shackler",
"flyersonly",
"tempflashback",
"legendruleremove"
"legendruleremove",
"canttransform",
"asflash"
};
map<string,int> Constants::MTGBasicAbilitiesMap;
+4 -4
View File
@@ -334,7 +334,7 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
else
return 0;
}
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed()))
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::ASFLASH) || (card->StackIsEmptyandSorcerySpeed()))
{
if(card->controller()->epic)
return 0;
@@ -559,7 +559,7 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
if(!card->getManaCost()->getKicker())
return 0;
if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed()))
if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::ASFLASH) || (card->StackIsEmptyandSorcerySpeed()))
{
if(card->controller()->epic)
return 0;
@@ -748,7 +748,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
else
return 0;
}
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::SPELLMASTERY) || card->has(Constants::OFFERING) || (card->StackIsEmptyandSorcerySpeed()))
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::ASFLASH) || card->has(Constants::SPELLMASTERY) || card->has(Constants::OFFERING) || (card->StackIsEmptyandSorcerySpeed()))
{
if(card->controller()->epic)
return 0;
@@ -1313,7 +1313,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
if(card->controller()->epic)//zoetic cavern... morph is casted for a cost...
return 0;
//note lands can morph too, this is different from other cost types.
if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed()))
if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::ASFLASH) || (card->StackIsEmptyandSorcerySpeed()))
{
if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY)
return 0;
+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)