Files
wagic/projects/mtg/src/MTGPack.cpp
T
wrenczes d5f3e4cfea Enabled precompiled headers for the build. This cuts the win compile time in debug by at least half on my laptop; on the psp compile, it shaves it down by ~ 45 seconds. I only did a cursory inspection of what to add to PrecompiledHeader.h, there's probably more that we can throw in there for more incremental speed improvements.
Also fixed the project includes so that we don't need to always use the indirect include path, ie:
#include "../include/foo.h" -> #include "foo.h"

I'm don't know much about make files - if I busted the linux build, mea culpa, but I think we're okay on that front too.  For future reference, here's the most straightforward link on the topic of adding pch support to make files:

http://www.mercs-eng.com/~hulud/index.php?2008/06/13/6-writing-a-good-makefile-for-a-c-project
2010-10-24 05:55:24 +00:00

309 lines
8.8 KiB
C++

#include "PrecompiledHeader.h"
#include <JGui.h>
#include <dirent.h>
#include "GameApp.h"
#include "Translate.h"
#include "WDataSrc.h"
#include "WFilter.h"
#include "DeckDataWrapper.h"
#include "MTGPack.h"
#include "../../../JGE/src/tinyxml/tinyxml.h"
MTGPack MTGPacks::defaultBooster;
int MTGPackEntryRandom::addCard(WSrcCards *pool, MTGDeck *to){
int fails = 0;
if(!pool) return 1;
WCFilterFactory * ff = WCFilterFactory::GetInstance();
WCardFilter * oldf = pool->unhookFilters();
pool->addFilter(ff->Construct(filter));
fails = pool->addRandomCards(to,copies);
pool->clearFilters();
pool->addFilter(oldf);
return fails;
}
int MTGPackEntrySpecific::addCard(WSrcCards *pool, MTGDeck *to){
int fails = 0;
//Ignores pool entirely.
MTGAllCards * ac = GameApp::collection;
if(!card) return copies;
for(int i=0;i<copies;i++)
to->add(card);
return 0;
}
int MTGPackSlot::add(WSrcCards * ocean, MTGDeck *to, int carryover){
if(!entries.size()) return copies;
int fails = 0;
int amt = copies + carryover;
WSrcCards * myPool = NULL;
if(pool.size()) myPool = MTGPack::getPool(pool);
if(!myPool) myPool = ocean;
for(int i=0;i<amt;i++){
size_t pos = rand() % entries.size();
while(pos < entries.size() && entries[pos]->addCard(myPool,to))
pos++;
if(pos == entries.size())
fails++;
}
if(myPool != ocean)
SAFE_DELETE(myPool);
return fails;
}
WSrcCards * MTGPack::getPool(string poolstr){
WSrcCards * mySrc = NULL;
size_t s = poolstr.find("all");
WCFilterFactory * ff = WCFilterFactory::GetInstance();
if(s == string::npos){ //Default to just unlocked cards
mySrc = NEW WSrcUnlockedCards();
s = poolstr.find("unlocked");
string sub = poolstr;
if(s != string::npos) sub = poolstr.substr(s+8);
if(sub.size()){
mySrc->addFilter(ff->Construct(sub));
mySrc->bakeFilters();
}
}
else{ //Use everything.
mySrc = NEW WSrcCards();
string sub = poolstr.substr(s+3);
if(sub.size()){
mySrc->addFilter(ff->Construct(sub));
mySrc->loadMatches(GameApp::collection);
mySrc->bakeFilters();
}else
mySrc->loadMatches(GameApp::collection);
}
mySrc->Shuffle();
return mySrc;
}
void MTGPackSlot::addEntry(MTGPackEntry*item){
if(item)
entries.push_back(item);
}
int MTGPack::assemblePack(MTGDeck *to){
int carryover = 0;
WSrcCards * p = getPool(pool);
if(!p) return -1;
p->Shuffle();
for(size_t i=0;i<slotss.size();i++){
carryover = slotss[i]->add(p,to,carryover);
if(carryover > 0)
carryover = carryover; //This means we're failing.
}
SAFE_DELETE(p);
return carryover;
}
void MTGPack::countCards(){
minCards = 0;
maxCards = 0;
for(size_t i=0;i<slotss.size();i++){
MTGPackSlot * ps = slotss[i];
int top = 0;
int bot = 999999999;
for(size_t y=0;y<ps->entries.size();y++){
int test = ps->entries[y]->copies * ps->copies;
if(test > top) top = test;
if(test < bot) bot = test;
}
maxCards += top;
minCards += bot;
}
}
void MTGPack::load(string filename){
//TODO Placeholder until XML format available.
TiXmlDocument packfile(filename.c_str());
if(!packfile.LoadFile())
return;
TiXmlHandle hDoc(&packfile);
TiXmlElement * pPack;
pPack = hDoc.FirstChildElement().Element();
if(!pPack ){
return;
}
//root should be "pack"
string tag = pPack->Value();
std::transform(tag.begin(),tag.end(),tag.begin(),::tolower);
if(tag != "pack")
return;
//After validating, handle actual loading.
TiXmlElement * pSlot;
const char * holder = NULL;
holder = pPack->Attribute("price");
if(holder) price = atoi(holder); else price = Constants::PRICE_BOOSTER;
holder = pPack->Attribute("pool");
if(holder) pool = holder; else pool = "";
holder = pPack->Attribute("type");
if(holder){
type = holder;
}else type = "Booster";
holder = pPack->Attribute("name");
if(holder) name = holder; else name = "Special";
holder = pPack->Attribute("requires");
if(holder) check = holder;
holder = pPack->Attribute("sort");
if(holder) sort = holder; else sort = "";
std::transform(sort.begin(),sort.end(),sort.begin(),::tolower);
for (pSlot=pPack->FirstChildElement();pSlot!=NULL;pSlot=pSlot->NextSiblingElement()){
TiXmlElement * pEntry;
//Load slot.
tag = pSlot->Value();
std::transform(tag.begin(),tag.end(),tag.begin(),::tolower);
if(tag != "slot") continue;
MTGPackSlot * s = NEW MTGPackSlot();
slotss.push_back(s);
holder = pSlot->Attribute("copies");
if(holder) s->copies = atoi(holder);
else s->copies = 1;
holder = pSlot->Attribute("pool");
if(holder) s->pool = holder;
for(pEntry = pSlot->FirstChildElement();pEntry!=NULL;pEntry=pEntry->NextSiblingElement()){
tag = pEntry->Value();
std::transform(tag.begin(),tag.end(),tag.begin(),::tolower);
if(tag == "card"){ //Load specific card
MTGPackEntrySpecific * es = NEW MTGPackEntrySpecific();
holder = pEntry->Attribute("copies");
if(holder) es->copies = atoi(holder);
else es->copies = 1;
es->card = GameApp::collection->getCardByName(pEntry->Value());
s->addEntry(es);
}else if(tag == "random_card"){ //Load random card
MTGPackEntryRandom * er = NEW MTGPackEntryRandom();
holder = pEntry->Attribute("copies");
if(holder) er->copies = atoi(holder);
else er->copies = 1;
const char * text = pEntry->GetText();
if(text) er->filter = text;
s->addEntry(er);
}else if(tag == "nothing"){
MTGPackEntryNothing * nt = NEW MTGPackEntryNothing();
s->addEntry(nt);
}
}
}
bValid = true;
countCards();
return;
}
MTGPackSlot::~MTGPackSlot(){
for(size_t t=0;t<entries.size();t++){
SAFE_DELETE(entries[t]);
}
entries.clear();
}
MTGPack::~MTGPack(){
for(size_t t=0;t<slotss.size();t++){
SAFE_DELETE(slotss[t]);
}
slotss.clear();
}
MTGPacks::~MTGPacks(){
for(size_t t=0;t<packs.size();t++){
SAFE_DELETE(packs[t]);
}
packs.clear();
}
MTGPack * MTGPacks::randomPack(int key){
if(!key) key = rand();
size_t s = packs.size();
if(!s) return NULL;
return packs[key%s];
}
void MTGPacks::loadAll(){
DIR *mDip = opendir(RESPATH"/packs/");
struct dirent *mDit;
if(!mDip) return;
while ((mDit = readdir(mDip))){
char myFilename[4096];
sprintf(myFilename, RESPATH"/packs/%s", mDit->d_name);
if(mDit->d_name[0] == '.') continue;
if(!strcmp(mDit->d_name,"default_booster.txt")) continue;
MTGPack * p = NEW MTGPack(myFilename);
if(!p->isValid()){
SAFE_DELETE(p);
continue;
}
packs.push_back(p);
}
closedir(mDip);
}
string MTGPack::getName(){
string n = _(name);
string t = _(type);
char buf[1024];
if(minCards != maxCards)
sprintf(buf,"%s %s (%i-%i cards)",n.c_str(),t.c_str(),minCards,maxCards);
else
sprintf(buf,"%s %s (%i cards)",n.c_str(),t.c_str(),maxCards);
return buf;
}
bool MTGPack::meetsRequirements(){
bool unlocked = true;
WCFilterFactory * ff = WCFilterFactory::GetInstance();
WSrcCards * myC = getPool(pool);
if(!myC || myC->Size() < maxCards) unlocked = false; //Top pool lacks cards.
SAFE_DELETE(myC);
if(!check.size() || !unlocked) return unlocked;
myC = NEW WSrcUnlockedCards(); //Requirements are independent of pool;
WCardFilter * cf = ff->Construct(check);
unlocked = !myC->isEmptySet(cf); //Quick check for empty set status.
SAFE_DELETE(cf); //delete requirement filter
SAFE_DELETE(myC); //delete pool.
return unlocked;
}
bool MTGPack::isUnlocked(){
if(unlockStatus == 0){
if(meetsRequirements())
unlockStatus = 1;
else
unlockStatus = -1;
}
return (unlockStatus > 0);
}
MTGPack * MTGPacks::getDefault(){
if(!defaultBooster.isValid()){
defaultBooster.load(RESPATH"/packs/default_booster.txt");
defaultBooster.unlockStatus = 1;
if(!defaultBooster.isValid()){
MTGPackSlot * ps = NEW MTGPackSlot(); ps->copies = 1;
ps->addEntry(NEW MTGPackEntryRandom("rarity:mythic;"));
for(int i=0;i<7;i++)
ps->addEntry(NEW MTGPackEntryRandom("rarity:rare;"));
defaultBooster.slotss.push_back(ps);
ps = NEW MTGPackSlot(); ps->copies = 3;
ps->addEntry(NEW MTGPackEntryRandom("rarity:uncommon;"));
defaultBooster.slotss.push_back(ps);
ps = NEW MTGPackSlot(); ps->copies = 1;
ps->addEntry(NEW MTGPackEntryRandom("rarity:land;&type:basic;"));
defaultBooster.slotss.push_back(ps);
ps = NEW MTGPackSlot(); ps->copies = 10;
ps->addEntry(NEW MTGPackEntryRandom("rarity:common;"));
defaultBooster.slotss.push_back(ps);
defaultBooster.bValid = true;
defaultBooster.unlockStatus = 1;
}
}
return &defaultBooster;
}
void MTGPacks::refreshUnlocked(){
for(size_t t=0;t<packs.size();t++){
if(packs[t]->unlockStatus < 0)
packs[t]->unlockStatus = 0;
}
}