From 3f090c7be858b521d2de47ce462036d6b5462ed5 Mon Sep 17 00:00:00 2001 From: "omegablast2002@yahoo.com" Date: Fri, 25 Feb 2011 18:40:23 +0000 Subject: [PATCH] added basic suspend. syntax suspend(number of time counter)={cost} suspend(3)={g} --- projects/mtg/include/AllAbilities.h | 7 +- projects/mtg/include/CardPrimitive.h | 1 + projects/mtg/include/MTGAbility.h | 2 + projects/mtg/include/MTGCardInstance.h | 1 + projects/mtg/include/MTGRules.h | 22 +++++ projects/mtg/include/ManaCost.h | 4 +- projects/mtg/src/CardPrimitive.cpp | 1 + projects/mtg/src/DuelLayers.cpp | 1 + projects/mtg/src/MTGAbility.cpp | 12 ++- projects/mtg/src/MTGCardInstance.cpp | 1 + projects/mtg/src/MTGDeck.cpp | 41 ++++++--- projects/mtg/src/MTGRules.cpp | 115 +++++++++++++++++++++++++ projects/mtg/src/ManaCost.cpp | 11 +++ 13 files changed, 203 insertions(+), 16 deletions(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 5acfe6393..8364dcb33 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -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; diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index ecd6f1643..42f4e1e4f 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -96,6 +96,7 @@ class CardPrimitive { bool hasRestriction; int restriction; string otherrestriction; + int suspendedTime; vectortypes; CardPrimitive(); diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index 52d45e3f8..94bcd40db 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -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, }; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index fc9905430..5156e489c 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -79,6 +79,7 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable { int phasedTurn; bool graveEffects; bool exileEffects; + bool suspended; int stillInUse(); int didattacked; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 770af1b89..0015fbf90 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -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: diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index a34686ca8..19d1f93eb 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -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(); diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 9612024ca..c796c9d1a 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -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::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it) diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index b5d78dfd5..3c4cb4c21 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -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)); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 37d6762c1..64c90ec47 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -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; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 3ac16648b..791333333 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -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; diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 6b3aa94ab..0bf09170d 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -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)) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 433edf087..d8d87e259 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -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(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) { diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index e5b919042..18c89c3d9 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -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)