Reducing the memory footprint: reworked the concept of 'colors' in CardPrimitives. What used to be an array of ints (ie 28 bytes) is now contained in a single byte, we use bit masking to support setting multiple colors on this variable. This also eliminates a lot of silly loops for setting colors in the code - now it's a straight byte copy.
Also thrown in are a couple of string to const string& conversions.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#define CD_OR 1
|
||||
#define CD_AND 2
|
||||
#define CD_NOT 3
|
||||
|
||||
enum ENUM_COMPARISON_MODES
|
||||
{
|
||||
@@ -23,10 +24,12 @@ enum ENUM_COMPARISON_MODES
|
||||
COMPARISON_UNEQUAL
|
||||
};
|
||||
|
||||
class CardDescriptor: public MTGCardInstance{
|
||||
class CardDescriptor: public MTGCardInstance
|
||||
{
|
||||
protected:
|
||||
MTGCardInstance * match_or(MTGCardInstance * card);
|
||||
MTGCardInstance * match_and(MTGCardInstance * card);
|
||||
MTGCardInstance * match_or(MTGCardInstance * card);
|
||||
MTGCardInstance * match_and(MTGCardInstance * card);
|
||||
MTGCardInstance * match_not(MTGCardInstance * card);
|
||||
bool valueInRange(int comparisonMode, int value, int criterion);
|
||||
public:
|
||||
int mode;
|
||||
|
||||
@@ -11,6 +11,15 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
const uint8_t kColorBitMask_Artifact = 0x01;
|
||||
const uint8_t kColorBitMask_Green = 0x02;
|
||||
const uint8_t kColorBitMask_Blue = 0x04;
|
||||
const uint8_t kColorBitMask_Red = 0x08;
|
||||
const uint8_t kColorBitMask_Black = 0x10;
|
||||
const uint8_t kColorBitMask_White = 0x20;
|
||||
const uint8_t kColorBitMask_Land = 0x40;
|
||||
|
||||
|
||||
class CardPrimitive
|
||||
#ifdef TRACK_OBJECT_USAGE
|
||||
: public InstanceCounter<CardPrimitive>
|
||||
@@ -25,7 +34,7 @@ public:
|
||||
string name;
|
||||
int init();
|
||||
|
||||
int colors[Constants::MTG_NB_COLORS];
|
||||
uint8_t colors;
|
||||
map<int,int> basicAbilities;
|
||||
map<string,string> magicTexts;
|
||||
string magicText;
|
||||
@@ -44,10 +53,10 @@ public:
|
||||
virtual ~CardPrimitive();
|
||||
|
||||
void setColor(int _color, int removeAllOthers = 0);
|
||||
void setColor(string _color, int removeAllOthers = 0);
|
||||
void setColor(const string& _color, int removeAllOthers = 0);
|
||||
void removeColor(int color);
|
||||
int getColor();
|
||||
int hasColor(int _color);
|
||||
bool hasColor(int inColor);
|
||||
int countColors();
|
||||
|
||||
int has(int ability);
|
||||
@@ -70,11 +79,11 @@ public:
|
||||
int removeType(int value, int removeAll = 0);
|
||||
bool hasSubtype(int _subtype);
|
||||
bool hasSubtype(const char * _subtype);
|
||||
bool hasSubtype(string _subtype);
|
||||
bool hasSubtype(const string& _subtype);
|
||||
bool hasType(int _type);
|
||||
bool hasType(const char * type);
|
||||
|
||||
void setManaCost(string value);
|
||||
void setManaCost(const string& value);
|
||||
ManaCost * getManaCost();
|
||||
bool isCreature();
|
||||
bool isLand();
|
||||
|
||||
@@ -101,6 +101,13 @@ bool CardDescriptor::valueInRange(int comparisonMode, int value, int criterion)
|
||||
return false;
|
||||
}
|
||||
|
||||
MTGCardInstance* CardDescriptor::match_not(MTGCardInstance * card)
|
||||
{
|
||||
// if we have a color match, return null
|
||||
bool colorFound = (colors & card->colors) > 0;
|
||||
return colorFound ? NULL : card;
|
||||
}
|
||||
|
||||
MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card)
|
||||
{
|
||||
int found = 1;
|
||||
@@ -128,27 +135,11 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card)
|
||||
if (!found)
|
||||
return NULL;
|
||||
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
|
||||
if (colors)
|
||||
{
|
||||
if (colors[i] == 1)
|
||||
{
|
||||
found = 0;
|
||||
if (card->hasColor(i))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (colors[i] == -1)
|
||||
{
|
||||
found = 0;
|
||||
if (!card->hasColor(i))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
found = (colors & card->colors);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return NULL;
|
||||
|
||||
@@ -184,13 +175,8 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
|
||||
{
|
||||
if ((colors[i] == 1 && !card->hasColor(i)) || (colors[i] == -1 && card->hasColor(i)))
|
||||
{
|
||||
match = NULL;
|
||||
}
|
||||
}
|
||||
if ((colors & card->colors) != colors)
|
||||
match = NULL;
|
||||
|
||||
if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power))
|
||||
match = NULL;
|
||||
@@ -200,21 +186,7 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card)
|
||||
match = NULL;
|
||||
if(nameComparisonMode && compareName != card->name)
|
||||
match = NULL;
|
||||
if(colorComparisonMode)
|
||||
{
|
||||
bool hasMatch = false;
|
||||
for (int i=0;i< Constants::MTG_NB_COLORS;i++)
|
||||
{
|
||||
if (card->hasColor(i) && colors[i] > 0)
|
||||
{
|
||||
hasMatch = true;
|
||||
}
|
||||
}
|
||||
if( !hasMatch )
|
||||
{
|
||||
match = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
@@ -226,10 +198,14 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card)
|
||||
{
|
||||
match = match_and(card);
|
||||
}
|
||||
else
|
||||
else if (mode == CD_OR)
|
||||
{
|
||||
match = match_or(card);
|
||||
}
|
||||
else
|
||||
{
|
||||
match = match_not(card);
|
||||
}
|
||||
|
||||
//Abilities
|
||||
for (map<int, int>::const_iterator it = basicAbilities.begin(); it != basicAbilities.end(); ++it)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "MTGDefinitions.h"
|
||||
#include "CardPrimitive.h"
|
||||
|
||||
#include "MTGDeck.h"
|
||||
@@ -8,9 +9,68 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace
|
||||
{
|
||||
uint8_t ConvertColorToBitMask(int inColor)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
switch (inColor)
|
||||
{
|
||||
case Constants::MTG_COLOR_ARTIFACT:
|
||||
value = kColorBitMask_Artifact;
|
||||
break;
|
||||
|
||||
case Constants::MTG_COLOR_GREEN:
|
||||
value = kColorBitMask_Green;
|
||||
break;
|
||||
|
||||
case Constants::MTG_COLOR_BLUE:
|
||||
value = kColorBitMask_Blue;
|
||||
break;
|
||||
|
||||
case Constants::MTG_COLOR_RED:
|
||||
value = kColorBitMask_Red;
|
||||
break;
|
||||
|
||||
case Constants::MTG_COLOR_BLACK:
|
||||
value = kColorBitMask_Black;
|
||||
break;
|
||||
|
||||
case Constants::MTG_COLOR_WHITE:
|
||||
value = kColorBitMask_White;
|
||||
break;
|
||||
|
||||
case Constants::MTG_COLOR_LAND:
|
||||
value = kColorBitMask_Land;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
** Count the number of set bits in a given integer
|
||||
*/
|
||||
int CountSetBits(int n)
|
||||
{
|
||||
int count = 0;
|
||||
while (n)
|
||||
{
|
||||
n &= (n-1);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SUPPORT_OBJECT_ANALYTICS(CardPrimitive)
|
||||
|
||||
CardPrimitive::CardPrimitive()
|
||||
: colors(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -22,8 +82,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
|
||||
|
||||
for (size_t i = 0; i < source->types.size(); ++i)
|
||||
types.push_back(source->types[i]);
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i)
|
||||
colors[i] = source->colors[i];
|
||||
colors = source->colors;
|
||||
manaCost.copy(source->getManaCost());
|
||||
//reducedCost.copy(source->getReducedManaCost());
|
||||
//increasedCost.copy(source->getIncreasedManaCost());
|
||||
@@ -56,9 +115,6 @@ int CardPrimitive::init()
|
||||
|
||||
types.clear();
|
||||
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i)
|
||||
colors[i] = 0;
|
||||
|
||||
magicText = "";
|
||||
magicTexts.clear();
|
||||
spellTargetType = "";
|
||||
@@ -102,17 +158,17 @@ void CardPrimitive::getOtherRestrictions()
|
||||
otherrestriction;
|
||||
}
|
||||
|
||||
void CardPrimitive::setColor(string _color, int removeAllOthers)
|
||||
void CardPrimitive::setColor(const string& _color, int removeAllOthers)
|
||||
{
|
||||
if (_color.compare("blue") == 0)
|
||||
if (_color.compare(Constants::kManaBlue) == 0)
|
||||
return setColor(Constants::MTG_COLOR_BLUE, removeAllOthers);
|
||||
if (_color.compare("red") == 0)
|
||||
if (_color.compare(Constants::kManaRed) == 0)
|
||||
return setColor(Constants::MTG_COLOR_RED, removeAllOthers);
|
||||
if (_color.compare("green") == 0)
|
||||
if (_color.compare(Constants::kManaGreen) == 0)
|
||||
return setColor(Constants::MTG_COLOR_GREEN, removeAllOthers);
|
||||
if (_color.compare("black") == 0)
|
||||
if (_color.compare(Constants::kManaBlack) == 0)
|
||||
return setColor(Constants::MTG_COLOR_BLACK, removeAllOthers);
|
||||
if (_color.compare("white") == 0)
|
||||
if (_color.compare(Constants::kManaWhite) == 0)
|
||||
return setColor(Constants::MTG_COLOR_WHITE, removeAllOthers);
|
||||
if (_color.compare("artifact") == 0)
|
||||
return setColor(Constants::MTG_COLOR_ARTIFACT, removeAllOthers);
|
||||
@@ -121,39 +177,43 @@ void CardPrimitive::setColor(string _color, int removeAllOthers)
|
||||
void CardPrimitive::setColor(int _color, int removeAllOthers)
|
||||
{
|
||||
if (removeAllOthers)
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
|
||||
colors[i] = 0;
|
||||
colors[_color] = 1;
|
||||
colors = 0;
|
||||
|
||||
colors |= ConvertColorToBitMask(_color);
|
||||
}
|
||||
|
||||
void CardPrimitive::removeColor(int _color)
|
||||
{
|
||||
colors[_color] = 0;
|
||||
uint8_t mask = ~ConvertColorToBitMask(_color);
|
||||
colors &= mask;
|
||||
}
|
||||
|
||||
int CardPrimitive::getColor()
|
||||
{
|
||||
for (int i = 1; i < Constants::MTG_NB_COLORS; i++)
|
||||
if (colors[i])
|
||||
return i;
|
||||
if (colors)
|
||||
{
|
||||
for (int i = 1; i < Constants::MTG_NB_COLORS; i++)
|
||||
if (hasColor(i))
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CardPrimitive::hasColor(int color)
|
||||
bool CardPrimitive::hasColor(int inColor)
|
||||
{
|
||||
return (colors[color]);
|
||||
return (colors & ConvertColorToBitMask(inColor)) > 0;
|
||||
}
|
||||
|
||||
int CardPrimitive::countColors()
|
||||
{
|
||||
int result = 0;
|
||||
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||
if (hasColor(i))
|
||||
++result;
|
||||
return result;
|
||||
uint8_t mask = kColorBitMask_Green | kColorBitMask_Blue | kColorBitMask_Red | kColorBitMask_Black | kColorBitMask_White;
|
||||
mask &= colors;
|
||||
|
||||
return CountSetBits(mask);
|
||||
}
|
||||
|
||||
void CardPrimitive::setManaCost(string s)
|
||||
void CardPrimitive::setManaCost(const string& s)
|
||||
{
|
||||
ManaCost::parseManaCost(s, &manaCost);
|
||||
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; i++)
|
||||
@@ -163,7 +223,6 @@ void CardPrimitive::setManaCost(string s)
|
||||
setColor(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CardPrimitive::setType(const string& _type_text)
|
||||
@@ -290,7 +349,7 @@ bool CardPrimitive::hasSubtype(const char * _subtype)
|
||||
return hasType(id);
|
||||
}
|
||||
|
||||
bool CardPrimitive::hasSubtype(string _subtype)
|
||||
bool CardPrimitive::hasSubtype(const string& _subtype)
|
||||
{
|
||||
int id = Subtypes::subtypesList->find(_subtype);
|
||||
return hasType(id);
|
||||
|
||||
@@ -3113,8 +3113,7 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
|
||||
card->setColor(0,1);
|
||||
card->name = card->model->data->name;
|
||||
card->types = card->model->data->types;
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i)
|
||||
card->colors[i] = card->model->data->colors[i];
|
||||
card->colors = card->model->data->colors;
|
||||
for (map<int, int>::const_iterator it = card->model->data->basicAbilities.begin(); it != card->model->data->basicAbilities.end(); ++it)
|
||||
{
|
||||
int i = it->first;
|
||||
|
||||
@@ -62,10 +62,9 @@ void MTGCardInstance::copy(MTGCardInstance * card)
|
||||
{
|
||||
types.push_back(data->types[i]);
|
||||
}
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
|
||||
{
|
||||
colors[i] = data->colors[i];
|
||||
}
|
||||
|
||||
colors = data->colors;
|
||||
|
||||
manaCost.copy(data->getManaCost());
|
||||
|
||||
text = data->text;
|
||||
@@ -197,32 +196,33 @@ void MTGCardInstance::initMTGCI()
|
||||
}
|
||||
}
|
||||
int colored = 0;
|
||||
|
||||
|
||||
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||
{
|
||||
if (this->hasColor(i))
|
||||
++colored;
|
||||
}
|
||||
if(colored > 1)
|
||||
if (colored > 1)
|
||||
{
|
||||
isMultiColored = 1;
|
||||
|
||||
if(this->hasColor(Constants::MTG_COLOR_WHITE) && this->hasColor(Constants::MTG_COLOR_BLACK))
|
||||
isBlackAndWhite = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_BLUE))
|
||||
isRedAndBlue = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_GREEN) && this->hasColor(Constants::MTG_COLOR_BLACK))
|
||||
isBlackAndGreen = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_BLUE) && this->hasColor(Constants::MTG_COLOR_GREEN))
|
||||
isBlueAndGreen = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_WHITE))
|
||||
isRedAndWhite = 1;
|
||||
}
|
||||
|
||||
if(previous && previous->morphed && !turningOver)
|
||||
{
|
||||
morphed = true;
|
||||
isMorphed = true;
|
||||
}
|
||||
|
||||
if(this->hasColor(Constants::MTG_COLOR_WHITE) && this->hasColor(Constants::MTG_COLOR_BLACK))
|
||||
isBlackAndWhite = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_BLUE))
|
||||
isRedAndBlue = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_GREEN) && this->hasColor(Constants::MTG_COLOR_BLACK))
|
||||
isBlackAndGreen = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_BLUE) && this->hasColor(Constants::MTG_COLOR_GREEN))
|
||||
isBlueAndGreen = 1;
|
||||
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_WHITE))
|
||||
isRedAndWhite = 1;
|
||||
if(previous && previous->morphed && !turningOver)
|
||||
{
|
||||
morphed = true;
|
||||
isMorphed = true;
|
||||
}
|
||||
}
|
||||
|
||||
const string MTGCardInstance::getDisplayName() const
|
||||
|
||||
@@ -507,13 +507,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
}
|
||||
else if( CDtype.find("color") != string::npos )
|
||||
{
|
||||
for(int i = 0; i < Constants::MTG_NB_COLORS; i++)
|
||||
{
|
||||
if(card->target)
|
||||
cd->colors[i] = card->target->colors[i];
|
||||
else
|
||||
cd->colors[i] = card->colors[i];
|
||||
}
|
||||
if(card->target)
|
||||
cd->colors = card->target->colors;
|
||||
else
|
||||
cd->colors = card->colors;
|
||||
|
||||
cd->mode = CD_OR;
|
||||
}
|
||||
else if( CDtype.find("types") != string::npos )
|
||||
@@ -571,20 +569,17 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
else
|
||||
{
|
||||
int attributefound = 0;
|
||||
//Colors
|
||||
//Colors - remove Artifact and Land from the loop
|
||||
for (int cid = 1; cid < Constants::MTG_NB_COLORS - 1; cid++)
|
||||
{ //remove Artifact and Land from the loop
|
||||
{
|
||||
if (attribute.find(Constants::MTGColorStrings[cid]) != string::npos)
|
||||
{
|
||||
attributefound = 1;
|
||||
if (minus)
|
||||
{
|
||||
cd->colors[cid] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cd->colors[cid] = 1;
|
||||
cd->mode = CD_NOT;
|
||||
}
|
||||
cd->setColor(cid);
|
||||
}
|
||||
}
|
||||
if (!attributefound)
|
||||
@@ -621,7 +616,8 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nbminuses) cd->mode = CD_AND;
|
||||
if (nbminuses && cd->mode != CD_NOT)
|
||||
cd->mode = CD_AND;
|
||||
typeName = typeName.substr(0, found);
|
||||
}
|
||||
//X targets allowed ?
|
||||
|
||||
@@ -211,7 +211,7 @@ string WCFilterSet::getCode()
|
||||
bool WCFilterColor::isMatch(MTGCard * c)
|
||||
{
|
||||
if (!c || !c->data) return false;
|
||||
return (c->data->hasColor(color) > 0);
|
||||
return (c->data->hasColor(color));
|
||||
}
|
||||
string WCFilterColor::getCode()
|
||||
{
|
||||
@@ -242,9 +242,9 @@ bool WCFilterOnlyColor::isMatch(MTGCard * c)
|
||||
for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
|
||||
{
|
||||
if (i == color) continue;
|
||||
if (c->data->hasColor(i) > 0) return false;
|
||||
if (c->data->hasColor(i)) return false;
|
||||
}
|
||||
return (c->data->hasColor(color) > 0);
|
||||
return (c->data->hasColor(color));
|
||||
}
|
||||
string WCFilterOnlyColor::getCode()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user