- 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{
private:
time_t gameLength;
int isDifficultyUnlocked();
int isDifficultyUnlocked(DeckStats * stats);
int isMomirUnlocked();
int isEvilTwinUnlocked();
int isRandomDeckUnlocked();
int IsMoreAIDecksUnlocked(DeckStats * stats);
public:
int value;
Player * p1, *p2;

View File

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

View File

@@ -52,6 +52,7 @@ public:
GUI_STYLE,
INTERRUPT_SECONDS,
KEY_BINDINGS,
AIDECKS_UNLOCKED,
//My interrupts
INTERRUPTMYSPELLS,
INTERRUPTMYABILITIES,
@@ -75,7 +76,7 @@ public:
MOMIR_MODE_UNLOCKED,
EVILTWIN_MODE_UNLOCKED,
RANDOMDECK_MODE_UNLOCKED,
AWARD_COLLECTOR,
AWARD_COLLECTOR,
LAST_NAMED, //Any option after this does not look up in optionNames.
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);
// 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.
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 *>
static void renderDeckMenu(SimpleMenu * _menu, const vector<DeckMetaData *>& deckMetaDataList);

View File

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

View File

@@ -119,7 +119,9 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
if (unlocked == -1)
{
unlocked = isDifficultyUnlocked();
DeckStats * stats = DeckStats::GetInstance();
stats->load(p1);
unlocked = isDifficultyUnlocked(stats);
if (unlocked)
{
unlockedTex = resources.RetrieveTexture("unlocked.png");
@@ -160,6 +162,12 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
if (si)
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)
{
@@ -292,15 +300,14 @@ void Credits::Render()
}
int Credits::isDifficultyUnlocked()
int Credits::isDifficultyUnlocked(DeckStats * stats)
{
if (options[Options::DIFFICULTY_MODE_UNLOCKED].number)
return 0;
int nbAIDecks = 0;
int found = 1;
int wins = 0;
DeckStats * stats = DeckStats::GetInstance();
stats->load(p1);
while (found)
{
found = 0;
@@ -424,3 +431,31 @@ int Credits::unlockRandomSet(bool force)
options.save();
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);
SAFE_DELETE(mScroller);
mScroller = NULL;
}

View File

@@ -3,6 +3,7 @@
#include "DeckMenuItem.h"
#include "Translate.h"
#include "WResourceManager.h"
#include <algorithm>
#define ITEM_PX_WIDTH 190.f
const int kHorizontalScrollSpeed = 10; // lower numbers mean faster scrolling
@@ -62,6 +63,19 @@ void DeckMenuItem::RenderWithOffset(float yOffset)
mScrollTimer = 0;
else if (mHasFocus && mScrollEnabled)
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()

View File

@@ -39,6 +39,7 @@ const string Options::optionNames[] = {
"keybindings_psp",
#endif
#endif
"aidecks",
"interruptMySpells",
"interruptMyAbilities",
//General interrupts
@@ -342,6 +343,9 @@ int GameOptions::load()
if (!(*this)[Options::MAX_GRADE].number)
(*this)[Options::MAX_GRADE].number = Constants::GRADE_BORDERLINE;
if (!(*this)[Options::AIDECKS_UNLOCKED].number)
(*this)[Options::AIDECKS_UNLOCKED].number = 10;
return 1;
}
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,
Player * statsPlayer)
Player * statsPlayer, int maxDecks)
{
bool translate = _menu->mAutoTranslate;
_menu->mAutoTranslate = false;
vector<DeckMetaData *> deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer);
vector<DeckMetaData *> deckMetaDataVector = getValidDeckMetaData(path, smallDeckPrefix, statsPlayer, maxDecks);
renderDeckMenu(_menu, deckMetaDataVector);
_menu->mAutoTranslate = translate;
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;
DeckMetaDataList * metas = DeckMetaDataList::decksMetaData;
int found = 1;
int nbDecks = 1;
while (found)
while (found && (!maxDecks || nbDecks <= maxDecks))
{
found = 0;
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", _(
"Can you play against yourself?").c_str());
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);
opponentMenu->Add(MENUITEM_CANCEL, "Cancel", _("Choose a different player deck").c_str());
opponentDeckList.clear();

View File

@@ -189,9 +189,13 @@ void Task::passOneDay()
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 nbDecks = 0;
while (found)
while (found && nbDecks < options[Options::AIDECKS_UNLOCKED].number)
{
found = 0;
char buffer[512];
@@ -211,19 +215,13 @@ void Task::loadAIDeckNames()
int Task::getAIDeckCount()
{
if (AIDeckNames.size() == 0)
{
loadAIDeckNames();
}
loadAIDeckNames();
return AIDeckNames.size();
}
string Task::getAIDeckName(int id)
{
if (AIDeckNames.size() == 0)
{
loadAIDeckNames();
}
loadAIDeckNames();
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
void PopulateAbilityIndexVector( list<int>& abilities, const string& abilityStringList, char delimiter )
{
vector<string> abilitiesList = split( abilityStringList, delimiter);
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
{
int abilityIndex = Constants::GetBasicAbilityIndex( *iter );
if (abilityIndex != -1)
abilities.push_back( abilityIndex );
vector<string> abilitiesList = split( abilityStringList, delimiter);
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
{
int abilityIndex = Constants::GetBasicAbilityIndex( *iter );
if (abilityIndex != -1)
abilities.push_back( abilityIndex );
}
}
void PopulateColorIndexVector( list<int>& colors, const string& colorStringList, char delimiter )
{
vector<string> abilitiesList = split( colorStringList, delimiter);
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
{
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 ( (Constants::GetBasicAbilityIndex( *iter ) != -1) && ((*iter).find( Constants::MTGColorStrings[ colorIndex ] ) != string::npos) )
colors.push_back(colorIndex);
}
vector<string> abilitiesList = split( colorStringList, delimiter);
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
{
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 ( (Constants::GetBasicAbilityIndex( *iter ) != -1) && ((*iter).find( Constants::MTGColorStrings[ colorIndex ] ) != string::npos) )
colors.push_back(colorIndex);
}
}
}
void PopulateSubtypesIndexVector( list<int>& types, const string& subTypesStringList, char delimiter)
{
vector<string> subTypesList = split( subTypesStringList, delimiter);
for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it)
{
string subtype = *it;
size_t id = Subtypes::subtypesList->find( subtype );
if ( id != string::npos )
types.push_back(id);
vector<string> subTypesList = split( subTypesStringList, delimiter);
for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it)
{
string subtype = *it;
size_t id = Subtypes::subtypesList->find( subtype );
if ( id != string::npos )
types.push_back(id);
}
}