- Added AI Decks unlock system. Please update your graphics folder, and crossing fingers that Ilya B. is still around as I don't have the correct fonts.
This commit is contained in:
wagic.the.homebrew@gmail.com
2010-11-28 04:15:58 +00:00
parent 84c2bd5a1e
commit 52fce24bf8
15 changed files with 103 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -25,10 +25,11 @@ public:
class Credits{ class Credits{
private: private:
time_t gameLength; time_t gameLength;
int isDifficultyUnlocked(); int isDifficultyUnlocked(DeckStats * stats);
int isMomirUnlocked(); int isMomirUnlocked();
int isEvilTwinUnlocked(); int isEvilTwinUnlocked();
int isRandomDeckUnlocked(); int isRandomDeckUnlocked();
int IsMoreAIDecksUnlocked(DeckStats * stats);
public: public:
int value; int value;
Player * p1, *p2; Player * p1, *p2;

View File

@@ -38,6 +38,8 @@ public:
int percentVictories(string opponentsDeckFile); int percentVictories(string opponentsDeckFile);
int percentVictories(); int percentVictories();
DeckStat * getDeckStat(string opponentsFile); DeckStat * getDeckStat(string opponentsFile);
//returns the total number of games played with this deck
int nbGames(); int nbGames();
}; };

View File

@@ -52,6 +52,7 @@ public:
GUI_STYLE, GUI_STYLE,
INTERRUPT_SECONDS, INTERRUPT_SECONDS,
KEY_BINDINGS, KEY_BINDINGS,
AIDECKS_UNLOCKED,
//My interrupts //My interrupts
INTERRUPTMYSPELLS, INTERRUPTMYSPELLS,
INTERRUPTMYABILITIES, INTERRUPTMYABILITIES,
@@ -75,7 +76,7 @@ public:
MOMIR_MODE_UNLOCKED, MOMIR_MODE_UNLOCKED,
EVILTWIN_MODE_UNLOCKED, EVILTWIN_MODE_UNLOCKED,
RANDOMDECK_MODE_UNLOCKED, RANDOMDECK_MODE_UNLOCKED,
AWARD_COLLECTOR, AWARD_COLLECTOR,
LAST_NAMED, //Any option after this does not look up in optionNames. LAST_NAMED, //Any option after this does not look up in optionNames.
SET_UNLOCKS = LAST_NAMED + 1, //For sets. SET_UNLOCKS = LAST_NAMED + 1, //For sets.
}; };

View File

@@ -69,10 +69,11 @@ class GameState
static vector<DeckMetaData *> fillDeckMenu(SimpleMenu * _menu, const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL); static vector<DeckMetaData *> fillDeckMenu(SimpleMenu * _menu, const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL);
// generate the Deck Meta Data and build the menu items of the menu given // generate the Deck Meta Data and build the menu items of the menu given
static vector<DeckMetaData *> fillDeckMenu(DeckMenu * _menu, const string& path, const string& smallDeckPrefix = "", Player * statsPlayer = NULL); // Will display up to maxDecks if maxDecks is non 0,all decks in path otherwise
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); static vector<DeckMetaData *> getValidDeckMetaData(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);

View File

