Implemented a lazy load pattern for the deck stats - when the DeckMenu is displaying decks, it calls LoadStats() for only the ones visible in the list. This helps reduces the lag that occurs each time we attempt to load all the AI decks during match selection.
This still could be improved - DeckMetaData's constructor loads an MTGDeck object to parse out the name of a deck from its file. This means that we crack open 106 files on the first attempt to show the list of opponent decks. I started optimizing this, but reverted, as the list itself is sorted alphabetically. Currently, with these mods, it's still taking 4 1/2 seconds on my psp to load the opponent list on the first go around. While at it, did some cleanup - removed the need for passing around a player pointer in some of the DeckStat functions, etc.
This commit is contained in:
@@ -17,20 +17,21 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
vector<DeckMetaData *> playerDeckOrderList;
|
vector<DeckMetaData*> playerDeckOrderList;
|
||||||
vector<DeckMetaData *> aiDeckOrderList;
|
vector<DeckMetaData*> aiDeckOrderList;
|
||||||
|
|
||||||
map<string, StatsWrapper *> playerDeckStatsMap;
|
map<string, StatsWrapper*> playerDeckStatsMap;
|
||||||
map<string, StatsWrapper *> aiDeckStatsMap;
|
map<string, StatsWrapper*> aiDeckStatsMap;
|
||||||
|
|
||||||
void updateMetaDataList(vector<DeckMetaData *>* refList, bool isAI);
|
void updateMetaDataList(vector<DeckMetaData*>* refList, bool isAI);
|
||||||
vector<DeckMetaData *> * getPlayerDeckOrderList();
|
vector<DeckMetaData*> * getPlayerDeckOrderList();
|
||||||
vector<DeckMetaData *> * getAIDeckOrderList();
|
vector<DeckMetaData*> * getAIDeckOrderList();
|
||||||
|
|
||||||
DeckMetaData * getDeckMetaDataById( int deckId, bool isAI );
|
DeckMetaData* getDeckMetaDataById(int deckId, bool isAI);
|
||||||
StatsWrapper * getExtendedStatsForDeckId( int deckId, MTGAllCards *collection, bool isAI );
|
DeckMetaData* getDeckMetaDataByFilename(const std::string& filename, bool isAI);
|
||||||
StatsWrapper * getExtendedDeckStats( DeckMetaData *selectedDeck, MTGAllCards *collection, bool isAI );
|
StatsWrapper* getExtendedStatsForDeckId(int deckId, MTGAllCards* collection, bool isAI);
|
||||||
static DeckManager * GetInstance();
|
StatsWrapper* getExtendedDeckStats(DeckMetaData* selectedDeck, MTGAllCards* collection, bool isAI);
|
||||||
|
static DeckManager* GetInstance();
|
||||||
static void EndInstance();
|
static void EndInstance();
|
||||||
|
|
||||||
//convenience method to get the difficulty rating between two decks. This should be refined a little more
|
//convenience method to get the difficulty rating between two decks. This should be refined a little more
|
||||||
|
|||||||
@@ -17,22 +17,21 @@ enum DECK_DIFFICULTY
|
|||||||
class DeckMetaData
|
class DeckMetaData
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
string _filename;
|
string mFilename;
|
||||||
|
string mDescription;
|
||||||
string _desc;
|
string mName;
|
||||||
string _name;
|
int mDeckId;
|
||||||
int _deckid;
|
string mAvatarFilename;
|
||||||
string _avatarFilename;
|
|
||||||
|
|
||||||
// statistical information
|
// statistical information
|
||||||
|
int mGamesPlayed, mVictories, mPercentVictories, mDifficulty;
|
||||||
|
|
||||||
int _nbGamesPlayed, _victories, _percentVictories, _difficulty;
|
DeckMetaData();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeckMetaData();
|
DeckMetaData(const string& filename);
|
||||||
DeckMetaData(string filename, Player * statsPlayer);
|
void LoadDeck();
|
||||||
void load(string filename);
|
void LoadStats();
|
||||||
void loadStatsForPlayer(Player * statsPlayer, string deckStatsFileName = "");
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
string getFilename();
|
string getFilename();
|
||||||
@@ -49,6 +48,13 @@ public:
|
|||||||
int getDifficulty();
|
int getDifficulty();
|
||||||
string getDifficultyString();
|
string getDifficultyString();
|
||||||
|
|
||||||
|
void Invalidate();
|
||||||
|
|
||||||
|
string mStatsFilename;
|
||||||
|
string mPlayerDeck;
|
||||||
|
bool mDeckLoaded;
|
||||||
|
bool mStatsLoaded;
|
||||||
|
bool mIsAI;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeckMetaDataList
|
class DeckMetaDataList
|
||||||
@@ -58,10 +64,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void invalidate(string filename);
|
void invalidate(string filename);
|
||||||
DeckMetaData * get(string filename, Player * statsPlayer = NULL);
|
DeckMetaData * get(string filename);
|
||||||
~DeckMetaDataList();
|
~DeckMetaDataList();
|
||||||
static DeckMetaDataList * decksMetaData;
|
static DeckMetaDataList * decksMetaData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,11 +34,9 @@ public:
|
|||||||
static DeckStats * GetInstance();
|
static DeckStats * GetInstance();
|
||||||
static void EndInstance();
|
static void EndInstance();
|
||||||
void saveStats(Player * player, Player * opponent, GameObserver * game);
|
void saveStats(Player * player, Player * opponent, GameObserver * game);
|
||||||
void save(const char * filename);
|
void save(const std::string& filename);
|
||||||
void save(Player * player);
|
void load(const std::string& filename);
|
||||||
void load(const char * filename);
|
|
||||||
void load(Player * player);
|
|
||||||
void cleanStats();
|
|
||||||
~DeckStats();
|
~DeckStats();
|
||||||
int percentVictories(string opponentsDeckFile);
|
int percentVictories(string opponentsDeckFile);
|
||||||
int percentVictories();
|
int percentVictories();
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
static vector<DeckMetaData *> fillDeckMenu(DeckMenu * _menu, const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL, int maxDecks = 0);
|
static vector<DeckMetaData *> fillDeckMenu(DeckMenu * _menu, const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL, int maxDecks = 0);
|
||||||
|
|
||||||
// build a vector of decks with the information passsed in.
|
// build a vector of decks with the information passsed in.
|
||||||
static vector<DeckMetaData *> getValidDeckMetaData(const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL, int maxDecks = 0);
|
static vector<DeckMetaData *> BuildDeckList(const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL, int maxDecks = 0);
|
||||||
|
|
||||||
// build menu items based on the vector<DeckMetaData *>
|
// build menu items based on the vector<DeckMetaData *>
|
||||||
static void renderDeckMenu(SimpleMenu * _menu, const vector<DeckMetaData *>& deckMetaDataList);
|
static void renderDeckMenu(SimpleMenu * _menu, const vector<DeckMetaData *>& deckMetaDataList);
|
||||||
|
|||||||
@@ -90,8 +90,6 @@ private:
|
|||||||
float mSlide;
|
float mSlide;
|
||||||
int mAlpha;
|
int mAlpha;
|
||||||
int mStage;
|
int mStage;
|
||||||
int nbDecks;
|
|
||||||
int deckNum;
|
|
||||||
int useFilter;
|
int useFilter;
|
||||||
JMusic * bgMusic;
|
JMusic * bgMusic;
|
||||||
JQuad * backQuad;
|
JQuad * backQuad;
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadAvatar(string file);
|
void loadAvatar(string file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Returns the path to the stats file of currently selected deck.
|
||||||
|
*/
|
||||||
|
std::string GetCurrentDeckStatsFile();
|
||||||
};
|
};
|
||||||
|
|
||||||
class HumanPlayer: public Player
|
class HumanPlayer: public Player
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
|
|||||||
if (unlocked == -1)
|
if (unlocked == -1)
|
||||||
{
|
{
|
||||||
DeckStats * stats = DeckStats::GetInstance();
|
DeckStats * stats = DeckStats::GetInstance();
|
||||||
stats->load(p1);
|
stats->load(p1->GetCurrentDeckStatsFile());
|
||||||
unlocked = isDifficultyUnlocked(stats);
|
unlocked = isDifficultyUnlocked(stats);
|
||||||
if (unlocked)
|
if (unlocked)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,6 +55,38 @@ DeckMetaData* DeckManager::getDeckMetaDataById( int deckId, bool isAI )
|
|||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Predicate helper for getDeckMetadataByFilename()
|
||||||
|
*/
|
||||||
|
struct DeckFilenameMatch
|
||||||
|
{
|
||||||
|
DeckFilenameMatch(const std::string& filename) : mFilename(filename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (DeckMetaData* inPtr)
|
||||||
|
{
|
||||||
|
return inPtr->getFilename() == mFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mFilename;
|
||||||
|
};
|
||||||
|
|
||||||
|
DeckMetaData* DeckManager::getDeckMetaDataByFilename(const string& filename, bool isAI)
|
||||||
|
{
|
||||||
|
DeckMetaData* deck = NULL;
|
||||||
|
std::vector<DeckMetaData *>& deckList = isAI ? aiDeckOrderList : playerDeckOrderList;
|
||||||
|
|
||||||
|
std::vector<DeckMetaData *>::iterator pos = find_if(deckList.begin(), deckList.end(), DeckFilenameMatch(filename));
|
||||||
|
if (pos != deckList.end())
|
||||||
|
{
|
||||||
|
deck = *pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return deck;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StatsWrapper * DeckManager::getExtendedStatsForDeckId( int deckId, MTGAllCards *collection, bool isAI )
|
StatsWrapper * DeckManager::getExtendedStatsForDeckId( int deckId, MTGAllCards *collection, bool isAI )
|
||||||
{
|
{
|
||||||
DeckMetaData *selectedDeck = getDeckMetaDataById( deckId, isAI );
|
DeckMetaData *selectedDeck = getDeckMetaDataById( deckId, isAI );
|
||||||
@@ -133,7 +165,7 @@ int DeckManager::getDifficultyRating(Player *statsPlayer, Player *player)
|
|||||||
{
|
{
|
||||||
DeckMetaDataList * metas = DeckMetaDataList::decksMetaData;
|
DeckMetaDataList * metas = DeckMetaDataList::decksMetaData;
|
||||||
|
|
||||||
DeckMetaData *meta = metas->get(player->deckFile, statsPlayer);
|
DeckMetaData *meta = metas->get(player->deckFile);
|
||||||
|
|
||||||
return meta->getDifficulty();
|
return meta->getDifficulty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,12 @@ void DeckMenu::Render()
|
|||||||
DeckMenuItem *currentMenuItem = static_cast<DeckMenuItem*> (mObjects[i]);
|
DeckMenuItem *currentMenuItem = static_cast<DeckMenuItem*> (mObjects[i]);
|
||||||
if (currentMenuItem->mY - kLineHeight * startId < mY + height - kLineHeight + 7)
|
if (currentMenuItem->mY - kLineHeight * startId < mY + height - kLineHeight + 7)
|
||||||
{
|
{
|
||||||
|
// only load stats for visible items in the list
|
||||||
|
if (currentMenuItem->meta)
|
||||||
|
{
|
||||||
|
currentMenuItem->meta->LoadStats();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentMenuItem->hasFocus())
|
if (currentMenuItem->hasFocus())
|
||||||
{
|
{
|
||||||
mSelectedDeckId = i;
|
mSelectedDeckId = i;
|
||||||
|
|||||||
@@ -11,71 +11,74 @@
|
|||||||
|
|
||||||
DeckMetaDataList * DeckMetaDataList::decksMetaData = NEW DeckMetaDataList();
|
DeckMetaDataList * DeckMetaDataList::decksMetaData = NEW DeckMetaDataList();
|
||||||
|
|
||||||
DeckMetaData::DeckMetaData()
|
DeckMetaData::DeckMetaData(const string& filename)
|
||||||
|
: mFilename(filename), mGamesPlayed(0), mVictories(0), mPercentVictories(0), mDifficulty(0),
|
||||||
|
mDeckLoaded(false), mStatsLoaded(false)
|
||||||
{
|
{
|
||||||
|
// TODO, figure out how we can defer this to later - currently,
|
||||||
|
// there's a catch 22, as we sort the deck list alphabetically, so we need to open the deck file
|
||||||
|
// to get its name. This means that for the opponent list, we crack open 106 files just to read the deck name
|
||||||
|
//, which is the bulk of the remaining 4 second delay we see the first time we try to pick an opponent on the first match
|
||||||
|
LoadDeck();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeckMetaData::DeckMetaData(string filename, Player * statsPlayer)
|
void DeckMetaData::LoadStats()
|
||||||
{
|
{
|
||||||
load(filename);
|
if (!mStatsLoaded)
|
||||||
}
|
|
||||||
|
|
||||||
void DeckMetaData::loadStatsForPlayer(Player * statsPlayer, string deckStatsFileName)
|
|
||||||
{
|
|
||||||
DeckStats * stats = DeckStats::GetInstance();
|
|
||||||
_nbGamesPlayed = 0;
|
|
||||||
_percentVictories = 0;
|
|
||||||
_victories = 0;
|
|
||||||
if (statsPlayer)
|
|
||||||
{
|
{
|
||||||
stats->load(statsPlayer);
|
DeckStats * stats = DeckStats::GetInstance();
|
||||||
DeckStat * opponentDeckStats = stats->getDeckStat(deckStatsFileName);
|
if (mIsAI)
|
||||||
if (opponentDeckStats)
|
|
||||||
{
|
{
|
||||||
_percentVictories = stats->percentVictories(deckStatsFileName);
|
stats->load(mPlayerDeck);
|
||||||
_victories = opponentDeckStats->victories;
|
DeckStat * opponentDeckStats = stats->getDeckStat(mStatsFilename);
|
||||||
_nbGamesPlayed = opponentDeckStats->nbgames;
|
if (opponentDeckStats)
|
||||||
ostringstream oss;
|
|
||||||
int deckFilenameOffset = deckStatsFileName.find("deck") + 4;
|
|
||||||
int oppDeckId = atoi(deckStatsFileName.substr(deckFilenameOffset, deckStatsFileName.find_last_of(".")).c_str());
|
|
||||||
int avatarId = getAvatarId(oppDeckId);
|
|
||||||
oss << "avatar" << avatarId << ".jpg";
|
|
||||||
_avatarFilename = oss.str();
|
|
||||||
if (_percentVictories < 34)
|
|
||||||
{
|
{
|
||||||
_difficulty = HARD;
|
mPercentVictories = stats->percentVictories(mStatsFilename);
|
||||||
}
|
mVictories = opponentDeckStats->victories;
|
||||||
else if (_percentVictories < 55)
|
mGamesPlayed = opponentDeckStats->nbgames;
|
||||||
{
|
ostringstream oss;
|
||||||
_difficulty = NORMAL;
|
int deckFilenameOffset = mStatsFilename.find("deck") + 4;
|
||||||
|
int oppDeckId = atoi(mStatsFilename.substr(deckFilenameOffset, mStatsFilename.find_last_of(".")).c_str());
|
||||||
|
int avatarId = getAvatarId(oppDeckId);
|
||||||
|
oss << "avatar" << avatarId << ".jpg";
|
||||||
|
mAvatarFilename = oss.str();
|
||||||
|
if (mPercentVictories < 34)
|
||||||
|
{
|
||||||
|
mDifficulty = HARD;
|
||||||
|
}
|
||||||
|
else if (mPercentVictories < 55)
|
||||||
|
{
|
||||||
|
mDifficulty = NORMAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mDifficulty = EASY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_difficulty = EASY;
|
ostringstream oss;
|
||||||
|
oss << "avatar" << getAvatarId(mDeckId) << ".jpg";
|
||||||
|
mAvatarFilename = oss.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ostringstream oss;
|
if (fileExists(mStatsFilename.c_str()))
|
||||||
oss << "avatar" << getAvatarId(_deckid) << ".jpg";
|
{
|
||||||
_avatarFilename = oss.str();
|
stats->load(mStatsFilename);
|
||||||
|
mGamesPlayed = stats->nbGames();
|
||||||
|
mPercentVictories = stats->percentVictories();
|
||||||
|
mVictories = static_cast<int>(mGamesPlayed * (mPercentVictories / 100.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mStatsLoaded = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fileExists(deckStatsFileName.c_str()))
|
|
||||||
{
|
|
||||||
stats->load(deckStatsFileName.c_str());
|
|
||||||
_nbGamesPlayed = stats->nbGames();
|
|
||||||
_percentVictories = stats->percentVictories();
|
|
||||||
_victories = _nbGamesPlayed * (_percentVictories / 100.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stats = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// since we only have 100 stock avatar images, we need to recylce the images for deck numbers > 99
|
// since we only have 100 stock avatar images, we need to recycle the images for deck numbers > 99
|
||||||
int DeckMetaData::getAvatarId(int deckId)
|
int DeckMetaData::getAvatarId(int deckId)
|
||||||
{
|
{
|
||||||
int avatarId = deckId % 100;
|
int avatarId = deckId % 100;
|
||||||
@@ -85,17 +88,19 @@ int DeckMetaData::getAvatarId(int deckId)
|
|||||||
return avatarId;
|
return avatarId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckMetaData::load(string filename)
|
void DeckMetaData::LoadDeck()
|
||||||
{
|
{
|
||||||
MTGDeck * mtgd = NEW MTGDeck(filename.c_str(), NULL, 1);
|
if (!mDeckLoaded)
|
||||||
_name = trim(mtgd->meta_name);
|
{
|
||||||
_desc = trim(mtgd->meta_desc);
|
MTGDeck deck(mFilename.c_str(), NULL, 1);
|
||||||
_deckid = atoi((filename.substr(filename.find("deck") + 4, filename.find(".txt"))).c_str());
|
mName = trim(deck.meta_name);
|
||||||
_percentVictories = 0;
|
mDescription = trim(deck.meta_desc);
|
||||||
_nbGamesPlayed = 0;
|
mDeckId = atoi((mFilename.substr(mFilename.find("deck") + 4, mFilename.find(".txt"))).c_str());
|
||||||
_filename = filename;
|
|
||||||
_victories = 0;
|
mDeckLoaded = true;
|
||||||
delete (mtgd);
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeckMetaDataList::~DeckMetaDataList()
|
DeckMetaDataList::~DeckMetaDataList()
|
||||||
@@ -117,14 +122,14 @@ void DeckMetaDataList::invalidate(string filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeckMetaData * DeckMetaDataList::get(string filename, Player * statsPlayer)
|
DeckMetaData * DeckMetaDataList::get(string filename)
|
||||||
{
|
{
|
||||||
map<string, DeckMetaData *>::iterator it = values.find(filename);
|
map<string, DeckMetaData *>::iterator it = values.find(filename);
|
||||||
if (it == values.end())
|
if (it == values.end())
|
||||||
{
|
{
|
||||||
if (fileExists(filename.c_str()))
|
if (fileExists(filename.c_str()))
|
||||||
{
|
{
|
||||||
values[filename] = NEW DeckMetaData(filename, statsPlayer);
|
values[filename] = NEW DeckMetaData(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,48 +140,48 @@ DeckMetaData * DeckMetaDataList::get(string filename, Player * statsPlayer)
|
|||||||
|
|
||||||
string DeckMetaData::getFilename()
|
string DeckMetaData::getFilename()
|
||||||
{
|
{
|
||||||
return _filename;
|
return mFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DeckMetaData::getName()
|
string DeckMetaData::getName()
|
||||||
{
|
{
|
||||||
return _name;
|
return mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DeckMetaData::getDeckId()
|
int DeckMetaData::getDeckId()
|
||||||
{
|
{
|
||||||
return _deckid;
|
return mDeckId;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DeckMetaData::getAvatarFilename()
|
string DeckMetaData::getAvatarFilename()
|
||||||
{
|
{
|
||||||
return _avatarFilename;
|
return mAvatarFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DeckMetaData::getGamesPlayed()
|
int DeckMetaData::getGamesPlayed()
|
||||||
{
|
{
|
||||||
return _nbGamesPlayed;
|
return mGamesPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DeckMetaData::getVictories()
|
int DeckMetaData::getVictories()
|
||||||
{
|
{
|
||||||
return _victories;
|
return mVictories;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DeckMetaData::getVictoryPercentage()
|
int DeckMetaData::getVictoryPercentage()
|
||||||
{
|
{
|
||||||
return _percentVictories;
|
return mPercentVictories;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DeckMetaData::getDifficulty()
|
int DeckMetaData::getDifficulty()
|
||||||
{
|
{
|
||||||
return _difficulty;
|
return mDifficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DeckMetaData::getDifficultyString()
|
string DeckMetaData::getDifficultyString()
|
||||||
{
|
{
|
||||||
string difficultyString = "Normal";
|
string difficultyString = "Normal";
|
||||||
switch (_difficulty)
|
switch (mDifficulty)
|
||||||
{
|
{
|
||||||
case HARD:
|
case HARD:
|
||||||
difficultyString = "Hard";
|
difficultyString = "Hard";
|
||||||
@@ -191,16 +196,22 @@ string DeckMetaData::getDifficultyString()
|
|||||||
|
|
||||||
string DeckMetaData::getDescription()
|
string DeckMetaData::getDescription()
|
||||||
{
|
{
|
||||||
return _desc;
|
return mDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DeckMetaData::getStatsSummary()
|
string DeckMetaData::getStatsSummary()
|
||||||
{
|
{
|
||||||
|
LoadStats();
|
||||||
|
|
||||||
ostringstream statsSummary;
|
ostringstream statsSummary;
|
||||||
statsSummary << "Difficulty: " << getDifficultyString() << endl
|
statsSummary << "Difficulty: " << getDifficultyString() << endl
|
||||||
<< "Victory %: " << getVictoryPercentage() << endl
|
<< "Victory %: " << getVictoryPercentage() << endl
|
||||||
<< "Games Played: " << getGamesPlayed() << endl;
|
<< "Games Played: " << getGamesPlayed() << endl;
|
||||||
|
|
||||||
return statsSummary.str();
|
return statsSummary.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckMetaData::Invalidate()
|
||||||
|
{
|
||||||
|
mStatsLoaded = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
|
#include "DeckManager.h"
|
||||||
#include "DeckStats.h"
|
#include "DeckStats.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "GameObserver.h"
|
#include "GameObserver.h"
|
||||||
@@ -27,19 +28,6 @@ DeckStats * DeckStats::GetInstance()
|
|||||||
return mInstance;
|
return mInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckStats::cleanStats()
|
|
||||||
{
|
|
||||||
/* map<string, DeckStat *>::iterator it;
|
|
||||||
for (it = stats.begin(); it != stats.end(); it++)
|
|
||||||
{
|
|
||||||
SAFE_DELETE(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
stats.clear();
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
DeckStats::~DeckStats()
|
DeckStats::~DeckStats()
|
||||||
{
|
{
|
||||||
map<string, map<string,DeckStat*> > ::iterator it;
|
map<string, map<string,DeckStat*> > ::iterator it;
|
||||||
@@ -118,14 +106,7 @@ int DeckStats::percentVictories()
|
|||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckStats::load(Player * player)
|
void DeckStats::load(const std::string& filename)
|
||||||
{
|
|
||||||
char filename[512];
|
|
||||||
sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str());
|
|
||||||
load(options.profileFile(filename).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeckStats::load(const char * filename)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
currentDeck = filename;
|
currentDeck = filename;
|
||||||
@@ -133,7 +114,7 @@ void DeckStats::load(const char * filename)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wagic::ifstream file(filename);
|
wagic::ifstream file(filename.c_str());
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
@@ -156,16 +137,9 @@ void DeckStats::load(const char * filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckStats::save(Player * player)
|
void DeckStats::save(const std::string& filename)
|
||||||
{
|
{
|
||||||
char filename[512];
|
std::ofstream file(filename.c_str());
|
||||||
sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str());
|
|
||||||
save(options.profileFile(filename).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeckStats::save(const char * filename)
|
|
||||||
{
|
|
||||||
std::ofstream file(filename);
|
|
||||||
char writer[512];
|
char writer[512];
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
@@ -196,7 +170,7 @@ void DeckStats::saveStats(Player *player, Player *opponent, GameObserver * game)
|
|||||||
{
|
{
|
||||||
victory = 0;
|
victory = 0;
|
||||||
}
|
}
|
||||||
load(player);
|
load(currentDeck);
|
||||||
map<string, DeckStat *> *stats = &masterDeckStats[currentDeck];
|
map<string, DeckStat *> *stats = &masterDeckStats[currentDeck];
|
||||||
map<string, DeckStat *>::iterator it = stats->find(opponent->deckFileSmall);
|
map<string, DeckStat *>::iterator it = stats->find(opponent->deckFileSmall);
|
||||||
if (it == stats->end())
|
if (it == stats->end())
|
||||||
@@ -208,7 +182,18 @@ void DeckStats::saveStats(Player *player, Player *opponent, GameObserver * game)
|
|||||||
it->second->victories += victory;
|
it->second->victories += victory;
|
||||||
it->second->nbgames += 1;
|
it->second->nbgames += 1;
|
||||||
}
|
}
|
||||||
save(player);
|
save(currentDeck);
|
||||||
|
|
||||||
|
DeckMetaData* playerMeta = DeckManager::GetInstance()->getDeckMetaDataByFilename(player->deckFile, false);
|
||||||
|
|
||||||
|
// metadata caches its internal data (number of games, victories, etc)
|
||||||
|
// tell it to refresh when stats are updated
|
||||||
|
if (playerMeta)
|
||||||
|
playerMeta->Invalidate();
|
||||||
|
|
||||||
|
DeckMetaData* aiMeta = DeckManager::GetInstance()->getDeckMetaDataByFilename(opponent->deckFile, true);
|
||||||
|
if (aiMeta)
|
||||||
|
aiMeta->Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckStats::EndInstance()
|
void DeckStats::EndInstance()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ vector<DeckMetaData *> GameState::fillDeckMenu(SimpleMenu * _menu, const string&
|
|||||||
Player * statsPlayer)
|
Player * statsPlayer)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<DeckMetaData *> deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer);
|
vector<DeckMetaData *> deckMetaDataVector = BuildDeckList(path, smallDeckPrefix, statsPlayer);
|
||||||
renderDeckMenu(_menu, deckMetaDataVector);
|
renderDeckMenu(_menu, deckMetaDataVector);
|
||||||
|
|
||||||
return deckMetaDataVector;
|
return deckMetaDataVector;
|
||||||
@@ -27,13 +27,13 @@ vector<DeckMetaData *> GameState::fillDeckMenu(DeckMenu * _menu, const string& p
|
|||||||
Player * statsPlayer, int maxDecks)
|
Player * statsPlayer, int maxDecks)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<DeckMetaData *> deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer, maxDecks);
|
vector<DeckMetaData *> deckMetaDataVector = BuildDeckList(path, smallDeckPrefix, statsPlayer, maxDecks);
|
||||||
renderDeckMenu(_menu, deckMetaDataVector);
|
renderDeckMenu(_menu, deckMetaDataVector);
|
||||||
|
|
||||||
return deckMetaDataVector;
|
return deckMetaDataVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<DeckMetaData *> GameState::getValidDeckMetaData(const string& path, const string& smallDeckPrefix, Player * statsPlayer, int maxDecks)
|
vector<DeckMetaData *> GameState::BuildDeckList(const string& path, const string& smallDeckPrefix, Player * statsPlayer, int maxDecks)
|
||||||
{
|
{
|
||||||
vector<DeckMetaData*> retList;
|
vector<DeckMetaData*> retList;
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ vector<DeckMetaData *> GameState::getValidDeckMetaData(const string& path, const
|
|||||||
found = 0;
|
found = 0;
|
||||||
std::ostringstream filename;
|
std::ostringstream filename;
|
||||||
filename << path << "/deck" << nbDecks << ".txt";
|
filename << path << "/deck" << nbDecks << ".txt";
|
||||||
DeckMetaData * meta = metas->get(filename.str(), statsPlayer);
|
DeckMetaData * meta = metas->get(filename.str());
|
||||||
string deckStatsFileName;
|
|
||||||
if (meta)
|
if (meta)
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
@@ -54,16 +54,22 @@ vector<DeckMetaData *> GameState::getValidDeckMetaData(const string& path, const
|
|||||||
{
|
{
|
||||||
std::ostringstream aiStatsDeckName;
|
std::ostringstream aiStatsDeckName;
|
||||||
aiStatsDeckName << smallDeckPrefix << "_deck" << nbDecks;
|
aiStatsDeckName << smallDeckPrefix << "_deck" << nbDecks;
|
||||||
deckStatsFileName = aiStatsDeckName.str();
|
meta->mStatsFilename = aiStatsDeckName.str();
|
||||||
|
meta->mIsAI = true;
|
||||||
|
if (meta->mPlayerDeck != statsPlayer->GetCurrentDeckStatsFile())
|
||||||
|
{
|
||||||
|
meta->mPlayerDeck = statsPlayer->GetCurrentDeckStatsFile();
|
||||||
|
meta->Invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::ostringstream playerStatsDeckName;
|
std::ostringstream playerStatsDeckName;
|
||||||
playerStatsDeckName << "stats/player_deck" << nbDecks << ".txt";
|
playerStatsDeckName << "stats/player_deck" << nbDecks << ".txt";
|
||||||
deckStatsFileName = options.profileFile(playerStatsDeckName.str());
|
meta->mStatsFilename = options.profileFile(playerStatsDeckName.str());
|
||||||
|
meta->mIsAI = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta->loadStatsForPlayer(statsPlayer, deckStatsFileName);
|
|
||||||
retList.push_back(meta);
|
retList.push_back(meta);
|
||||||
nbDecks++;
|
nbDecks++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ GameStateDeckViewer::GameStateDeckViewer(GameApp* parent) :
|
|||||||
GameState(parent)
|
GameState(parent)
|
||||||
{
|
{
|
||||||
bgMusic = NULL;
|
bgMusic = NULL;
|
||||||
nbDecks = 0;
|
|
||||||
deckNum = 0;
|
|
||||||
useFilter = 0;
|
useFilter = 0;
|
||||||
isAIDeckSave = false;
|
isAIDeckSave = false;
|
||||||
mSwitching = false;
|
mSwitching = false;
|
||||||
@@ -168,9 +166,7 @@ void GameStateDeckViewer::updateDecks()
|
|||||||
DeckManager * deckManager = DeckManager::GetInstance();
|
DeckManager * deckManager = DeckManager::GetInstance();
|
||||||
vector<DeckMetaData *> playerDeckList = fillDeckMenu(welcome_menu, options.profileFile());
|
vector<DeckMetaData *> playerDeckList = fillDeckMenu(welcome_menu, options.profileFile());
|
||||||
|
|
||||||
deckNum = 0;
|
|
||||||
newDeckname = "";
|
newDeckname = "";
|
||||||
nbDecks = playerDeckList.size() + 1;
|
|
||||||
welcome_menu->Add(MENU_ITEM_NEW_DECK, "--NEW--");
|
welcome_menu->Add(MENU_ITEM_NEW_DECK, "--NEW--");
|
||||||
if (options[Options::CHEATMODE].number && (!myCollection || myCollection->getCount(WSrcDeck::UNFILTERED_MIN_COPIES) < 4)) welcome_menu->Add(
|
if (options[Options::CHEATMODE].number && (!myCollection || myCollection->getCount(WSrcDeck::UNFILTERED_MIN_COPIES) < 4)) welcome_menu->Add(
|
||||||
MENU_ITEM_CHEAT_MODE, "--UNLOCK CARDS--");
|
MENU_ITEM_CHEAT_MODE, "--UNLOCK CARDS--");
|
||||||
@@ -319,7 +315,7 @@ void GameStateDeckViewer::saveDeck()
|
|||||||
void GameStateDeckViewer::saveAsAIDeck(string deckName)
|
void GameStateDeckViewer::saveAsAIDeck(string deckName)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<DeckMetaData *> aiDecks = GameState::getValidDeckMetaData(JGE_GET_RES("ai/baka"), "ai_baka", NULL);
|
vector<DeckMetaData *> aiDecks = GameState::BuildDeckList(JGE_GET_RES("ai/baka"), "ai_baka", NULL);
|
||||||
int nbAiDecks = aiDecks.size() + 1;
|
int nbAiDecks = aiDecks.size() + 1;
|
||||||
aiDecks.clear();
|
aiDecks.clear();
|
||||||
|
|
||||||
@@ -1570,7 +1566,6 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId)
|
|||||||
|
|
||||||
loadDeck(deckIdNumber);
|
loadDeck(deckIdNumber);
|
||||||
mStage = STAGE_WAITING;
|
mStage = STAGE_WAITING;
|
||||||
deckNum = controlId;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_DECK_BUILDER: //Save / exit menu
|
case MENU_DECK_BUILDER: //Save / exit menu
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ void GameStateDuel::Start()
|
|||||||
GameStateDuel::selectedPlayerDeckId, true);
|
GameStateDuel::selectedPlayerDeckId, true);
|
||||||
deckmenu->enableDisplayDetailsOverride();
|
deckmenu->enableDisplayDetailsOverride();
|
||||||
DeckManager *deckManager = DeckManager::GetInstance();
|
DeckManager *deckManager = DeckManager::GetInstance();
|
||||||
vector<DeckMetaData *> playerDeckList = getValidDeckMetaData(options.profileFile());
|
vector<DeckMetaData *> playerDeckList = BuildDeckList(options.profileFile());
|
||||||
int nbDecks = playerDeckList.size();
|
int nbDecks = playerDeckList.size();
|
||||||
|
|
||||||
if (nbDecks)
|
if (nbDecks)
|
||||||
|
|||||||
@@ -192,11 +192,13 @@ void GameStateMenu::fillScroller()
|
|||||||
char buff2[512];
|
char buff2[512];
|
||||||
|
|
||||||
DeckStats * stats = DeckStats::GetInstance();
|
DeckStats * stats = DeckStats::GetInstance();
|
||||||
vector<DeckMetaData *> playerDecks = getValidDeckMetaData(options.profileFile(), "", NULL, 6);
|
vector<DeckMetaData *> playerDecks = BuildDeckList(options.profileFile(), "", NULL, 6);
|
||||||
int totalGames = 0;
|
int totalGames = 0;
|
||||||
for (size_t j = 0; j < playerDecks.size(); j++)
|
for (size_t j = 0; j < playerDecks.size(); j++)
|
||||||
{
|
{
|
||||||
DeckMetaData* meta = playerDecks[j];
|
DeckMetaData* meta = playerDecks[j];
|
||||||
|
if (meta)
|
||||||
|
meta->LoadStats();
|
||||||
sprintf(buffer, "stats/player_deck%i.txt", meta->getDeckId());
|
sprintf(buffer, "stats/player_deck%i.txt", meta->getDeckId());
|
||||||
string deckstats = options.profileFile(buffer);
|
string deckstats = options.profileFile(buffer);
|
||||||
if (fileExists(deckstats.c_str()))
|
if (fileExists(deckstats.c_str()))
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ int Player::gainOrLoseLife(int value)
|
|||||||
game->receiveEvent(lifed);
|
game->receiveEvent(lifed);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
};
|
}
|
||||||
|
|
||||||
int Player::gainLife(int value)
|
int Player::gainLife(int value)
|
||||||
{
|
{
|
||||||
@@ -144,7 +144,7 @@ int Player::gainLife(int value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return gainOrLoseLife(value);
|
return gainOrLoseLife(value);
|
||||||
};
|
}
|
||||||
|
|
||||||
int Player::loseLife(int value)
|
int Player::loseLife(int value)
|
||||||
{
|
{
|
||||||
@@ -154,21 +154,23 @@ int Player::loseLife(int value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return gainOrLoseLife(-value);
|
return gainOrLoseLife(-value);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
int Player::afterDamage()
|
int Player::afterDamage()
|
||||||
{
|
{
|
||||||
return life;
|
return life;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Player::poisoned()
|
int Player::poisoned()
|
||||||
{
|
{
|
||||||
return poisonCount;
|
return poisonCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Player::damaged()
|
int Player::damaged()
|
||||||
{
|
{
|
||||||
return damageCount;
|
return damageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Player::prevented()
|
int Player::prevented()
|
||||||
{
|
{
|
||||||
return preventable;
|
return preventable;
|
||||||
@@ -197,6 +199,13 @@ void Player::cleanupPhase()
|
|||||||
game->graveyard->cleanupPhase();
|
game->graveyard->cleanupPhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Player::GetCurrentDeckStatsFile()
|
||||||
|
{
|
||||||
|
std::ostringstream filename;
|
||||||
|
filename << "stats/" << deckFileSmall << ".txt";
|
||||||
|
return options.profileFile(filename.str());
|
||||||
|
}
|
||||||
|
|
||||||
ostream& operator<<(ostream& out, const Player& p)
|
ostream& operator<<(ostream& out, const Player& p)
|
||||||
{
|
{
|
||||||
return out << p.getDisplayName();
|
return out << p.getDisplayName();
|
||||||
|
|||||||
Reference in New Issue
Block a user