added basic suspend.
syntax
suspend(number of time counter)={cost}
suspend(3)={g}
This commit is contained in:
@@ -224,10 +224,11 @@ public:
|
||||
TargetChooser * toTcCard, *fromTcCard;
|
||||
bool once;
|
||||
bool sourceUntapped;
|
||||
bool isSuspended;
|
||||
bool activeTrigger;
|
||||
TrCardAddedToZone(int id, MTGCardInstance * source, TargetZoneChooser * toTcZone, TargetChooser * toTcCard,
|
||||
TargetZoneChooser * fromTcZone = NULL, TargetChooser * fromTcCard = NULL,bool once = false,bool sourceUntapped = false) :
|
||||
TriggeredAbility(id, source), toTcZone(toTcZone), fromTcZone(fromTcZone), toTcCard(toTcCard), fromTcCard(fromTcCard),once(once),sourceUntapped(sourceUntapped)
|
||||
TargetZoneChooser * fromTcZone = NULL, TargetChooser * fromTcCard = NULL,bool once = false,bool sourceUntapped = false,bool isSuspended = false) :
|
||||
TriggeredAbility(id, source), toTcZone(toTcZone), fromTcZone(fromTcZone), toTcCard(toTcCard), fromTcCard(fromTcCard),once(once),sourceUntapped(sourceUntapped),isSuspended(isSuspended)
|
||||
{
|
||||
activeTrigger = true;
|
||||
}
|
||||
@@ -245,6 +246,8 @@ public:
|
||||
if (!e) return 0;
|
||||
if(sourceUntapped && source->isTapped() == 1)
|
||||
return 0;
|
||||
if(isSuspended && !source->suspended)
|
||||
return 0;
|
||||
if(activeTrigger == false)
|
||||
return 0;
|
||||
if (!toTcZone->targetsZone(e->to)) return 0;
|
||||
|
||||
@@ -96,6 +96,7 @@ class CardPrimitive {
|
||||
bool hasRestriction;
|
||||
int restriction;
|
||||
string otherrestriction;
|
||||
int suspendedTime;
|
||||
|
||||
vector<int>types;
|
||||
CardPrimitive();
|
||||
|
||||
@@ -119,6 +119,7 @@ class MTGAbility: public ActionElement{
|
||||
ManaCost * FlashBack;
|
||||
ManaCost * Retrace;
|
||||
ManaCost * morph;
|
||||
ManaCost * suspend;
|
||||
|
||||
Targetable * target;
|
||||
int aType;
|
||||
@@ -174,6 +175,7 @@ class MTGAbility: public ActionElement{
|
||||
STANDARD_TEACH = 26,
|
||||
STANDARD_TOKENCREATOR = 27,
|
||||
MORPH_COST = 28,
|
||||
SUSPEND_COST = 29,
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -79,6 +79,7 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
|
||||
int phasedTurn;
|
||||
bool graveEffects;
|
||||
bool exileEffects;
|
||||
bool suspended;
|
||||
|
||||
int stillInUse();
|
||||
int didattacked;
|
||||
|
||||
@@ -115,6 +115,28 @@ public:
|
||||
virtual MTGMorphCostRule * clone() const;
|
||||
};
|
||||
|
||||
class MTGSuspendRule: public MTGAlternativeCostRule
|
||||
{
|
||||
public:
|
||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||
int MTGSuspendRule::receiveEvent(WEvent *e);
|
||||
int reactToClick(MTGCardInstance * card);
|
||||
int testDestroy();
|
||||
string suspendmenu;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
MTGSuspendRule(int _id);
|
||||
const char * getMenuText()
|
||||
{
|
||||
suspendmenu = "Suspend";
|
||||
//char buffer[20];
|
||||
//sprintf(buffer,"-%i",card->suspendedTime);
|
||||
//suspendmenu.append(buffer);
|
||||
//TODO:make this work so it shows "Suspend-the amount of turns"
|
||||
return suspendmenu.c_str();
|
||||
}
|
||||
virtual MTGSuspendRule * clone() const;
|
||||
};
|
||||
|
||||
class MTGAttackRule: public MTGAbility, public Limitor
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -33,7 +33,8 @@ public:
|
||||
MANA_PAID_WITH_BUYBACK = 4,
|
||||
MANA_PAID_WITH_FLASHBACK = 5,
|
||||
MANA_PAID_WITH_RETRACE = 6,
|
||||
MANA_PAID_WITH_MORPH = 7
|
||||
MANA_PAID_WITH_MORPH = 7,
|
||||
MANA_PAID_WITH_SUSPEND = 8
|
||||
|
||||
};
|
||||
ExtraCosts * extraCosts;
|
||||
@@ -43,6 +44,7 @@ public:
|
||||
ManaCost * FlashBack;
|
||||
ManaCost * Retrace;
|
||||
ManaCost * morph;
|
||||
ManaCost * suspend;
|
||||
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL);
|
||||
virtual void init();
|
||||
void x();
|
||||
|
||||
@@ -31,6 +31,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
|
||||
toughness = source->toughness;
|
||||
restriction = source->restriction;
|
||||
otherrestriction = source->otherrestriction;
|
||||
suspendedTime = source->suspendedTime;
|
||||
|
||||
magicText = source->magicText;
|
||||
for (map<string, string>::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it)
|
||||
|
||||
@@ -28,6 +28,7 @@ void DuelLayers::init()
|
||||
action->Add(NEW MTGBuyBackRule(-1));
|
||||
action->Add(NEW MTGFlashBackRule(-1));
|
||||
action->Add(NEW MTGRetraceRule(-1));
|
||||
action->Add(NEW MTGSuspendRule(-1));
|
||||
action->Add(NEW MTGAttackRule(-1));
|
||||
action->Add(NEW MTGBlockRule(-1));
|
||||
action->Add(NEW MTGCombatTriggersRule(-1));
|
||||
|
||||
@@ -319,6 +319,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
|
||||
bool lifelost = false;
|
||||
int lifeamount = 0;
|
||||
bool limitOnceATurn = false;
|
||||
bool isSuspended = false;
|
||||
found = s.find("once");
|
||||
if (found != string::npos)
|
||||
{
|
||||
@@ -356,7 +357,11 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
|
||||
{
|
||||
limitOnceATurn = true;
|
||||
}
|
||||
|
||||
found = s.find("suspended");
|
||||
if ( found != string::npos)
|
||||
{
|
||||
isSuspended = true;
|
||||
}
|
||||
//Card Changed Zone
|
||||
found = s.find("movedto(");
|
||||
if (found != string::npos)
|
||||
@@ -407,7 +412,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
|
||||
fromTc = tcf.createTargetChooser(starget, card);
|
||||
fromTc->targetter = NULL; //avoid protection from
|
||||
}
|
||||
return NEW TrCardAddedToZone(id, card, (TargetZoneChooser *) toTc, toTcCard, (TargetZoneChooser *) fromTc, fromTcCard,once,sourceUntapped);
|
||||
return NEW TrCardAddedToZone(id, card, (TargetZoneChooser *) toTc, toTcCard, (TargetZoneChooser *) fromTc, fromTcCard,once,sourceUntapped,isSuspended);
|
||||
}
|
||||
|
||||
//Card unTapped
|
||||
@@ -3737,6 +3742,9 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
|
||||
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "plains"));
|
||||
}
|
||||
|
||||
if(card->previous && card->previous->previous && card->previous->previous->suspended)
|
||||
card->basicAbilities[Constants::HASTE] = 1;
|
||||
|
||||
if (card->hasType("instant") || card->hasType("sorcery"))
|
||||
{
|
||||
MTGPlayerCards * zones = card->controller()->game;
|
||||
|
||||
@@ -145,6 +145,7 @@ void MTGCardInstance::initMTGCI()
|
||||
damageToOpponent = false;
|
||||
damageToController = false;
|
||||
wasDealtDamage = false;
|
||||
suspended = false;
|
||||
|
||||
for (int i = 0; i < ManaCost::MANA_PAID_WITH_RETRACE +1; i++)
|
||||
alternateCostPaid[i] = 0;
|
||||
|
||||
@@ -289,24 +289,43 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
|
||||
}
|
||||
break;
|
||||
case 's': //subtype
|
||||
if (!primitive) primitive = NEW CardPrimitive();
|
||||
while (true)
|
||||
{
|
||||
char* found = strchr(val, ' ');
|
||||
if (found)
|
||||
if (s.find("suspend") != string::npos)
|
||||
{
|
||||
string value(val, found - val);
|
||||
primitive->setSubtype(value);
|
||||
val = found + 1;
|
||||
size_t time = s.find("suspend(");
|
||||
size_t end = s.find(")=");
|
||||
int suspendTime = atoi(s.substr(time + 8,end - 2).c_str());
|
||||
if (!primitive) primitive = NEW CardPrimitive();
|
||||
if (ManaCost * cost = primitive->getManaCost())
|
||||
{
|
||||
string value = val;
|
||||
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||
cost->suspend = ManaCost::parseManaCost(value);
|
||||
primitive->suspendedTime = suspendTime;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
primitive->setSubtype(val);
|
||||
break;
|
||||
if (!primitive) primitive = NEW CardPrimitive();
|
||||
while (true)
|
||||
{
|
||||
char* found = strchr(val, ' ');
|
||||
if (found)
|
||||
{
|
||||
string value(val, found - val);
|
||||
primitive->setSubtype(value);
|
||||
val = found + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
primitive->setSubtype(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (!primitive) primitive = NEW CardPrimitive();
|
||||
if (0 == strcmp("target", key))
|
||||
|
||||
@@ -64,6 +64,8 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
#ifdef WIN32
|
||||
cost->Dump();
|
||||
#endif
|
||||
if(!cost->getConvertedCost() && card->getManaCost()->suspend)
|
||||
return 0;
|
||||
//cost of card.
|
||||
if (playerMana->canAfford(cost))
|
||||
{
|
||||
@@ -519,6 +521,119 @@ MTGRetraceRule * MTGRetraceRule::clone() const
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
//Suspend
|
||||
MTGSuspendRule::MTGSuspendRule(int _id) :
|
||||
MTGAlternativeCostRule(_id)
|
||||
{
|
||||
aType = MTGAbility::SUSPEND_COST;
|
||||
}
|
||||
|
||||
int MTGSuspendRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
{
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * alternateManaCost = card->getManaCost()->suspend;
|
||||
|
||||
if (!player->game->hand->hasCard(card))
|
||||
return 0;
|
||||
return MTGAlternativeCostRule::isReactingToClick( card, mana, alternateManaCost );
|
||||
}
|
||||
|
||||
int MTGSuspendRule::receiveEvent(WEvent *e)
|
||||
{
|
||||
if (WEventPhaseChange* event = dynamic_cast<WEventPhaseChange*>(e))
|
||||
{
|
||||
if (Constants::MTG_PHASE_UNTAP == event->from->id)
|
||||
{
|
||||
Player * p = game->currentPlayer;
|
||||
MTGGameZone * z = p->game->exile;
|
||||
int originalAmount = z->nb_cards;
|
||||
for (int i = 0; i < z->nb_cards; i++)
|
||||
{
|
||||
MTGCardInstance * card = z->cards[i];
|
||||
|
||||
if (card->suspended && card->counters->hasCounter("Time",0,0))
|
||||
card->counters->removeCounter("Time",0,0);
|
||||
if (card->suspended && !card->counters->hasCounter("Time",0,0))
|
||||
{
|
||||
MTGCardInstance * copy = p->game->putInZone(card, card->currentZone, p->game->stack);
|
||||
Spell * spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, NULL,1, 0);
|
||||
game->targetChooser = NULL;
|
||||
}
|
||||
if(z->nb_cards != originalAmount)
|
||||
{
|
||||
i = 0;
|
||||
originalAmount = z->nb_cards;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGSuspendRule::reactToClick(MTGCardInstance * card)
|
||||
{
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
Player *player = game->currentlyActing();
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
ManaCost * alternateCost = card->getManaCost()->suspend;
|
||||
//this handles extra cost payments at the moment a card is played.
|
||||
if (playerMana->canAfford(alternateCost))
|
||||
{
|
||||
if (alternateCost->isExtraPaymentSet())
|
||||
{
|
||||
if (!game->targetListIsSet(card))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alternateCost->setExtraCostsAction(this, card);
|
||||
game->mExtraPayment = cost->suspend->extraCosts;
|
||||
return 0;
|
||||
}
|
||||
card->paymenttype = MTGAbility::SUSPEND_COST;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
int payResult = player->getManaPool()->pay(card->getManaCost()->suspend);
|
||||
card->getManaCost()->suspend->doPayExtra();
|
||||
payResult = ManaCost::MANA_PAID_WITH_SUSPEND;
|
||||
//---------------------------------------------------------------------------
|
||||
player->game->putInZone(card, card->currentZone, player->game->exile);
|
||||
card->next->suspended = true;
|
||||
for(signed int i = 0; i < card->suspendedTime;i++)
|
||||
card->next->counters->addCounter("Time",0,0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//The Put into play rule is never destroyed
|
||||
int MTGSuspendRule::testDestroy()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ostream& MTGSuspendRule::toString(ostream& out) const
|
||||
{
|
||||
out << "MTGSuspendRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
MTGSuspendRule * MTGSuspendRule::clone() const
|
||||
{
|
||||
MTGSuspendRule * a = NEW MTGSuspendRule(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
MTGMorphCostRule::MTGMorphCostRule(int _id) :
|
||||
MTGAbility(_id, NULL)
|
||||
{
|
||||
|
||||
@@ -257,6 +257,7 @@ ManaCost::ManaCost(ManaCost * manaCost)
|
||||
alternative = NEW ManaCost( manaCost->alternative );
|
||||
FlashBack = NEW ManaCost( manaCost->FlashBack );
|
||||
morph = NEW ManaCost( manaCost->morph );
|
||||
suspend = NEW ManaCost( manaCost->suspend );
|
||||
|
||||
// TODO: Need to figure out if a deep copy is necessary
|
||||
extraCosts = manaCost->extraCosts;
|
||||
@@ -285,6 +286,7 @@ ManaCost::ManaCost(const ManaCost& manaCost)
|
||||
alternative = NEW ManaCost( manaCost.alternative );
|
||||
FlashBack = NEW ManaCost( manaCost.FlashBack );
|
||||
morph = NEW ManaCost( manaCost.morph );
|
||||
suspend = NEW ManaCost( manaCost.suspend );
|
||||
|
||||
// TODO: Need to figure out if a deep copy is necessary
|
||||
extraCosts = manaCost.extraCosts;
|
||||
@@ -312,6 +314,7 @@ ManaCost & ManaCost::operator= (const ManaCost & manaCost)
|
||||
alternative = manaCost.alternative;
|
||||
FlashBack = manaCost.FlashBack;
|
||||
morph = manaCost.morph;
|
||||
suspend = manaCost.suspend;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -330,6 +333,7 @@ ManaCost::~ManaCost()
|
||||
SAFE_DELETE(FlashBack);
|
||||
SAFE_DELETE(Retrace);
|
||||
SAFE_DELETE(morph);
|
||||
SAFE_DELETE(suspend);
|
||||
}
|
||||
|
||||
void ManaCost::x()
|
||||
@@ -358,6 +362,7 @@ void ManaCost::init()
|
||||
FlashBack = NULL;
|
||||
Retrace = NULL;
|
||||
morph = NULL;
|
||||
suspend = NULL;
|
||||
|
||||
// why is hybrids hardcoded to 10?
|
||||
for (i = 0; i < 10; i++)
|
||||
@@ -424,6 +429,12 @@ void ManaCost::copy(ManaCost * _manaCost)
|
||||
morph = NEW ManaCost();
|
||||
morph->copy(_manaCost->morph);
|
||||
}
|
||||
SAFE_DELETE(suspend);
|
||||
if (_manaCost->suspend)
|
||||
{
|
||||
suspend = NEW ManaCost();
|
||||
suspend->copy(_manaCost->suspend);
|
||||
}
|
||||
}
|
||||
|
||||
int ManaCost::getCost(int color)
|
||||
|
||||
Reference in New Issue
Block a user