@@ -978,9 +978,10 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, Player * op
{ {
if (!deckid) if (!deckid)
{ {
//random deck
int nbdecks = 0; int nbdecks = 0;
int found = 1; int found = 1;
while (found) while (found && nbdecks < options[Options::AIDECKS_UNLOCKED].number)
{ {
found = 0; found = 0;
char buffer[512]; char buffer[512];

View File

@@ -119,7 +119,9 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
if (unlocked == -1) if (unlocked == -1)
{ {
unlocked = isDifficultyUnlocked(); DeckStats * stats = DeckStats::GetInstance();
stats->load(p1);
unlocked = isDifficultyUnlocked(stats);
if (unlocked) if (unlocked)
{ {
unlockedTex = resources.RetrieveTexture("unlocked.png"); unlockedTex = resources.RetrieveTexture("unlocked.png");
@@ -160,6 +162,12 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
if (si) if (si)
unlockedString = si->getName(); //Show the set's pretty name for unlocks. unlockedString = si->getName(); //Show the set's pretty name for unlocks.
} }
else if ((unlocked = IsMoreAIDecksUnlocked(stats)))
{
options[Options::AIDECKS_UNLOCKED].number += 10;
unlockedTex = resources.RetrieveTexture("ai_unlocked.png");
unlockedQuad = resources.RetrieveQuad("ai_unlocked.png", 2, 2, 396, 96);
}
if (unlocked && options[Options::SFXVOLUME].number > 0) if (unlocked && options[Options::SFXVOLUME].number > 0)
{ {
@@ -292,15 +300,14 @@ void Credits::Render()
} }
int Credits::isDifficultyUnlocked() int Credits::isDifficultyUnlocked(DeckStats * stats)
{ {
if (options[Options::DIFFICULTY_MODE_UNLOCKED].number) if (options[Options::DIFFICULTY_MODE_UNLOCKED].number)
return 0; return 0;
int nbAIDecks = 0; int nbAIDecks = 0;
int found = 1; int found = 1;
int wins = 0; int wins = 0;
DeckStats * stats = DeckStats::GetInstance();
stats->load(p1);
while (found) while (found)
{ {
found = 0; found = 0;
@@ -424,3 +431,31 @@ int Credits::unlockRandomSet(bool force)
options.save(); options.save();
return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later. return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
} }
int Credits::IsMoreAIDecksUnlocked(DeckStats * stats) {
int currentlyUnlocked = options[Options::AIDECKS_UNLOCKED].number;
// Random rule: having played at least twice as much games as
// the number of currently unlocked decks in order to go through.
if (stats->nbGames() < currentlyUnlocked * 2) return 0;
int nbdecks = 0;
int found = 1;
while (found)
{
found = 0;
char buffer[512];
sprintf(buffer, JGE_GET_RES("ai/baka/deck%i.txt").c_str(), nbdecks + 1);
std::ifstream file(buffer);
if (file)
{
found = 1;
file.close();
nbdecks++;
if (nbdecks > currentlyUnlocked)
return 1;
}
}
return 0;
}

View File

@@ -336,5 +336,4 @@ DeckMenu::~DeckMenu()
{ {
resources.Release(pspIconsTexture); resources.Release(pspIconsTexture);
SAFE_DELETE(mScroller); SAFE_DELETE(mScroller);
mScroller = NULL;
} }

View File

@@ -3,6 +3,7 @@
#include "DeckMenuItem.h" #include "DeckMenuItem.h"
#include "Translate.h" #include "Translate.h"
#include "WResourceManager.h" #include "WResourceManager.h"
#include <algorithm>
#define ITEM_PX_WIDTH 190.f #define ITEM_PX_WIDTH 190.f
const int kHorizontalScrollSpeed = 10; // lower numbers mean faster scrolling const int kHorizontalScrollSpeed = 10; // lower numbers mean faster scrolling
@@ -62,6 +63,19 @@ void DeckMenuItem::RenderWithOffset(float yOffset)
mScrollTimer = 0; mScrollTimer = 0;
else if (mHasFocus && mScrollEnabled) else if (mHasFocus && mScrollEnabled)
mScrollTimer++; mScrollTimer++;
//Render a "new" icon for decks that have never been played yet
if (meta && !meta->getGamesPlayed())
{
JTexture * tex = resources.RetrieveTexture("new.png");
if (tex)
{
JQuad * quad = resources.RetrieveQuad("new.png", 2, 2, tex->mWidth - 4, tex->mHeight - 4); //avoids weird rectangle aroudn the texture because of bilinear filtering
quad->SetHotSpot(quad->mWidth/2, quad->mHeight/2);
float x = mX + min(ITEM_PX_WIDTH - quad->mWidth, mFont->GetStringWidth(menuItemString.c_str()))/2 + quad->mWidth/2;
if (quad) JRenderer::GetInstance()->RenderQuad(quad, x , mY + yOffset + quad->mHeight/2, 0.5);
}
}
} }
void DeckMenuItem::Render() void DeckMenuItem::Render()

View File

@@ -39,6 +39,7 @@ const string Options::optionNames[] = {
"keybindings_psp", "keybindings_psp",
#endif #endif
#endif #endif
"aidecks",
"interruptMySpells", "interruptMySpells",
"interruptMyAbilities", "interruptMyAbilities",
//General interrupts //General interrupts
@@ -342,6 +343,9 @@ int GameOptions::load()
if (!(*this)[Options::MAX_GRADE].number) if (!(*this)[Options::MAX_GRADE].number)
(*this)[Options::MAX_GRADE].number = Constants::GRADE_BORDERLINE; (*this)[Options::MAX_GRADE].number = Constants::GRADE_BORDERLINE;
if (!(*this)[Options::AIDECKS_UNLOCKED].number)
(*this)[Options::AIDECKS_UNLOCKED].number = 10;
return 1; return 1;
} }
int GameOptions::save() int GameOptions::save()

View File

@@ -26,25 +26,25 @@ vector<DeckMetaData *> GameState::fillDeckMenu(SimpleMenu * _menu, const string&
} }
vector<DeckMetaData *> GameState::fillDeckMenu(DeckMenu * _menu, const string& path, const string& smallDeckPrefix, vector<DeckMetaData *> GameState::fillDeckMenu(DeckMenu * _menu, const string& path, const string& smallDeckPrefix,
Player * statsPlayer) Player * statsPlayer, int maxDecks)
{ {
bool translate = _menu->mAutoTranslate; bool translate = _menu->mAutoTranslate;
_menu->mAutoTranslate = false; _menu->mAutoTranslate = false;
vector<DeckMetaData *> deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer); vector<DeckMetaData *> deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer, maxDecks);
renderDeckMenu(_menu, deckMetaDataVector); renderDeckMenu(_menu, deckMetaDataVector);
_menu->mAutoTranslate = translate; _menu->mAutoTranslate = translate;
return deckMetaDataVector; return deckMetaDataVector;
} }
vector<DeckMetaData *> GameState::getValidDeckMetaData(const string& path, const string& smallDeckPrefix, Player * statsPlayer) vector<DeckMetaData *> GameState::getValidDeckMetaData(const string& path, const string& smallDeckPrefix, Player * statsPlayer, int maxDecks)
{ {
vector<DeckMetaData*> retList; vector<DeckMetaData*> retList;
DeckMetaDataList * metas = DeckMetaDataList::decksMetaData; DeckMetaDataList * metas = DeckMetaDataList::decksMetaData;
int found = 1; int found = 1;
int nbDecks = 1; int nbDecks = 1;
while (found) while (found && (!maxDecks || nbDecks <= maxDecks))
{ {
found = 0; found = 0;
std::ostringstream filename; std::ostringstream filename;

View File

@@ -283,7 +283,7 @@ void GameStateDuel::ensureOpponentMenu()
if (options[Options::EVILTWIN_MODE_UNLOCKED].number) opponentMenu->Add(MENUITEM_EVIL_TWIN, "Evil Twin", _( if (options[Options::EVILTWIN_MODE_UNLOCKED].number) opponentMenu->Add(MENUITEM_EVIL_TWIN, "Evil Twin", _(
"Can you play against yourself?").c_str()); "Can you play against yourself?").c_str());
DeckManager * deckManager = DeckManager::GetInstance(); DeckManager * deckManager = DeckManager::GetInstance();
vector<DeckMetaData*> opponentDeckList = fillDeckMenu(opponentMenu, JGE_GET_RES("ai/baka"), "ai_baka", mPlayers[0]); vector<DeckMetaData*> opponentDeckList = fillDeckMenu(opponentMenu, JGE_GET_RES("ai/baka"), "ai_baka", mPlayers[0], options[Options::AIDECKS_UNLOCKED].number);
deckManager->updateMetaDataList(&opponentDeckList, true); deckManager->updateMetaDataList(&opponentDeckList, true);
opponentMenu->Add(MENUITEM_CANCEL, "Cancel", _("Choose a different player deck").c_str()); opponentMenu->Add(MENUITEM_CANCEL, "Cancel", _("Choose a different player deck").c_str());
opponentDeckList.clear(); opponentDeckList.clear();

View File

@@ -189,9 +189,13 @@ void Task::passOneDay()
void Task::loadAIDeckNames() void Task::loadAIDeckNames()
{ {
//check if cache is up to date
if (AIDeckNames.size() == (unsigned int)(options[Options::AIDECKS_UNLOCKED].number)) return;
AIDeckNames.clear();
int found = 1; int found = 1;
int nbDecks = 0; int nbDecks = 0;
while (found) while (found && nbDecks < options[Options::AIDECKS_UNLOCKED].number)
{ {
found = 0; found = 0;
char buffer[512]; char buffer[512];
@@ -211,19 +215,13 @@ void Task::loadAIDeckNames()
int Task::getAIDeckCount() int Task::getAIDeckCount()
{ {
if (AIDeckNames.size() == 0) loadAIDeckNames();
{
loadAIDeckNames();
}
return AIDeckNames.size(); return AIDeckNames.size();
} }
string Task::getAIDeckName(int id) string Task::getAIDeckName(int id)
{ {
if (AIDeckNames.size() == 0) loadAIDeckNames();
{
loadAIDeckNames();
}
return ((unsigned int) id <= AIDeckNames.size()) ? AIDeckNames.at(id - 1) : "<Undefined>"; return ((unsigned int) id <= AIDeckNames.size()) ? AIDeckNames.at(id - 1) : "<Undefined>";
} }

View File

@@ -265,39 +265,39 @@ std::string wordWrap(std::string sentence, int width)
// Given a delimited string of abilities, add the ones to the list that are "Basic" MTG abilities // Given a delimited string of abilities, add the ones to the list that are "Basic" MTG abilities
void PopulateAbilityIndexVector( list<int>& abilities, const string& abilityStringList, char delimiter ) void PopulateAbilityIndexVector( list<int>& abilities, const string& abilityStringList, char delimiter )
{ {
vector<string> abilitiesList = split( abilityStringList, delimiter); vector<string> abilitiesList = split( abilityStringList, delimiter);
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter) for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
{ {
int abilityIndex = Constants::GetBasicAbilityIndex( *iter ); int abilityIndex = Constants::GetBasicAbilityIndex( *iter );
if (abilityIndex != -1) if (abilityIndex != -1)
abilities.push_back( abilityIndex ); abilities.push_back( abilityIndex );
} }
} }
void PopulateColorIndexVector( list<int>& colors, const string& colorStringList, char delimiter ) void PopulateColorIndexVector( list<int>& colors, const string& colorStringList, char delimiter )
{ {
vector<string> abilitiesList = split( colorStringList, delimiter); vector<string> abilitiesList = split( colorStringList, delimiter);
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter) for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
{ {
for (int colorIndex = Constants::MTG_COLOR_ARTIFACT; colorIndex < Constants::MTG_NB_COLORS; ++colorIndex) for (int colorIndex = Constants::MTG_COLOR_ARTIFACT; colorIndex < Constants::MTG_NB_COLORS; ++colorIndex)
{ {
// if the text is not a basic ability but contains a valid color add it to the color vector // if the text is not a basic ability but contains a valid color add it to the color vector
if ( (Constants::GetBasicAbilityIndex( *iter ) != -1) && ((*iter).find( Constants::MTGColorStrings[ colorIndex ] ) != string::npos) ) if ( (Constants::GetBasicAbilityIndex( *iter ) != -1) && ((*iter).find( Constants::MTGColorStrings[ colorIndex ] ) != string::npos) )
colors.push_back(colorIndex); colors.push_back(colorIndex);
} }
} }
} }
void PopulateSubtypesIndexVector( list<int>& types, const string& subTypesStringList, char delimiter) void PopulateSubtypesIndexVector( list<int>& types, const string& subTypesStringList, char delimiter)
{ {
vector<string> subTypesList = split( subTypesStringList, delimiter); vector<string> subTypesList = split( subTypesStringList, delimiter);
for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it) for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it)
{ {
string subtype = *it; string subtype = *it;
size_t id = Subtypes::subtypesList->find( subtype ); size_t id = Subtypes::subtypesList->find( subtype );
if ( id != string::npos ) if ( id != string::npos )
types.push_back(id); types.push_back(id);
} }
} }