@@ -4456,6 +4456,29 @@ public:
|
||||
const string getMenuText();
|
||||
AAMorph * clone() const;
|
||||
};
|
||||
|
||||
class AAMeldFrom : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
string _MeldedName;
|
||||
AAMeldFrom(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, string MeldedName = "");
|
||||
int resolve();
|
||||
|
||||
const string getMenuText();
|
||||
AAMeldFrom * clone() const;
|
||||
};
|
||||
/* meld*/
|
||||
class AAMeld : public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
string _MeldedName;
|
||||
AAMeld(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target,string MeldedName = "");
|
||||
int resolve();
|
||||
|
||||
const string getMenuText();
|
||||
AAMeld * clone() const;
|
||||
};
|
||||
|
||||
/* flip*/
|
||||
class AAFlip: public InstantAbility
|
||||
{
|
||||
|
||||
@@ -299,7 +299,8 @@ public:
|
||||
class Offering : public ExtraCost
|
||||
{
|
||||
public:
|
||||
Offering(TargetChooser *_tc = NULL);
|
||||
bool emerge;
|
||||
Offering(TargetChooser *_tc = NULL, bool emerge = false);
|
||||
virtual int canPay();
|
||||
virtual int isPaymentSet();
|
||||
virtual int doPay();
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
bool turningOver;
|
||||
bool isMorphed;
|
||||
bool isFlipped;
|
||||
string MeldedFrom;
|
||||
bool isPhased;
|
||||
bool isCascaded;
|
||||
int phasedTurn;
|
||||
|
||||
@@ -3069,6 +3069,68 @@ AAMorph * AAMorph::clone() const
|
||||
a->forceDestroy = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
//Melded From Setter
|
||||
AAMeldFrom::AAMeldFrom(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, string MeldedName) :
|
||||
ActivatedAbility(observer, id, card, 0), _MeldedName(MeldedName)
|
||||
{
|
||||
target = _target;
|
||||
// aType = MTGAbility::Melder;
|
||||
}
|
||||
|
||||
int AAMeldFrom::resolve()
|
||||
{
|
||||
source->MeldedFrom = _MeldedName;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const string AAMeldFrom::getMenuText()
|
||||
{
|
||||
return "Melded From";
|
||||
}
|
||||
|
||||
AAMeldFrom * AAMeldFrom::clone() const
|
||||
{
|
||||
return NEW AAMeldFrom(*this);
|
||||
}
|
||||
|
||||
//Melding
|
||||
AAMeld::AAMeld(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, string MeldedName) :
|
||||
ActivatedAbility(observer, id, card, 0), _MeldedName(MeldedName)
|
||||
{
|
||||
target = _target;
|
||||
// aType = MTGAbility::Melder;
|
||||
}
|
||||
|
||||
int AAMeld::resolve()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||
if (_target && _target->controller() == source->controller() && _target->owner == source->owner && !_target->isToken && !source->isToken)
|
||||
{
|
||||
source->controller()->game->putInExile(source);
|
||||
_target->controller()->game->putInExile(_target);
|
||||
source->next->controller()->game->putInZone(source->next, source->next->currentZone, source->next->controller()->game->temp);
|
||||
_target->next->controller()->game->putInZone(_target->next, _target->next->currentZone, _target->next->controller()->game->temp);
|
||||
MTGAbility *a = NEW AACastCard(game, game->mLayers->actionLayer()->getMaxId(), source, source, false, false, false, _MeldedName, _MeldedName, false, true);
|
||||
a->oneShot = false;
|
||||
a->canBeInterrupted = false;
|
||||
a->addToGame();
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const string AAMeld::getMenuText()
|
||||
{
|
||||
return "Meld";
|
||||
}
|
||||
|
||||
AAMeld * AAMeld::clone() const
|
||||
{
|
||||
return NEW AAMeld(*this);
|
||||
}
|
||||
|
||||
// flip a card
|
||||
AAFlip::AAFlip(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target,string flipStats) :
|
||||
InstantAbility(observer, id, card, _target),flipStats(flipStats)
|
||||
@@ -6900,21 +6962,62 @@ void ABlink::resolveBlink()
|
||||
// this->forceDestroy = 1;
|
||||
// return;
|
||||
//}
|
||||
if (_target->MeldedFrom.size())
|
||||
{
|
||||
//cards with meld are handled very different from normal cards with this specific ability giving us about 3 of the
|
||||
//core rules for the ability. below we split the card up, and we send them to garbage, move the original to temp where
|
||||
//it is later moved to garbage by garbage collection.
|
||||
//then we build 2 seperate blinks with the 2 parts as the targets.
|
||||
vector<string> names = split(_target->MeldedFrom, '|');
|
||||
MTGCard * cardone = MTGCollection()->getCardByName(names[0]);
|
||||
MTGCardInstance * cardOne = NEW MTGCardInstance(cardone, _target->owner->game);
|
||||
MTGCard * cardtwo = MTGCollection()->getCardByName(names[1]);
|
||||
MTGCardInstance * cardTwo = NEW MTGCardInstance(cardtwo, _target->owner->game);
|
||||
_target->controller()->game->putInZone(_target, _target->currentZone,
|
||||
_target->owner->game->temp);
|
||||
_target->controller()->game->garbage->addCard(cardOne);
|
||||
_target->controller()->game->garbage->addCard(cardTwo);
|
||||
MTGAbility * a = NEW ABlinkGeneric(game, game->mLayers->actionLayer()->getMaxId(), source, cardOne, blinkueot, blinkForSource, blinkhand, stored);
|
||||
a->target = (Targetable*)cardOne;
|
||||
a->oneShot = false;
|
||||
a->canBeInterrupted = false;
|
||||
a->resolve();
|
||||
SAFE_DELETE(a);
|
||||
|
||||
|
||||
MTGAbility * a2 = NEW ABlinkGeneric(game, game->mLayers->actionLayer()->getMaxId(), source, cardTwo, blinkueot, blinkForSource, blinkhand, stored);
|
||||
a2->target = (Targetable*)cardTwo;
|
||||
a2->oneShot = false;
|
||||
a2->canBeInterrupted = false;
|
||||
a2->resolve();
|
||||
SAFE_DELETE(a2);
|
||||
this->forceDestroy = 1;
|
||||
this->removeFromGame();
|
||||
return;
|
||||
}
|
||||
else
|
||||
_target->controller()->game->putInZone(_target, _target->currentZone,
|
||||
_target->owner->game->exile);
|
||||
if (_target->MeldedFrom.size() || !_target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(_target->isToken)
|
||||
{
|
||||
//if our target is a token, we're done as soon as its sent to exile.
|
||||
this->forceDestroy = 1;
|
||||
return;
|
||||
}
|
||||
_target = _target->next;
|
||||
|
||||
if (_target && _target->next)
|
||||
_target = _target->next;
|
||||
_target->blinked = true;
|
||||
Blinked = _target;
|
||||
if(!blinkueot && !blinkForSource)
|
||||
if (!blinkueot && !blinkForSource)
|
||||
{
|
||||
returnCardIntoPlay(_target);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +154,11 @@ void CardGui::Render()
|
||||
quad = AlternateThumbQuad(card);
|
||||
|
||||
float cardScale = quad ? 40 / quad->mHeight : 1;
|
||||
//I want the below for melded cards but I dont know how to adjust everything else
|
||||
//to look neat and clean. leaving this here incase someone else wants to pretty up the p/t box
|
||||
//and line up the position.
|
||||
/* if (card->MeldedFrom.size())
|
||||
cardScale = cardScale + (10 / quad->mHeight);*/
|
||||
float scale = actZ * cardScale;
|
||||
|
||||
JQuadPtr shadow;
|
||||
|
||||
@@ -1128,8 +1128,8 @@ Offering * Offering::clone() const
|
||||
return ec;
|
||||
}
|
||||
|
||||
Offering::Offering(TargetChooser *_tc) :
|
||||
ExtraCost("Select creature to offer", _tc)
|
||||
Offering::Offering(TargetChooser *_tc,bool emerge) :
|
||||
ExtraCost("Select creature to offer", _tc), emerge(emerge)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1137,28 +1137,77 @@ int Offering::canPay()
|
||||
{
|
||||
if (target && target->has(Constants::CANTBESACRIFIED))
|
||||
return 0;
|
||||
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
if (emerge)
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
target = NULL;
|
||||
return 0;
|
||||
if (target)
|
||||
{
|
||||
ManaCost * reduced = NEW ManaCost(source->getManaCost());
|
||||
reduced->remove(Constants::MTG_COLOR_ARTIFACT, target->getManaCost()->getConvertedCost());
|
||||
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(reduced)))
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
target = NULL;
|
||||
SAFE_DELETE(reduced);
|
||||
return 0;
|
||||
}
|
||||
if (target && source->controller()->getManaPool()->canAfford(reduced))
|
||||
{
|
||||
SAFE_DELETE(reduced);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
target = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
return 1;
|
||||
}
|
||||
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Offering::isPaymentSet()
|
||||
{
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
if (emerge)
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
target = NULL;
|
||||
return 0;
|
||||
if (target)
|
||||
{
|
||||
ManaCost * reduced = NEW ManaCost(source->getManaCost());
|
||||
reduced->remove(Constants::MTG_COLOR_ARTIFACT, target->getManaCost()->getConvertedCost());
|
||||
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(reduced)))
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
target = NULL;
|
||||
SAFE_DELETE(reduced);
|
||||
return 0;
|
||||
}
|
||||
if (target && source->controller()->getManaPool()->canAfford(reduced))
|
||||
{
|
||||
SAFE_DELETE(reduced);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
target = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
return 1;
|
||||
}
|
||||
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1166,6 +1215,14 @@ int Offering::doPay()
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
if (emerge)
|
||||
{
|
||||
ManaCost * reduced = NEW ManaCost(source->getManaCost());
|
||||
reduced->remove(Constants::MTG_COLOR_ARTIFACT, target->getManaCost()->getConvertedCost());
|
||||
target->controller()->getManaPool()->pay(reduced);
|
||||
SAFE_DELETE(reduced);
|
||||
}
|
||||
else
|
||||
target->controller()->getManaPool()->pay(source->getManaCost()->Diff(target->getManaCost()));
|
||||
MTGCardInstance * beforeCard = target;
|
||||
source->storedCard = target->createSnapShot();
|
||||
|
||||
@@ -3296,6 +3296,33 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return a;
|
||||
}
|
||||
|
||||
//meld helper class
|
||||
vector<string> splitMeldFrom = parseBetween(s, "meldfrom(", ")", true);
|
||||
if (splitMeldFrom.size())
|
||||
{
|
||||
string splitMeldNames = "";
|
||||
if (splitMeldFrom[1].size())
|
||||
{
|
||||
splitMeldNames = splitMeldFrom[1];
|
||||
}
|
||||
MTGAbility * a = NEW AAMeldFrom(observer, id, card, target, splitMeldNames);
|
||||
a->oneShot = true;
|
||||
return a;
|
||||
}
|
||||
|
||||
//meld
|
||||
vector<string> splitMeld = parseBetween(s, "meld(", ")", true);
|
||||
if (splitMeld.size())
|
||||
{
|
||||
string splitMeldName = "";
|
||||
if (splitMeld[1].size())
|
||||
{
|
||||
splitMeldName = splitMeld[1];
|
||||
}
|
||||
MTGAbility * a = NEW AAMeld(observer, id, card, target, splitMeldName);
|
||||
a->oneShot = true;
|
||||
return a;
|
||||
}
|
||||
//flip
|
||||
vector<string> splitFlipStat = parseBetween(s, "flip(", ")", true);
|
||||
if(splitFlipStat.size())
|
||||
|
||||
@@ -195,6 +195,7 @@ void MTGCardInstance::initMTGCI()
|
||||
morphed = false;
|
||||
turningOver = false;
|
||||
isMorphed = false;
|
||||
MeldedFrom = "";
|
||||
isFlipped = false;
|
||||
isPhased = false;
|
||||
isCascaded = false;
|
||||
|
||||
@@ -431,6 +431,34 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
|
||||
return ret;//don't send event
|
||||
}
|
||||
}
|
||||
//before adding card to zone, if its Melded, we break it apart
|
||||
if (from == g->players[0]->game->battlefield || from == g->players[1]->game->battlefield)
|
||||
{
|
||||
if(to != g->players[0]->game->battlefield || to != g->players[1]->game->battlefield)
|
||||
if (copy->previous && copy->previous->MeldedFrom.size())
|
||||
{
|
||||
vector<string> names = split(copy->previous->MeldedFrom, '|');
|
||||
MTGCard * cardone = MTGCollection()->getCardByName(names[0]);
|
||||
MTGCardInstance * cardOne = NEW MTGCardInstance(cardone, copy->owner->game);
|
||||
to->addCard(cardOne);
|
||||
WEvent * e = NEW WEventZoneChange(cardOne, from, to);
|
||||
g->receiveEvent(e);
|
||||
MTGCard * cardtwo = MTGCollection()->getCardByName(names[1]);
|
||||
MTGCardInstance * cardTwo = NEW MTGCardInstance(cardtwo, copy->owner->game);
|
||||
to->addCard(cardTwo);
|
||||
WEvent * e2 = NEW WEventZoneChange(cardTwo, from, to);
|
||||
g->receiveEvent(e2);
|
||||
|
||||
if(from == g->players[0]->game->battlefield)
|
||||
g->players[0]->game->temp->addCard(copy);
|
||||
if (from == g->players[1]->game->battlefield)
|
||||
g->players[1]->game->temp->addCard(copy);
|
||||
WEvent * e3 = NEW WEventZoneChange(copy, from, to);
|
||||
g->receiveEvent(e3);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
to->addCard(copy);
|
||||
//The "Temp" zone are purely for code purposes, and we don't want the abilities engine to
|
||||
//Trigger when cards move in this zone
|
||||
|
||||
@@ -153,6 +153,13 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
if (value == "emerge")
|
||||
{
|
||||
if (!tc)
|
||||
tc = tcf.createTargetChooser("creature|mybattlefield", c);
|
||||
manaCost->addExtraCost(NEW Offering(tc,true));
|
||||
}
|
||||
else
|
||||
//Exile
|
||||
manaCost->addExtraCost(NEW ExileTargetCost(tc));
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user