Psyringe - added quantifiable target restrictions. Whenever you use square brackets [] to specify attributes of a target, you can use the operators <=, >= and = to specify quantities for power, toughness, and/or converted manacost. See added cards for examples.
Limitations: - Operators for "greater than", "less than", "unequal" have not been implemented, but if a card actually needs them, you can use a preceding minus sign to negate a comparison. Example: -power=3 means "power not equal to 3", -toughness<=3 means "toughness>3". - You can't use spaces when specifying such restrictions. Write "power<=3" instead of "power <= 3" - You now need to use a space before the "<" and ">" commands that count the matches for lord(), foreach(), all() and aslongas(). So far we always did use spaces in front of them without actually needing to, now we need to. - manacost restrictions don't take "X" costs into account. Example: Mistmeadow Skulkin (FUT) has protection from manacost>=3. Blaze has a converted manacost of 1, but when you cast it with an X of 2, then it actually has a converted manacost of 3 while on the stack, and Mistmeadow Skulkin would be protected from it, but currently it isn't. Please review the code, I'll add a few remarks/questions of my own.
This commit is contained in:
@@ -3,9 +3,14 @@
|
||||
#include "../include/Subtypes.h"
|
||||
#include "../include/Counters.h"
|
||||
|
||||
|
||||
CardDescriptor::CardDescriptor(): MTGCardInstance(){
|
||||
init();
|
||||
mode = CD_AND;
|
||||
powerComparisonMode = COMPARISON_NONE;
|
||||
toughnessComparisonMode = COMPARISON_NONE;
|
||||
manacostComparisonMode = COMPARISON_NONE;
|
||||
convertedManacost = -1;
|
||||
}
|
||||
|
||||
int CardDescriptor::init(){
|
||||
@@ -29,6 +34,26 @@ void CardDescriptor::setNegativeSubtype( string value){
|
||||
addType(-id);
|
||||
}
|
||||
|
||||
// Very generic function to compare a value to a criterion.
|
||||
// Should be easily transferable to a more generic class if desired.
|
||||
bool CardDescriptor::valueInRange(int comparisonMode, int value, int criterion){
|
||||
switch (comparisonMode){
|
||||
case COMPARISON_AT_MOST:
|
||||
return (value <= criterion);
|
||||
case COMPARISON_AT_LEAST:
|
||||
return (value >= criterion);
|
||||
case COMPARISON_EQUAL:
|
||||
return (value == criterion);
|
||||
case COMPARISON_GREATER:
|
||||
return (value > criterion);
|
||||
case COMPARISON_LESS:
|
||||
return (value < criterion);
|
||||
case COMPARISON_UNEQUAL:
|
||||
return (value != criterion);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card){
|
||||
int found = 1;
|
||||
for (int i = 0; i< nb_types; i++){
|
||||
@@ -65,6 +90,12 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card){
|
||||
}
|
||||
}
|
||||
if (!found) return NULL;
|
||||
|
||||
// Quantified restrictions are always AND-ed:
|
||||
if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power) ) return NULL;
|
||||
if (toughnessComparisonMode && !valueInRange(toughnessComparisonMode, card->getToughness(), toughness) ) return NULL;
|
||||
if (manacostComparisonMode && !valueInRange(manacostComparisonMode, card->getManaCost()->getConvertedCost(), convertedManacost) ) return NULL;
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
@@ -86,6 +117,11 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card){
|
||||
match = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power) ) match = NULL;
|
||||
if (toughnessComparisonMode && !valueInRange(toughnessComparisonMode, card->getToughness(), toughness) ) match = NULL;
|
||||
if (manacostComparisonMode && !valueInRange(manacostComparisonMode, card->getManaCost()->getConvertedCost(), convertedManacost) ) match = NULL;
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
@@ -364,10 +364,10 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
|
||||
int mini = 0;
|
||||
int maxi = 0;
|
||||
found = s.find(">");
|
||||
if (found !=string::npos) mini = atoi(s.substr(found+1,1).c_str());
|
||||
found = s.find("<");
|
||||
if (found !=string::npos) maxi = atoi(s.substr(found+1,1).c_str());
|
||||
found = s.find(" >");
|
||||
if (found !=string::npos) mini = atoi(s.substr(found+2,1).c_str());
|
||||
found = s.find(" <");
|
||||
if (found !=string::npos) maxi = atoi(s.substr(found+2,1).c_str());
|
||||
switch(i){
|
||||
case 0: result = NEW ALord(id, card, lordTargets, lordIncludeSelf, a); break;
|
||||
case 1: result = NEW AForeach(id, card, _target,lordTargets, lordIncludeSelf, a,mini,maxi); break;
|
||||
@@ -1351,13 +1351,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1285: //Dwarven Warriors
|
||||
{
|
||||
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
||||
tc->maxpower = 2;
|
||||
game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, Constants::UNBLOCKABLE, NULL,tc));
|
||||
break;
|
||||
}
|
||||
case 1288: //EarthBind
|
||||
{
|
||||
game->addObserver(NEW AEarthbind(_id, card, card->target));
|
||||
@@ -1435,15 +1428,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
||||
game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, card->target, NEW WParsedPT(power,toughness)));
|
||||
}
|
||||
|
||||
case 1703: //Pendelhaven
|
||||
{
|
||||
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
||||
tc->maxpower = 1;
|
||||
tc->maxtoughness =1;
|
||||
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, NEW WParsedPT(1,2), NEW ManaCost(),tc));
|
||||
break;
|
||||
}
|
||||
|
||||
//Addons ICE-AGE Cards
|
||||
|
||||
case 2474: //Minion of Leshrac
|
||||
@@ -1456,25 +1440,8 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
|
||||
game->addObserver(NEW AShieldOfTheAge( _id, card));
|
||||
break;
|
||||
}
|
||||
case 2435: //Whalebone Glider
|
||||
{
|
||||
int cost[] = {Constants::MTG_COLOR_ARTIFACT,2};
|
||||
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
||||
tc->maxpower = 3;
|
||||
game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, Constants::FLYING, NEW ManaCost(cost,1),tc));
|
||||
break;
|
||||
}
|
||||
case 2393: //Aegis of the Meek work but work also for 0/1 creatures... :D
|
||||
{
|
||||
int cost[] = {Constants::MTG_COLOR_ARTIFACT,1};
|
||||
CreatureTargetChooser * tc = NEW CreatureTargetChooser(card);
|
||||
tc->maxpower = 1;
|
||||
tc->maxtoughness =1;
|
||||
game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, NEW WParsedPT(1,2), NEW ManaCost(cost,1),tc));
|
||||
break;
|
||||
}
|
||||
|
||||
// --- addon Mirage ---
|
||||
// --- addon Mirage ---
|
||||
|
||||
case 3410: //Seed of Innocence
|
||||
{
|
||||
|
||||
@@ -121,6 +121,40 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
nbminuses++;
|
||||
attribute=attribute.substr(1);
|
||||
}
|
||||
int comparisonMode = COMPARISON_NONE;
|
||||
int comparisonCriterion = 0;
|
||||
if (attribute.size() > 1){
|
||||
size_t operatorPosition = attribute.find("=",1);
|
||||
if (operatorPosition != string::npos){
|
||||
comparisonCriterion = atoi(attribute.substr(operatorPosition+1,attribute.size()-operatorPosition-1).c_str());
|
||||
switch (attribute[operatorPosition-1]){
|
||||
case '<':
|
||||
if (minus){
|
||||
comparisonMode = COMPARISON_GREATER;
|
||||
}else{
|
||||
comparisonMode = COMPARISON_AT_MOST;
|
||||
}
|
||||
operatorPosition--;
|
||||
break;
|
||||
case '>':
|
||||
if (minus){
|
||||
comparisonMode = COMPARISON_LESS;
|
||||
}else{
|
||||
comparisonMode = COMPARISON_AT_LEAST;
|
||||
}
|
||||
operatorPosition--;
|
||||
break;
|
||||
default:
|
||||
if (minus){
|
||||
comparisonMode = COMPARISON_UNEQUAL;
|
||||
}else{
|
||||
comparisonMode = COMPARISON_EQUAL;
|
||||
}
|
||||
}
|
||||
attribute = attribute.substr(0,operatorPosition);
|
||||
}
|
||||
}
|
||||
|
||||
//Attacker
|
||||
if (attribute.find("attacking") != string::npos){
|
||||
if (minus){
|
||||
@@ -142,6 +176,18 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
}else{
|
||||
cd->unsecureSetTapped(1);
|
||||
}
|
||||
//Power restrictions
|
||||
}else if (attribute.find("power") != string::npos){
|
||||
cd->setPower(comparisonCriterion);
|
||||
cd->powerComparisonMode = comparisonMode;
|
||||
//Toughness restrictions
|
||||
}else if (attribute.find("toughness") != string::npos){
|
||||
cd->setToughness(comparisonCriterion);
|
||||
cd->toughnessComparisonMode = comparisonMode;
|
||||
//Manacost restrictions
|
||||
}else if (attribute.find("manacost") != string::npos){
|
||||
cd->convertedManacost = comparisonCriterion;
|
||||
cd->manacostComparisonMode = comparisonMode;
|
||||
}else{
|
||||
int attributefound = 0;
|
||||
//Colors
|
||||
@@ -474,8 +520,6 @@ DescriptorTargetChooser::~DescriptorTargetChooser(){
|
||||
CreatureTargetChooser::CreatureTargetChooser( MTGCardInstance * card, int _maxtargets, bool other):TargetZoneChooser(card, _maxtargets, other){
|
||||
int default_zones[] = {MTGGameZone::MY_BATTLEFIELD, MTGGameZone::OPPONENT_BATTLEFIELD};
|
||||
init(default_zones,2);
|
||||
maxpower= -1;
|
||||
maxtoughness= -1;
|
||||
}
|
||||
|
||||
CreatureTargetChooser::CreatureTargetChooser(int * _zones, int nbzones, MTGCardInstance * card, int _maxtargets, bool other):TargetZoneChooser(card, _maxtargets, other){
|
||||
@@ -485,8 +529,6 @@ CreatureTargetChooser::CreatureTargetChooser(int * _zones, int nbzones, MTGCardI
|
||||
}else{
|
||||
init(_zones, nbzones);
|
||||
}
|
||||
maxpower = -1;
|
||||
maxtoughness= -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -494,8 +536,6 @@ bool CreatureTargetChooser::canTarget(Targetable * target){
|
||||
if (!TargetZoneChooser::canTarget(target)) return false;
|
||||
if (target->typeAsTarget() == TARGET_CARD){
|
||||
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||
if (maxpower != -1 && card->power > maxpower) return false;
|
||||
if (maxtoughness != -1 && card->toughness > maxtoughness) return false;
|
||||
return card->isCreature();
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user