- added maxCast and maxPlay abilities, this deprecates the following abilities: nospells,nocreatures,onlyonespell,land
I usually don't like to deprecate abilities, but the existing ones, despite having easy to remember names, were really not flexible enough.

If you want to use these old keywords, instead use:
-- nospells  =>  maxCast(*)0
-- onlyOneSpell => maxCast(*)1
--nocreatures => maxCast(creature)0
--land:1 => maxplay(land)+1

note maxPlay and maxCast. They follow similar rules, but maxPlay monitors the number of cards that are going on the Battlefield, while maxCast monitors the stack. In most cases, maxCast should be the one to use, but lands are a special case because they go directly to play.

I unfortunately cannot guarantee I didn't break anything, especially in the AI, but the test suite passes ,and I added a few additional tests yesterday and today, to feel more confident about the change.

next step is removing the creatures keywords that do the same kind of thing (cantcast, etc...) and replace them with maxCast
This commit is contained in:
wagic.the.homebrew@gmail.com
2011-02-13 08:01:13 +00:00
parent 2165a38d3b
commit 8eac9c587e
14 changed files with 333 additions and 364 deletions
+15 -26
View File
@@ -1330,13 +1330,15 @@ int AIPlayerBaka::computeActions()
ipotential = true;
}
//look for an instant of ability to interupt with
if((castrestrictedspell == false && nospellinstant == false)&&
(onlyonecast == false || castcount < 2) && (onlyoneinstant == false || castcount < 2))
if((castrestrictedspell == false)&&
(onlyonecast == false || castcount < 2))
{
if (!nextCardToPlay)
{
nextCardToPlay = FindCardToPlay(icurrentMana, "instant");
if (game->playRestrictions->canPutIntoZone(nextCardToPlay, game->stack) == PlayRestriction::CANT_PLAY)
nextCardToPlay = NULL;
}
if (!nextCardToPlay)
{
@@ -1379,33 +1381,20 @@ int AIPlayerBaka::computeActions()
nextCardToPlay = FindCardToPlay(currentMana, "land");
selectAbility();
//look for the most expensive creature we can afford
if((castrestrictedspell == false && nospellinstant == false)&&
(onlyonecast == false || castcount < 2)&&(onlyoneinstant == false || castcount < 2))
if((castrestrictedspell == false)&&
(onlyonecast == false || castcount < 2))
{
if (castrestrictedcreature == false && nocreatureinstant == false)
const char* types[] = {"creature", "enchantment", "artifact", "sorcery", "instant"};
int count = 0;
while (!nextCardToPlay && count < 5)
{
if (!nextCardToPlay)
{
nextCardToPlay = FindCardToPlay(currentMana, "creature");
}
}
//Let's Try an enchantment maybe ?
if (!nextCardToPlay)
{
nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
}
if (!nextCardToPlay)
{
nextCardToPlay = FindCardToPlay(currentMana, "artifact");
}
if (!nextCardToPlay)
{
nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
}
if (!nextCardToPlay)
{
nextCardToPlay = FindCardToPlay(currentMana, "instant");
nextCardToPlay = FindCardToPlay(currentMana, types[count]);
if (game->playRestrictions->canPutIntoZone(nextCardToPlay, game->stack) == PlayRestriction::CANT_PLAY)
nextCardToPlay = NULL;
count++;
}
if (!nextCardToPlay)
{
selectAbility();
+84 -133
View File
@@ -1455,63 +1455,124 @@ AACloner::~AACloner()
{
}
// More Land - allow more lands to be played on a turn
AMoreLandPlzUEOT::AMoreLandPlzUEOT(int _id, MTGCardInstance * card, Targetable * _target, WParsedInt * _additional, int who) :
InstantAbilityTP(_id, card, _target, who), additional(_additional)
// Cast/Play Restriction modifier
ACastRestriction::ACastRestriction(int _id, MTGCardInstance * card, Targetable * _target, TargetChooser * _restrictionsScope, WParsedInt * _value, bool _modifyExisting, int _zoneId, int who) :
AbilityTP(_id, card, _target, who), restrictionsScope(_restrictionsScope), value(_value), modifyExisting(_modifyExisting),zoneId(_zoneId)
{
landsRestriction = NULL;
existingRestriction = NULL;
targetPlayer = NULL;
}
int AMoreLandPlzUEOT::addToGame()
int ACastRestriction::addToGame()
{
Targetable * _target = getTarget();
Player * player;
if (_target)
{
if (_target->typeAsTarget() == TARGET_CARD)
{
player = ((MTGCardInstance *) _target)->controller();
targetPlayer = ((MTGCardInstance *) _target)->controller();
}
else
{
player = (Player *) _target;
targetPlayer = (Player *) _target;
}
landsRestriction = (MaxPerTurnRestriction *) (player->game->playRestrictions->getRestrictionById(PlayRestriction::LANDS_RULE_ID));
if(landsRestriction && landsRestriction->maxPerTurn != MaxPerTurnRestriction::NO_MAX)
landsRestriction->maxPerTurn += additional->getValue();
return InstantAbility::addToGame();
if (modifyExisting)
{
//For now the only modifying rule is the one for lands, so this is hardcoded here.
//This means that a modifying rule for anything lands will actually modify the lands rule.
//In the future, we need a way to "identify" rules that modify an existing restriction, probably by doing a comparison of the TargetChoosers
existingRestriction = (MaxPerTurnRestriction *) (targetPlayer->game->playRestrictions->getRestrictionById(PlayRestriction::LANDS_RULE_ID));
if(existingRestriction && existingRestriction->maxPerTurn != MaxPerTurnRestriction::NO_MAX)
existingRestriction->maxPerTurn += value->getValue();
}
else
{
TargetChooser * _tc = restrictionsScope->clone();
existingRestriction = NEW MaxPerTurnRestriction(PlayRestriction::UNDEF_ID, _tc, value->getValue(), MTGGameZone::intToZone(zoneId, source->controller(), targetPlayer));
targetPlayer->game->playRestrictions->addRestriction(existingRestriction);
}
AbilityTP::addToGame();
}
return 0;
}
int AMoreLandPlzUEOT::destroy()
int ACastRestriction::destroy()
{
if (!landsRestriction)
if (!existingRestriction)
return 0;
if(landsRestriction && landsRestriction->maxPerTurn != MaxPerTurnRestriction::NO_MAX)
landsRestriction->maxPerTurn -= additional->getValue();
if (modifyExisting)
{
if(existingRestriction->maxPerTurn != MaxPerTurnRestriction::NO_MAX)
existingRestriction->maxPerTurn -= value->getValue();
}
else
{
targetPlayer->game->playRestrictions->removeRestriction(existingRestriction);
SAFE_DELETE(existingRestriction);
}
return 1;
}
const char * AMoreLandPlzUEOT::getMenuText()
const char * ACastRestriction::getMenuText()
{
return "Additional Lands";
if (modifyExisting)
return "Additional Lands"; //hardoced because only the lands rule allows to modify existing rule for now
return "Cast Restriction";
}
AMoreLandPlzUEOT * AMoreLandPlzUEOT::clone() const
ACastRestriction * ACastRestriction::clone() const
{
AMoreLandPlzUEOT * a = NEW AMoreLandPlzUEOT(*this);
a->additional = NEW WParsedInt(*(a->additional));
ACastRestriction * a = NEW ACastRestriction(*this);
a->value = NEW WParsedInt(*(a->value));
a->restrictionsScope = restrictionsScope->clone();
a->isClone = 1;
return a;
}
AMoreLandPlzUEOT::~AMoreLandPlzUEOT()
ACastRestriction::~ACastRestriction()
{
SAFE_DELETE(additional);
SAFE_DELETE(value);
SAFE_DELETE(restrictionsScope);
}
AInstantCastRestrictionUEOT::AInstantCastRestrictionUEOT(int _id, MTGCardInstance * card, Targetable * _target, TargetChooser * _restrictionsScope, WParsedInt * _value, bool _modifyExisting, int _zoneId, int who) :
InstantAbilityTP(_id, card, _target, who)
{
ability = NEW ACastRestriction(_id, card, _target, _restrictionsScope, _value, _modifyExisting, _zoneId, who);
}
int AInstantCastRestrictionUEOT::resolve()
{
ACastRestriction * a = ability->clone();
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source, (Damageable *) (this->target), a);
wrapper->addToGame();
return 1;
}
const char * AInstantCastRestrictionUEOT::getMenuText()
{
return ability->getMenuText();
}
AInstantCastRestrictionUEOT * AInstantCastRestrictionUEOT::clone() const
{
AInstantCastRestrictionUEOT * a = NEW AInstantCastRestrictionUEOT(*this);
a->ability = this->ability->clone();
a->isClone = 1;
return a;
}
AInstantCastRestrictionUEOT::~AInstantCastRestrictionUEOT()
{
SAFE_DELETE(ability);
}
//AAMover
AAMover::AAMover(int _id, MTGCardInstance * _source, MTGCardInstance * _target, string dest, ManaCost * _cost, int doTap) :
ActivatedAbility(_id, _source, _cost, 0, doTap), destination(dest)
@@ -1570,116 +1631,6 @@ AAMover * AAMover::clone() const
return a;
}
// No Creatures
AANoCreatures::AANoCreatures(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, int _tap, int who) :
ActivatedAbilityTP(_id, card, _target, _cost, _tap, who)
{
}
int AANoCreatures::resolve()
{
Targetable * _target = getTarget();
Player * player;
if (_target)
{
if (_target->typeAsTarget() == TARGET_CARD)
{
player = ((MTGCardInstance *) _target)->controller();
}
else
{
player = (Player *) _target;
}
player->nocreatureinstant = true;
}
return 1;
}
const char * AANoCreatures::getMenuText()
{
return "No Creatures!";
}
AANoCreatures * AANoCreatures::clone() const
{
AANoCreatures * a = NEW AANoCreatures(*this);
a->isClone = 1;
return a;
}
// AA No Spells
AANoSpells::AANoSpells(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, int _tap, int who) :
ActivatedAbilityTP(_id, card, _target, _cost, _tap, who)
{
}
int AANoSpells::resolve()
{
Targetable * _target = getTarget();
Player * player;
if (_target)
{
if (_target->typeAsTarget() == TARGET_CARD)
{
player = ((MTGCardInstance *) _target)->controller();
}
else
{
player = (Player *) _target;
}
player->nospellinstant = true;
}
return 1;
}
const char * AANoSpells::getMenuText()
{
return "No Spells!";
}
AANoSpells * AANoSpells::clone() const
{
AANoSpells * a = NEW AANoSpells(*this);
a->isClone = 1;
return a;
}
//OnlyOne
AAOnlyOne::AAOnlyOne(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, int _tap, int who) :
ActivatedAbilityTP(_id, card, _target, _cost, _tap, who)
{
}
int AAOnlyOne::resolve()
{
Targetable * _target = getTarget();
Player * player;
if (_target)
{
if (_target->typeAsTarget() == TARGET_CARD)
{
player = ((MTGCardInstance *) _target)->controller();
}
else
{
player = (Player *) _target;
}
player->onlyoneinstant = true;
}
return 1;
}
const char * AAOnlyOne::getMenuText()
{
return "Only One Spell!";
}
AAOnlyOne * AAOnlyOne::clone() const
{
AAOnlyOne * a = NEW AAOnlyOne(*this);
a->isClone = 1;
return a;
}
//Random Discard
AARandomDiscarder::AARandomDiscarder(int _id, MTGCardInstance * card, Targetable * _target,string nbcardsStr, ManaCost * _cost,
int _tap, int who) :
-3
View File
@@ -111,9 +111,6 @@ void GameObserver::nextGamePhase()
currentPlayer->castedspellsthisturn = 0;
currentPlayer->opponent()->castedspellsthisturn = 0;
currentPlayer->castcount = 0;
currentPlayer->nocreatureinstant = false;
currentPlayer->nospellinstant = false;
currentPlayer->onlyoneinstant = false;
currentPlayer->damageCount = 0;
currentPlayer->preventable = 0;
currentPlayer->isPoisoned = false;
+84 -53
View File
@@ -18,6 +18,10 @@ const size_t kLordKeywordsCount = 5;
const string kThisKeywords[] = { "this(", "thisforeach(" };
const size_t kThisKeywordsCount = 2;
const string kMaxCastKeywords[] = { "maxplay(", "maxcost("};
const int kMaxCastZones[] = { MTGGameZone::BATTLEFIELD, MTGGameZone::STACK};
const size_t kMaxCastKeywordsCount = 2;
int MTGAbility::allowedToCast(MTGCardInstance * card,Player * player)
{
int cPhase = game->getCurrentGamePhase();
@@ -699,7 +703,8 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
}
return NEW TrVampired(id, card, tc, fromTc, 0);
}
//when card becomes the target of a spell or ability
//when card becomes the target of a spell or ability
found = s.find("targeted(");
if (found != string::npos)
{
@@ -796,6 +801,7 @@ int AbilityFactory::parseRestriction(string s)
return ActivatedAbility::NO_RESTRICTION;
}
// When abilities encapsulate each other, gets the deepest one (it is the one likely to have the most relevant information)
MTGAbility * AbilityFactory::getCoreAbility(MTGAbility * a)
{
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*> (a);
@@ -2187,27 +2193,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
a->oneShot = 1;
return a;
}
//additional lands per turn
found = s.find("land:");
if (found != string::npos)
{
size_t start = s.find(":", found);
size_t end = s.find(" ", start);
string additionalStr;
if (end != string::npos)
{
additionalStr = s.substr(start + 1, end - start - 1);
}
else
{
additionalStr = s.substr(start + 1);
}
WParsedInt * additional = NEW WParsedInt(additionalStr, spell, card);
Targetable * t = NULL;
if (spell)
t = spell->getNextTarget();
return NEW AMoreLandPlzUEOT(id, card, t, additional, who);
}
//Deplete
found = s.find("deplete:");
@@ -2244,38 +2230,45 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return a;
}
//cantcastspells
found = s.find("onlyonespell");
if (found != string::npos)
//Cast/Play Restrictions
for (size_t i = 0; i < kMaxCastKeywordsCount; ++i)
{
Targetable * t = NULL;
if (spell)
t = spell->getNextTarget();
MTGAbility * a = NEW AAOnlyOne(id, card, t, NULL, 0, who);
a->oneShot = 1;
return a;
}
//cantcastspells
found = s.find("nospells");
if (found != string::npos)
{
Targetable * t = NULL;
if (spell)
t = spell->getNextTarget();
MTGAbility * a = NEW AANoSpells(id, card, t, NULL, 0, who);
a->oneShot = 1;
return a;
}
//cantcastcreature
found = s.find("nocreatures");
if (found != string::npos)
{
Targetable * t = NULL;
if (spell)
t = spell->getNextTarget();
MTGAbility * a = NEW AANoCreatures(id, card, t, NULL, 0, who);
a->oneShot = 1;
return a;
found = s.find(kMaxCastKeywords[i]);
if (found != string::npos)
{
size_t header = kMaxCastKeywords[i].size();
size_t end = s.find(")");
string targetsString = s.substr(found + header, end - found - header);
TargetChooserFactory tcf;
TargetChooser * castTargets = tcf.createTargetChooser(targetsString, card);
size_t space = s.find(" ", end);
string valueStr;
if (space!= string::npos)
{
valueStr = s.substr(end + 1, space - end - 1);
}
else
{
valueStr = s.substr(end + 1);
}
bool modifyExisting = (valueStr.find("+") != string::npos || valueStr.find("-") != string::npos);
WParsedInt * value = NEW WParsedInt(valueStr, spell, card);
Targetable * t = NULL;
if (spell)
t = spell->getNextTarget();
if (!activated)
{
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT)
{
return NEW AInstantCastRestrictionUEOT(id, card, t, castTargets, value, modifyExisting, kMaxCastZones[i], who);
}
return NEW ACastRestriction(id, card, t, castTargets, value, modifyExisting, kMaxCastZones[i], who);
}
return NULL; //TODO NEW ACastRestrictionUntilEndOfTurn(id, card, t, value, modifyExisting, kMaxCastZones[i], who);
}
}
//Discard
@@ -4752,6 +4745,44 @@ AManaProducer * AManaProducer::clone() const
return a;
}
AbilityTP::AbilityTP(int id, MTGCardInstance * card, Targetable * _target, int who) :
MTGAbility(id, card), who(who)
{
if (_target)
target = _target;
}
Targetable * AbilityTP::getTarget()
{
switch (who)
{
case TargetChooser::TARGET_CONTROLLER:
if (target)
{
switch (target->typeAsTarget())
{
case TARGET_CARD:
return ((MTGCardInstance *) target)->controller();
case TARGET_STACKACTION:
return ((Interruptible *) target)->source->controller();
default:
return (Player *) target;
}
}
return NULL;
case TargetChooser::CONTROLLER:
return source->controller();
case TargetChooser::OPPONENT:
return source->controller()->opponent();
case TargetChooser::OWNER:
return source->owner;
default:
return target;
}
return NULL;
}
ActivatedAbilityTP::ActivatedAbilityTP(int id, MTGCardInstance * card, Targetable * _target, ManaCost * cost, int doTap, int who) :
ActivatedAbility(id, card, cost, 0, doTap), who(who)
{
+62 -42
View File
@@ -731,6 +731,63 @@ void MTGLibrary::shuffleTopToBottom(int nbcards)
}
}
MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2)
{
switch (zoneId)
{
case MY_GRAVEYARD:
return p->game->graveyard;
case OPPONENT_GRAVEYARD:
return p->opponent()->game->graveyard;
case TARGET_CONTROLLER_GRAVEYARD:
return p2->game->graveyard;
case MY_BATTLEFIELD:
return p->game->inPlay;
case OPPONENT_BATTLEFIELD:
return p->opponent()->game->inPlay;
case TARGET_CONTROLLER_BATTLEFIELD:
return p2->game->inPlay;
case BATTLEFIELD:
return p->game->inPlay;
case MY_HAND:
return p->game->hand;
case OPPONENT_HAND:
return p->opponent()->game->hand;
case TARGET_CONTROLLER_HAND:
return p2->game->hand;
case MY_EXILE:
return p->game->removedFromGame;
case OPPONENT_EXILE:
return p->opponent()->game->removedFromGame;
case TARGET_CONTROLLER_EXILE:
return p2->game->removedFromGame;
case MY_LIBRARY:
return p->game->library;
case OPPONENT_LIBRARY:
return p->opponent()->game->library;
case TARGET_CONTROLLER_LIBRARY:
return p2->game->library;
case LIBRARY:
return p->game->library;
case MY_STACK:
return p->game->stack;
case OPPONENT_STACK:
return p->opponent()->game->stack;
case TARGET_CONTROLLER_STACK:
return p2->game->stack;
case STACK:
return p->game->stack;
default:
return NULL;
}
}
MTGGameZone * MTGGameZone::intToZone(int zoneId, MTGCardInstance * source, MTGCardInstance * target)
{
Player *p, *p2;
@@ -758,88 +815,51 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, MTGCardInstance * source, MTGCa
else
p2 = target->controller();
MTGGameZone * result = intToZone(zoneId, p, p2);
if (result) return result;
switch (zoneId)
{
case MY_GRAVEYARD:
return p->game->graveyard;
case OPPONENT_GRAVEYARD:
return p->opponent()->game->graveyard;
case TARGET_OWNER_GRAVEYARD:
return target->owner->game->graveyard;
case TARGET_CONTROLLER_GRAVEYARD:
return p2->game->graveyard;
case GRAVEYARD:
return target->owner->game->graveyard;
case OWNER_GRAVEYARD:
return target->owner->game->graveyard;
case MY_BATTLEFIELD:
return p->game->inPlay;
case OPPONENT_BATTLEFIELD:
return p->opponent()->game->inPlay;
case TARGET_OWNER_BATTLEFIELD:
return target->owner->game->inPlay;
case TARGET_CONTROLLER_BATTLEFIELD:
return p2->game->inPlay;
case BATTLEFIELD:
return p->game->inPlay;
case OWNER_BATTLEFIELD:
return target->owner->game->inPlay;
case MY_HAND:
return p->game->hand;
case OPPONENT_HAND:
return p->opponent()->game->hand;
case TARGET_OWNER_HAND:
return target->owner->game->hand;
case TARGET_CONTROLLER_HAND:
return p2->game->hand;
case HAND:
return target->owner->game->hand;
case OWNER_HAND:
return target->owner->game->hand;
case MY_EXILE:
return p->game->removedFromGame;
case OPPONENT_EXILE:
return p->opponent()->game->removedFromGame;
case TARGET_OWNER_EXILE:
return target->owner->game->removedFromGame;
case TARGET_CONTROLLER_EXILE:
return p2->game->removedFromGame;
case EXILE:
return target->owner->game->removedFromGame;
case OWNER_EXILE:
return target->owner->game->removedFromGame;
case MY_LIBRARY:
return p->game->library;
case OPPONENT_LIBRARY:
return p->opponent()->game->library;
case TARGET_OWNER_LIBRARY:
return target->owner->game->library;
case TARGET_CONTROLLER_LIBRARY:
return p2->game->library;
case LIBRARY:
return p->game->library;
case OWNER_LIBRARY:
return target->owner->game->library;
case MY_STACK:
return p->game->stack;
case OPPONENT_STACK:
return p->opponent()->game->stack;
case TARGET_OWNER_STACK:
return target->owner->game->stack;
case TARGET_CONTROLLER_STACK:
return p2->game->stack;
case STACK:
return p->game->stack;
case OWNER_STACK:
return target->owner->game->stack;
default:
return NULL;
}
}
int MTGGameZone::zoneStringToId(string zoneName)
+14 -49
View File
@@ -55,6 +55,9 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
)
{
if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->stack) == PlayRestriction::CANT_PLAY)
return 0;
ManaCost * playerMana = player->getManaPool();
ManaCost * cost = card->getManaCost();
@@ -69,21 +72,7 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
return 0;
}
if (player->nospellinstant)
{
return 0;
}
if (player->onlyoneinstant)
{
if (player->castcount >= 1)
{
return 0;
}
}
if (player->nocreatureinstant && card->hasType("creature"))
{
return 0;
}
if (player->castrestrictedcreature && card->hasType("creature"))
{
return 0;
@@ -168,7 +157,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast || player->onlyoneinstant)
if (player->onlyonecast)
{
player->castcount += 1;
}
@@ -178,7 +167,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0);
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast || player->onlyoneinstant)
if (player->onlyonecast)
{
player->castcount += 1;
}
@@ -275,6 +264,8 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
)
{
if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->stack) == PlayRestriction::CANT_PLAY)
return 0;
ManaCost * playerMana = player->getManaPool();
#ifdef WIN32
@@ -289,21 +280,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
{
return 0;
}
if (player->nospellinstant )
{
return 0;
}
if (player->onlyoneinstant )
{
if (player->castcount >= 1)
{
return 0;
}
}
if (player->nocreatureinstant && card->hasType("creature"))
{
return 0;
}
if (player->castrestrictedcreature && card->hasType("creature"))
{
return 0;
@@ -375,7 +352,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast || player->onlyoneinstant)
if (player->onlyonecast )
player->castcount += 1;
if (card->has(Constants::STORM))
@@ -610,6 +587,8 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
)
{
if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->stack) == PlayRestriction::CANT_PLAY)
return 0;
ManaCost * playerMana = player->getManaPool();
ManaCost * cost = card->getManaCost();
ManaCost * morph = card->getManaCost()->morph;
@@ -624,21 +603,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
return 0;
}
if (player->nospellinstant )
{
return 0;
}
if (player->onlyoneinstant )
{
if (player->castcount >= 1)
{
return 0;
}
}
if (player->nocreatureinstant && card->hasType("creature"))
{
return 0;
}
if (player->castrestrictedcreature && card->hasType("creature"))
{
return 0;
@@ -709,7 +674,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card)
copy->toughness = 2;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast || player->onlyoneinstant)
if (player->onlyonecast)
{
player->castcount += 1;
-3
View File
@@ -21,9 +21,6 @@ Damageable(20)
onlyoneboth = false;
onlyonecast = false;
castcount = 0;
nocreatureinstant = false;
nospellinstant = false;
onlyoneinstant = false;
poisonCount = 0;
damageCount = 0;
preventable = 0;