Files
wagic/projects/mtg/src/ThisDescriptor.cpp
omegablast2002@yahoo.com 9d52e4547e fixed a parsing error with tokengen, no actually my fault :P there was never a check if the end was the real end or not.
2nd, added this(blocking) in hopes to fix mogg flunkies and similar creatures.
2011-04-14 17:06:44 +00:00

531 lines
11 KiB
C++

#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);
}