Erwan
- 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:
BIN
projects/mtg/bin/Res/graphics/ai_unlocked.png
Normal file
BIN
projects/mtg/bin/Res/graphics/ai_unlocked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
projects/mtg/bin/Res/graphics/new.png
Normal file
BIN
projects/mtg/bin/Res/graphics/new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -336,5 +336,4 @@ DeckMenu::~DeckMenu()
|
|||||||
{
|
{
|
||||||
resources.Release(pspIconsTexture);
|
resources.Release(pspIconsTexture);
|
||||||
SAFE_DELETE(mScroller);
|
SAFE_DELETE(mScroller);
|
||||||
mScroller = NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user