Erwan
- 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:
@@ -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) :
|
||||
|
||||
Reference in New Issue
Block a user