#include "PrecompiledHeader.h" #include "ThisDescriptor.h" #include "Counters.h" #include "MTGCardInstance.h" #include "CardDescriptor.h" ThisDescriptor::~ThisDescriptor() { //nothing to do for now } //Returns the amount by which a value passes the comparison. int ThisDescriptor::matchValue(int value) { switch (comparisonMode) { case COMPARISON_AT_MOST: return (comparisonCriterion - value + 1); case COMPARISON_AT_LEAST: return (value - comparisonCriterion + 1); case COMPARISON_EQUAL: return (comparisonCriterion == value); case COMPARISON_GREATER: return (value - comparisonCriterion); case COMPARISON_LESS: return (comparisonCriterion - value); case COMPARISON_UNEQUAL: return (comparisonCriterion != value); } return 0; } ThisDescriptor * ThisDescriptorFactory::createThisDescriptor(string s) { size_t found; string whitespaces(" \t\f\v\n\r"); found = s.find_last_not_of(whitespaces); if (found != string::npos) s.erase(found + 1); else return NULL; found = s.find_first_not_of(whitespaces); if (found != string::npos) s.erase(0, found); else return NULL; //set comparison mode //equal, greater, and less must remain above the others, otherwise the others may never be used. int mode = 0; size_t found2 = string::npos; int opLength = 0; found = s.find("="); if (found != string::npos) { mode = COMPARISON_EQUAL; found2 = found + 1; opLength = 1; } found = s.find(">"); if (found != string::npos) { mode = COMPARISON_GREATER; found2 = found + 1; opLength = 1; } found = s.find("<"); if (found != string::npos) { mode = COMPARISON_LESS; found2 = found + 1; opLength = 1; } found = s.find("<="); if (found != string::npos) { mode = COMPARISON_AT_MOST; found2 = found + 2; opLength = 2; } found = s.find(">="); if (found != string::npos) { mode = COMPARISON_AT_LEAST; found2 = found + 2; opLength = 2; } found = s.find("!="); if (found != string::npos) { mode = COMPARISON_UNEQUAL; found2 = found + 2; opLength = 2; } if (!mode) mode = COMPARISON_AT_LEAST; //get comparison criterion int criterionFound = 0; int criterion = 1; if ((found2 != string::npos) && (found2 < s.length())) { criterion = atoi(s.substr(found2).c_str()); criterionFound = 1; } if (found2 != string::npos) s.erase(found2 - opLength); //counters found = s.find("counter{"); if (found != string::npos) { size_t start = s.find("{"); size_t end = s.find("}"); string counterString = s.substr(start + 1, end - start - 1); AbilityFactory abf; Counter * counter = abf.parseCounter(counterString, NULL); if (counter) { if (criterionFound) counter->nb = criterion; ThisCounter * td = NEW ThisCounter(counter); if (td) { td->comparisonMode = mode; return td; } } return NULL; } //any counter found = s.find("counters"); if (found != string::npos) { ThisCounterAny * td = NEW ThisCounterAny(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //equips and auras found = s.find("gear");//still same meaning, better wording to word conflict with MTGAbility equip. if (found != string::npos) { ThisEquip * td = NEW ThisEquip(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } found = s.find("auras"); if (found != string::npos) { ThisAuras * td = NEW ThisAuras(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } // opponent damage count found = s.find("opponentdamagecount"); if (found != string::npos) { ThisOpponentDamageAmount * td = NEW ThisOpponentDamageAmount(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //untapped status found = s.find("untapped"); if (found != string::npos) { ThisUntapped * td = NEW ThisUntapped(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } found = s.find("tapped"); if (found != string::npos) { ThisTapped * td = NEW ThisTapped(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //whenever this creature attacks do effect found = s.find("attacking"); if (found != string::npos) { ThisAttacked * td = NEW ThisAttacked(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //whenever this creature blocks do effect found = s.find("blocking"); if (found != string::npos) { ThisBlocked * td = NEW ThisBlocked(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //whenever this creature attacks do effect found = s.find("notblocked"); if (found != string::npos) { ThisNotBlocked * td = NEW ThisNotBlocked(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //this creature was dealt damage this turn found = s.find("damaged"); if (found != string::npos) { ThisDamaged * td = NEW ThisDamaged(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //controller life found = s.find("opponentlife"); if (found != string::npos) { ThisOpponentlife * td = NEW ThisOpponentlife(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //controller life found = s.find("controllerlife"); if (found != string::npos) { ThisControllerlife * td = NEW ThisControllerlife(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //power found = s.find("power"); if (found != string::npos) { ThisPower * td = NEW ThisPower(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } //toughness found = s.find("toughness"); if (found != string::npos) { ThisToughness * td = NEW ThisToughness(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } // X found = s.find("x"); if (found != string::npos) { ThisX * td = NEW ThisX(criterion); if (td) { td->comparisonMode = mode; return td; } return NULL; } return NULL; } ThisCounter::ThisCounter(Counter * _counter) { counter = _counter; comparisonCriterion = counter->nb; } ThisCounter::ThisCounter(int power, int toughness, int nb, const char * name) { counter = NEW Counter(NULL, name, power, toughness); comparisonCriterion = nb; } int ThisCounter::match(MTGCardInstance * card) { Counter * targetCounter = card->counters->hasCounter(counter->name.c_str(), counter->power, counter->toughness); if (targetCounter) { return matchValue(targetCounter->nb); } else { switch (comparisonMode) { case COMPARISON_LESS: return comparisonCriterion; case COMPARISON_AT_MOST: return comparisonCriterion + 1; case COMPARISON_UNEQUAL: if (comparisonCriterion) return 1; else return 0; case COMPARISON_EQUAL: if (comparisonCriterion) return 0; else return 1; default: return 0; } } } ThisCounter::~ThisCounter() { SAFE_DELETE(counter); } ThisOpponentlife::ThisOpponentlife(int olife) { comparisonCriterion = olife; } int ThisOpponentlife::match(MTGCardInstance * card) { return matchValue(card->controller()->opponent()->life); } ThisControllerlife::ThisControllerlife(int life) { comparisonCriterion = life; } int ThisControllerlife::match(MTGCardInstance * card) { return matchValue(card->controller()->life); } ThisPower::ThisPower(int power) { comparisonCriterion = power; } int ThisPower::match(MTGCardInstance * card) { return matchValue(card->power); } ThisEquip::ThisEquip(int equipment) { comparisonCriterion = equipment; } int ThisEquip::match(MTGCardInstance * card) { return matchValue(card->equipment); } ThisAuras::ThisAuras(int auras) { comparisonCriterion = auras; } int ThisAuras::match(MTGCardInstance * card) { return matchValue(card->auras); } ThisOpponentDamageAmount::ThisOpponentDamageAmount(int damagecount) { comparisonCriterion = damagecount; } int ThisOpponentDamageAmount::match(MTGCardInstance * card) { return matchValue(card->controller()->opponent()->damageCount); } ThisUntapped::ThisUntapped(int untapped) { comparisonCriterion = untapped; } int ThisUntapped::match(MTGCardInstance * card) { return matchValue(!card->isTapped()); } ThisTapped::ThisTapped(int tapped) { comparisonCriterion = tapped; } int ThisTapped::match(MTGCardInstance * card) { return matchValue(card->isTapped()); } ThisAttacked::ThisAttacked(int attack) { comparisonCriterion = attack; } int ThisAttacked::match(MTGCardInstance * card) { return matchValue(card->didattacked); } ThisBlocked::ThisBlocked(int block) { comparisonCriterion = block; } int ThisBlocked::match(MTGCardInstance * card) { return matchValue(card->didblocked); } ThisNotBlocked::ThisNotBlocked(int unblocked) { comparisonCriterion = unblocked; } int ThisNotBlocked::match(MTGCardInstance * card) { return matchValue(card->notblocked); } ThisDamaged::ThisDamaged(int wasDealtDamage) { comparisonCriterion = wasDealtDamage; } int ThisDamaged::match(MTGCardInstance * card) { int result = 0; if(card->wasDealtDamage) result = 1; return matchValue(result); } ThisToughness::ThisToughness(int toughness) { comparisonCriterion = toughness; } int ThisToughness::match(MTGCardInstance * card) { return matchValue(card->toughness); } ThisCounterAny::ThisCounterAny(int nb) { comparisonCriterion = nb; } int ThisCounterAny::match(MTGCardInstance * card) { int result = 0; for (int i = 0; i < card->counters->mCount; i++) { result += card->counters->counters[i]->nb; } return matchValue(result); } ThisX::ThisX(int x) { comparisonCriterion = x; } int ThisX::match(MTGCardInstance * card) { return matchValue(card->X); }