From 6675a7da315c9f3e07ec9d354d298cfb5609113d Mon Sep 17 00:00:00 2001 From: "wrenczes@gmail.com" Date: Sun, 30 Jan 2011 13:06:21 +0000 Subject: [PATCH] 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. --- projects/mtg/include/DeckManager.h | 23 ++-- projects/mtg/include/DeckMetaData.h | 31 +++-- projects/mtg/include/DeckStats.h | 8 +- projects/mtg/include/GameState.h | 2 +- projects/mtg/include/GameStateDeckViewer.h | 2 - projects/mtg/include/Player.h | 5 + projects/mtg/src/Credits.cpp | 2 +- projects/mtg/src/DeckManager.cpp | 34 ++++- projects/mtg/src/DeckMenu.cpp | 6 + projects/mtg/src/DeckMetaData.cpp | 151 +++++++++++---------- projects/mtg/src/DeckStats.cpp | 51 +++---- projects/mtg/src/GameState.cpp | 22 +-- projects/mtg/src/GameStateDeckViewer.cpp | 7 +- projects/mtg/src/GameStateDuel.cpp | 2 +- projects/mtg/src/GameStateMenu.cpp | 4 +- projects/mtg/src/Player.cpp | 39 ++++-- 16 files changed, 221 insertions(+), 168 deletions(-) diff --git a/projects/mtg/include/DeckManager.h b/projects/mtg/include/DeckManager.h index 7138db76a..2c6d67ec4 100644 --- a/projects/mtg/include/DeckManager.h +++ b/projects/mtg/include/DeckManager.h @@ -17,20 +17,21 @@ private: public: - vector playerDeckOrderList; - vector aiDeckOrderList; + vector playerDeckOrderList; + vector aiDeckOrderList; - map playerDeckStatsMap; - map aiDeckStatsMap; + map playerDeckStatsMap; + map aiDeckStatsMap; - void updateMetaDataList(vector* refList, bool isAI); - vector * getPlayerDeckOrderList(); - vector * getAIDeckOrderList(); + void updateMetaDataList(vector* refList, bool isAI); + vector * getPlayerDeckOrderList(); + vector * getAIDeckOrderList(); - DeckMetaData * getDeckMetaDataById( int deckId, bool isAI ); - StatsWrapper * getExtendedStatsForDeckId( int deckId, MTGAllCards *collection, bool isAI ); - StatsWrapper * getExtendedDeckStats( DeckMetaData *selectedDeck, MTGAllCards *collection, bool isAI ); - static DeckManager * GetInstance(); + DeckMetaData* getDeckMetaDataById(int deckId, bool isAI); + DeckMetaData* getDeckMetaDataByFilename(const std::string& filename, bool isAI); + StatsWrapper* getExtendedStatsForDeckId(int deckId, MTGAllCards* collection, bool isAI); + StatsWrapper* getExtendedDeckStats(DeckMetaData* selectedDeck, MTGAllCards* collection, bool isAI); + static DeckManager* GetInstance(); static void EndInstance(); //convenience method to get the difficulty rating between two decks. This should be refined a little more diff --git a/projects/mtg/include/DeckMetaData.h b/projects/mtg/include/DeckMetaData.h index 6a8e370e3..d04abbefd 100644 --- a/projects/mtg/include/DeckMetaData.h +++ b/projects/mtg/include/DeckMetaData.h @@ -17,22 +17,21 @@ enum DECK_DIFFICULTY class DeckMetaData { private: - string _filename; - - string _desc; - string _name; - int _deckid; - string _avatarFilename; + string mFilename; + string mDescription; + string mName; + int mDeckId; + string mAvatarFilename; // statistical information + int mGamesPlayed, mVictories, mPercentVictories, mDifficulty; - int _nbGamesPlayed, _victories, _percentVictories, _difficulty; + DeckMetaData(); public: - DeckMetaData(); - DeckMetaData(string filename, Player * statsPlayer); - void load(string filename); - void loadStatsForPlayer(Player * statsPlayer, string deckStatsFileName = ""); + DeckMetaData(const string& filename); + void LoadDeck(); + void LoadStats(); // Accessors string getFilename(); @@ -49,6 +48,13 @@ public: int getDifficulty(); string getDifficultyString(); + void Invalidate(); + + string mStatsFilename; + string mPlayerDeck; + bool mDeckLoaded; + bool mStatsLoaded; + bool mIsAI; }; class DeckMetaDataList @@ -58,10 +64,9 @@ private: public: void invalidate(string filename); - DeckMetaData * get(string filename, Player * statsPlayer = NULL); + DeckMetaData * get(string filename); ~DeckMetaDataList(); static DeckMetaDataList * decksMetaData; - }; #endif diff --git a/projects/mtg/include/DeckStats.h b/projects/mtg/include/DeckStats.h index 5b410425d..8434e9b37 100644 --- a/projects/mtg/include/DeckStats.h +++ b/projects/mtg/include/DeckStats.h @@ -34,11 +34,9 @@ public: static DeckStats * GetInstance(); static void EndInstance(); void saveStats(Player * player, Player * opponent, GameObserver * game); - void save(const char * filename); - void save(Player * player); - void load(const char * filename); - void load(Player * player); - void cleanStats(); + void save(const std::string& filename); + void load(const std::string& filename); + ~DeckStats(); int percentVictories(string opponentsDeckFile); int percentVictories(); diff --git a/projects/mtg/include/GameState.h b/projects/mtg/include/GameState.h index bc0e2f0c6..5e2908022 100644 --- a/projects/mtg/include/GameState.h +++ b/projects/mtg/include/GameState.h @@ -73,7 +73,7 @@ public: static vector 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. - static vector getValidDeckMetaData(const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL, int maxDecks = 0); + static vector BuildDeckList(const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL, int maxDecks = 0); // build menu items based on the vector static void renderDeckMenu(SimpleMenu * _menu, const vector& deckMetaDataList); diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index 81e9897a7..6406b302f 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -90,8 +90,6 @@ private: float mSlide; int mAlpha; int mStage; - int nbDecks; - int deckNum; int useFilter; JMusic * bgMusic; JQuad * backQuad; diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index 0cd77f8c0..bdd9ac35e 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -100,6 +100,11 @@ public: } void loadAvatar(string file); + + /** + ** Returns the path to the stats file of currently selected deck. + */ + std::string GetCurrentDeckStatsFile(); }; class HumanPlayer: public Player diff --git a/projects/mtg/src/Credits.cpp b/projects/mtg/src/Credits.cpp index 2ee93cb8f..3eada3a98 100644 --- a/projects/mtg/src/Credits.cpp +++ b/projects/mtg/src/Credits.cpp @@ -117,7 +117,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app) if (unlocked == -1) { DeckStats * stats = DeckStats::GetInstance(); - stats->load(p1); + stats->load(p1->GetCurrentDeckStatsFile()); unlocked = isDifficultyUnlocked(stats); if (unlocked) { diff --git a/projects/mtg/src/DeckManager.cpp b/projects/mtg/src/DeckManager.cpp index 107fdeb34..663e8ba6b 100644 --- a/projects/mtg/src/DeckManager.cpp +++ b/projects/mtg/src/DeckManager.cpp @@ -55,6 +55,38 @@ DeckMetaData* DeckManager::getDeckMetaDataById( int deckId, bool isAI ) 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& deckList = isAI ? aiDeckOrderList : playerDeckOrderList; + + std::vector::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 ) { DeckMetaData *selectedDeck = getDeckMetaDataById( deckId, isAI ); @@ -133,7 +165,7 @@ int DeckManager::getDifficultyRating(Player *statsPlayer, Player *player) { DeckMetaDataList * metas = DeckMetaDataList::decksMetaData; - DeckMetaData *meta = metas->get(player->deckFile, statsPlayer); + DeckMetaData *meta = metas->get(player->deckFile); return meta->getDifficulty(); } diff --git a/projects/mtg/src/DeckMenu.cpp b/projects/mtg/src/DeckMenu.cpp index 80a321538..d7d8e2da6 100644 --- a/projects/mtg/src/DeckMenu.cpp +++ b/projects/mtg/src/DeckMenu.cpp @@ -184,6 +184,12 @@ void DeckMenu::Render() DeckMenuItem *currentMenuItem = static_cast (mObjects[i]); 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()) { mSelectedDeckId = i; diff --git a/projects/mtg/src/DeckMetaData.cpp b/projects/mtg/src/DeckMetaData.cpp index 50650af7f..bbe7f016a 100644 --- a/projects/mtg/src/DeckMetaData.cpp +++ b/projects/mtg/src/DeckMetaData.cpp @@ -11,71 +11,74 @@ 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); -} - -void DeckMetaData::loadStatsForPlayer(Player * statsPlayer, string deckStatsFileName) -{ - DeckStats * stats = DeckStats::GetInstance(); - _nbGamesPlayed = 0; - _percentVictories = 0; - _victories = 0; - if (statsPlayer) + if (!mStatsLoaded) { - stats->load(statsPlayer); - DeckStat * opponentDeckStats = stats->getDeckStat(deckStatsFileName); - if (opponentDeckStats) + DeckStats * stats = DeckStats::GetInstance(); + if (mIsAI) { - _percentVictories = stats->percentVictories(deckStatsFileName); - _victories = opponentDeckStats->victories; - _nbGamesPlayed = opponentDeckStats->nbgames; - 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) + stats->load(mPlayerDeck); + DeckStat * opponentDeckStats = stats->getDeckStat(mStatsFilename); + if (opponentDeckStats) { - _difficulty = HARD; - } - else if (_percentVictories < 55) - { - _difficulty = NORMAL; + mPercentVictories = stats->percentVictories(mStatsFilename); + mVictories = opponentDeckStats->victories; + mGamesPlayed = opponentDeckStats->nbgames; + ostringstream oss; + 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 { - _difficulty = EASY; + ostringstream oss; + oss << "avatar" << getAvatarId(mDeckId) << ".jpg"; + mAvatarFilename = oss.str(); } } else { - ostringstream oss; - oss << "avatar" << getAvatarId(_deckid) << ".jpg"; - _avatarFilename = oss.str(); + if (fileExists(mStatsFilename.c_str())) + { + stats->load(mStatsFilename); + mGamesPlayed = stats->nbGames(); + mPercentVictories = stats->percentVictories(); + mVictories = static_cast(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 avatarId = deckId % 100; @@ -85,17 +88,19 @@ int DeckMetaData::getAvatarId(int deckId) return avatarId; } -void DeckMetaData::load(string filename) +void DeckMetaData::LoadDeck() { - MTGDeck * mtgd = NEW MTGDeck(filename.c_str(), NULL, 1); - _name = trim(mtgd->meta_name); - _desc = trim(mtgd->meta_desc); - _deckid = atoi((filename.substr(filename.find("deck") + 4, filename.find(".txt"))).c_str()); - _percentVictories = 0; - _nbGamesPlayed = 0; - _filename = filename; - _victories = 0; - delete (mtgd); + if (!mDeckLoaded) + { + MTGDeck deck(mFilename.c_str(), NULL, 1); + mName = trim(deck.meta_name); + mDescription = trim(deck.meta_desc); + mDeckId = atoi((mFilename.substr(mFilename.find("deck") + 4, mFilename.find(".txt"))).c_str()); + + mDeckLoaded = true; + } + + } DeckMetaDataList::~DeckMetaDataList() @@ -117,14 +122,14 @@ void DeckMetaDataList::invalidate(string filename) } } -DeckMetaData * DeckMetaDataList::get(string filename, Player * statsPlayer) +DeckMetaData * DeckMetaDataList::get(string filename) { map::iterator it = values.find(filename); if (it == values.end()) { 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() { - return _filename; + return mFilename; } string DeckMetaData::getName() { - return _name; + return mName; } int DeckMetaData::getDeckId() { - return _deckid; + return mDeckId; } string DeckMetaData::getAvatarFilename() { - return _avatarFilename; + return mAvatarFilename; } int DeckMetaData::getGamesPlayed() { - return _nbGamesPlayed; + return mGamesPlayed; } int DeckMetaData::getVictories() { - return _victories; + return mVictories; } int DeckMetaData::getVictoryPercentage() { - return _percentVictories; + return mPercentVictories; } int DeckMetaData::getDifficulty() { - return _difficulty; + return mDifficulty; } string DeckMetaData::getDifficultyString() { string difficultyString = "Normal"; - switch (_difficulty) + switch (mDifficulty) { case HARD: difficultyString = "Hard"; @@ -191,16 +196,22 @@ string DeckMetaData::getDifficultyString() string DeckMetaData::getDescription() { - return _desc; + return mDescription; } string DeckMetaData::getStatsSummary() { + LoadStats(); + ostringstream statsSummary; statsSummary << "Difficulty: " << getDifficultyString() << endl << "Victory %: " << getVictoryPercentage() << endl << "Games Played: " << getGamesPlayed() << endl; return statsSummary.str(); - +} + +void DeckMetaData::Invalidate() +{ + mStatsLoaded = false; } diff --git a/projects/mtg/src/DeckStats.cpp b/projects/mtg/src/DeckStats.cpp index cff6eeccc..983c13f43 100644 --- a/projects/mtg/src/DeckStats.cpp +++ b/projects/mtg/src/DeckStats.cpp @@ -1,5 +1,6 @@ #include "PrecompiledHeader.h" +#include "DeckManager.h" #include "DeckStats.h" #include "Player.h" #include "GameObserver.h" @@ -27,19 +28,6 @@ DeckStats * DeckStats::GetInstance() return mInstance; } -void DeckStats::cleanStats() -{ -/* map::iterator it; - for (it = stats.begin(); it != stats.end(); it++) - { - SAFE_DELETE(it->second); - } - - stats.clear(); - - */ -} - DeckStats::~DeckStats() { map > ::iterator it; @@ -118,14 +106,7 @@ int DeckStats::percentVictories() return 50; } -void DeckStats::load(Player * player) -{ - char filename[512]; - sprintf(filename, "stats/%s.txt", player->deckFileSmall.c_str()); - load(options.profileFile(filename).c_str()); -} - -void DeckStats::load(const char * filename) +void DeckStats::load(const std::string& filename) { currentDeck = filename; @@ -133,7 +114,7 @@ void DeckStats::load(const char * filename) { return; } - wagic::ifstream file(filename); + wagic::ifstream file(filename.c_str()); std::string s; 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]; - 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); + std::ofstream file(filename.c_str()); char writer[512]; if (file) { @@ -196,7 +170,7 @@ void DeckStats::saveStats(Player *player, Player *opponent, GameObserver * game) { victory = 0; } - load(player); + load(currentDeck); map *stats = &masterDeckStats[currentDeck]; map::iterator it = stats->find(opponent->deckFileSmall); if (it == stats->end()) @@ -208,7 +182,18 @@ void DeckStats::saveStats(Player *player, Player *opponent, GameObserver * game) it->second->victories += victory; 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() diff --git a/projects/mtg/src/GameState.cpp b/projects/mtg/src/GameState.cpp index 85e08ef46..421f939ec 100644 --- a/projects/mtg/src/GameState.cpp +++ b/projects/mtg/src/GameState.cpp @@ -17,7 +17,7 @@ vector GameState::fillDeckMenu(SimpleMenu * _menu, const string& Player * statsPlayer) { - vector deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer); + vector deckMetaDataVector = BuildDeckList(path, smallDeckPrefix, statsPlayer); renderDeckMenu(_menu, deckMetaDataVector); return deckMetaDataVector; @@ -27,13 +27,13 @@ vector GameState::fillDeckMenu(DeckMenu * _menu, const string& p Player * statsPlayer, int maxDecks) { - vector deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer, maxDecks); + vector deckMetaDataVector = BuildDeckList(path, smallDeckPrefix, statsPlayer, maxDecks); renderDeckMenu(_menu, deckMetaDataVector); return deckMetaDataVector; } -vector GameState::getValidDeckMetaData(const string& path, const string& smallDeckPrefix, Player * statsPlayer, int maxDecks) +vector GameState::BuildDeckList(const string& path, const string& smallDeckPrefix, Player * statsPlayer, int maxDecks) { vector retList; @@ -45,8 +45,8 @@ vector GameState::getValidDeckMetaData(const string& path, const found = 0; std::ostringstream filename; filename << path << "/deck" << nbDecks << ".txt"; - DeckMetaData * meta = metas->get(filename.str(), statsPlayer); - string deckStatsFileName; + DeckMetaData * meta = metas->get(filename.str()); + if (meta) { found = 1; @@ -54,16 +54,22 @@ vector GameState::getValidDeckMetaData(const string& path, const { std::ostringstream aiStatsDeckName; 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 { std::ostringstream playerStatsDeckName; 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); nbDecks++; } diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index 53645a0dc..fb2da36a2 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -39,8 +39,6 @@ GameStateDeckViewer::GameStateDeckViewer(GameApp* parent) : GameState(parent) { bgMusic = NULL; - nbDecks = 0; - deckNum = 0; useFilter = 0; isAIDeckSave = false; mSwitching = false; @@ -168,9 +166,7 @@ void GameStateDeckViewer::updateDecks() DeckManager * deckManager = DeckManager::GetInstance(); vector playerDeckList = fillDeckMenu(welcome_menu, options.profileFile()); - deckNum = 0; newDeckname = ""; - nbDecks = playerDeckList.size() + 1; welcome_menu->Add(MENU_ITEM_NEW_DECK, "--NEW--"); if (options[Options::CHEATMODE].number && (!myCollection || myCollection->getCount(WSrcDeck::UNFILTERED_MIN_COPIES) < 4)) welcome_menu->Add( MENU_ITEM_CHEAT_MODE, "--UNLOCK CARDS--"); @@ -319,7 +315,7 @@ void GameStateDeckViewer::saveDeck() void GameStateDeckViewer::saveAsAIDeck(string deckName) { - vector aiDecks = GameState::getValidDeckMetaData(JGE_GET_RES("ai/baka"), "ai_baka", NULL); + vector aiDecks = GameState::BuildDeckList(JGE_GET_RES("ai/baka"), "ai_baka", NULL); int nbAiDecks = aiDecks.size() + 1; aiDecks.clear(); @@ -1570,7 +1566,6 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) loadDeck(deckIdNumber); mStage = STAGE_WAITING; - deckNum = controlId; break; case MENU_DECK_BUILDER: //Save / exit menu diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 474dd60f4..00ec86c06 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -111,7 +111,7 @@ void GameStateDuel::Start() GameStateDuel::selectedPlayerDeckId, true); deckmenu->enableDisplayDetailsOverride(); DeckManager *deckManager = DeckManager::GetInstance(); - vector playerDeckList = getValidDeckMetaData(options.profileFile()); + vector playerDeckList = BuildDeckList(options.profileFile()); int nbDecks = playerDeckList.size(); if (nbDecks) diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 8dc79a7d4..0a8b5971f 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -192,11 +192,13 @@ void GameStateMenu::fillScroller() char buff2[512]; DeckStats * stats = DeckStats::GetInstance(); - vector playerDecks = getValidDeckMetaData(options.profileFile(), "", NULL, 6); + vector playerDecks = BuildDeckList(options.profileFile(), "", NULL, 6); int totalGames = 0; for (size_t j = 0; j < playerDecks.size(); j++) { DeckMetaData* meta = playerDecks[j]; + if (meta) + meta->LoadStats(); sprintf(buffer, "stats/player_deck%i.txt", meta->getDeckId()); string deckstats = options.profileFile(buffer); if (fileExists(deckstats.c_str())) diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index de53db3fa..c9b87cdc5 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -134,7 +134,7 @@ int Player::gainOrLoseLife(int value) game->receiveEvent(lifed); return value; -}; +} int Player::gainLife(int value) { @@ -144,7 +144,7 @@ int Player::gainLife(int value) return 0; } return gainOrLoseLife(value); -}; +} int Player::loseLife(int value) { @@ -154,21 +154,23 @@ int Player::loseLife(int value) return 0; } return gainOrLoseLife(-value); -}; - +} int Player::afterDamage() { return life; } + int Player::poisoned() { return poisonCount; } + int Player::damaged() { return damageCount; } + int Player::prevented() { return preventable; @@ -176,17 +178,17 @@ int Player::prevented() void Player::takeMulligan() { - MTGPlayerCards * currentPlayerZones = game; - int cardsinhand = currentPlayerZones->hand->nb_cards; - for (int i = 0; i < cardsinhand; i++) //Discard hand - currentPlayerZones->putInZone(currentPlayerZones->hand->cards[0], - currentPlayerZones->hand, - currentPlayerZones->library); - - currentPlayerZones->library->shuffle(); //Shuffle - - for (int i = 0; i < (cardsinhand - 1); i++) - game->drawFromLibrary(); + MTGPlayerCards * currentPlayerZones = game; + int cardsinhand = currentPlayerZones->hand->nb_cards; + for (int i = 0; i < cardsinhand; i++) //Discard hand + currentPlayerZones->putInZone(currentPlayerZones->hand->cards[0], + currentPlayerZones->hand, + currentPlayerZones->library); + + currentPlayerZones->library->shuffle(); //Shuffle + + for (int i = 0; i < (cardsinhand - 1); i++) + game->drawFromLibrary(); //Draw hand with 1 less card penalty //almhum } @@ -197,6 +199,13 @@ void Player::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) { return out << p.getDisplayName();