758 lines
22 KiB
C++
758 lines
22 KiB
C++
#include "PrecompiledHeader.h"
|
|
|
|
#include "Credits.h"
|
|
#include "GameApp.h"
|
|
#include "PlayerData.h"
|
|
#include "DeckStats.h"
|
|
#include "Translate.h"
|
|
#include "MTGDeck.h"
|
|
#include "GameObserver.h"
|
|
#include "GameStateShop.h"
|
|
#include "AIPlayer.h"
|
|
|
|
|
|
map <string, Unlockable *> Unlockable::unlockables;
|
|
|
|
Unlockable::Unlockable()
|
|
{
|
|
}
|
|
|
|
void Unlockable::setValue(string k , string v)
|
|
{
|
|
mValues[k] = v;
|
|
}
|
|
|
|
string Unlockable::getValue(string k)
|
|
{
|
|
return mValues[k];
|
|
}
|
|
|
|
bool Unlockable::isUnlocked() {
|
|
string id = getValue("id");
|
|
assert(id.size() > 0);
|
|
return (options[id].number != 0);
|
|
}
|
|
|
|
bool Unlockable::tryToUnlock(GameObserver * game) {
|
|
if (isUnlocked())
|
|
return false;
|
|
|
|
string conditions = getValue("unlock_condition");
|
|
|
|
Player * p = game->players[0];
|
|
if (p->isAI())
|
|
return false;
|
|
|
|
// We need a card belonging to the player in order to call parceCastRestrictions
|
|
// The goal is usually to create objects such as targetChoosers, that are usually required
|
|
// for protection, or determining the card's owner
|
|
//Therefore here any card is ok
|
|
MTGCardInstance * dummyCard = p->game->battlefield->nb_cards
|
|
? p->game->battlefield->cards[0]
|
|
: p->game->hand->nb_cards
|
|
? p->game->hand->cards[0]
|
|
: p->game->library->nb_cards
|
|
? p->game->library->cards[0]
|
|
: NULL;
|
|
|
|
AbilityFactory af(game);
|
|
int meetConditions = conditions.size()
|
|
? dummyCard
|
|
? af.parseCastRestrictions(dummyCard, p, conditions)
|
|
: 0
|
|
: 1;
|
|
|
|
if (!meetConditions)
|
|
return false;
|
|
|
|
// Unlock the award and return
|
|
string id = getValue("id");
|
|
assert(id.size() > 0);
|
|
|
|
GameOptionAward* goa = (GameOptionAward*) &options[id];
|
|
goa->giveAward();
|
|
return true;
|
|
}
|
|
|
|
void Unlockable::load()
|
|
{
|
|
std::string contents;
|
|
if (! JFileSystem::GetInstance()->readIntoString("rules/awards.dat", contents))
|
|
return;
|
|
|
|
std::stringstream stream(contents);
|
|
std::string s;
|
|
|
|
Unlockable * current = NULL;
|
|
while (std::getline(stream, s))
|
|
{
|
|
if (!s.size()) continue;
|
|
if (s[s.size() - 1] == '\r') s.erase(s.size() - 1); //Handle DOS files
|
|
if (!s.size()) continue;
|
|
if (s[0] == '#') continue;
|
|
|
|
if (s == "[award]")
|
|
{
|
|
current = NEW Unlockable();
|
|
continue;
|
|
}
|
|
|
|
|
|
if (!current)
|
|
continue;
|
|
|
|
if (s == "[/award]")
|
|
{
|
|
string id = current->getValue("id");
|
|
|
|
if (id.size())
|
|
unlockables[id] = current;
|
|
else
|
|
SAFE_DELETE(current);
|
|
|
|
continue;
|
|
}
|
|
|
|
vector<string> keyValue = split(s,'=');
|
|
if (keyValue.size() != 2)
|
|
continue;
|
|
|
|
current->setValue(keyValue[0], keyValue[1]);
|
|
}
|
|
}
|
|
|
|
void Unlockable::Destroy()
|
|
{
|
|
for (map<string, Unlockable *>::iterator it = unlockables.begin(); it != unlockables.end(); ++it) {
|
|
SAFE_DELETE(it->second);
|
|
}
|
|
unlockables.clear();
|
|
}
|
|
|
|
CreditBonus::CreditBonus(int _value, string _text)
|
|
{
|
|
value = _value;
|
|
text = _text;
|
|
}
|
|
|
|
void CreditBonus::Render(float x, float y, WFont * font)
|
|
{
|
|
char buffer[512];
|
|
sprintf(buffer, "%s: %i", text.c_str(), value);
|
|
font->DrawString(buffer, x, y);
|
|
}
|
|
|
|
Credits::Credits()
|
|
{
|
|
unlocked = -1;
|
|
p1 = NULL;
|
|
p2 = NULL;
|
|
observer = NULL;
|
|
mTournament=false;
|
|
mMatch=false;
|
|
mPlayerWin=false;
|
|
mGamesWon=0;
|
|
mGamesPlayed=0;
|
|
mMatchesWon=0;
|
|
mMatchesPlayed=0;
|
|
}
|
|
|
|
Credits::~Credits()
|
|
{
|
|
for (unsigned int i = 0; i < bonus.size(); ++i)
|
|
if (bonus[i])
|
|
delete bonus[i];
|
|
bonus.clear();
|
|
}
|
|
|
|
void Credits::compute(GameObserver* g, GameApp * _app)
|
|
{
|
|
if (!g->turn)
|
|
return;
|
|
p1 = g->players[0];
|
|
p2 = g->players[1];
|
|
observer = g;
|
|
app = _app;
|
|
showMsg = (WRand() % 3);
|
|
|
|
//no credits when the AI plays :)
|
|
if (p1->isAI())
|
|
return;
|
|
|
|
PlayerData * playerdata = NEW PlayerData(MTGCollection());
|
|
if (p2->isAI() && g->didWin(p1))
|
|
{
|
|
gameLength = time(0) - g->startedAt;
|
|
value = 400;
|
|
if (app->gameType != GAME_TYPE_CLASSIC)
|
|
value = 200;
|
|
int difficulty = options[Options::DIFFICULTY].number;
|
|
if (options[Options::DIFFICULTY_MODE_UNLOCKED].number && difficulty)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(100 * difficulty, _("Difficulty Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
if (p1->life == 1)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(111, _("'Live dangerously and you live right' Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
int diff = p1->life - p2->life;
|
|
if (diff < 0)
|
|
diff = 0;
|
|
if (diff > 10000)
|
|
diff = 10000;
|
|
if (diff)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(diff, _("Life Delta Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
if (p1->game->library->nb_cards == 0)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(391, _("'Decree of Theophilus' Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
if ((p2->game->library->nb_cards == 0) && p1->game->library->nb_cards)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(p1->game->library->nb_cards * 3, _("Miller Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
if (g->turn < 15)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus((20 - g->turn) * 17, _("'Fast and Furious' Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
GameOptionAward * goa = NULL;
|
|
// <Tasks handling>
|
|
vector<Task*> finishedTasks;
|
|
playerdata->taskList->getDoneTasks(g, _app, &finishedTasks);
|
|
|
|
char buffer[512];
|
|
|
|
for (vector<Task*>::iterator it = finishedTasks.begin(); it != finishedTasks.end(); it++)
|
|
{
|
|
sprintf(buffer, _("Task: %s").c_str(), (*it)->getShortDesc().c_str());
|
|
CreditBonus * b = NEW CreditBonus((*it)->getReward(), buffer);
|
|
bonus.push_back(b);
|
|
playerdata->taskList->removeTask(*it);
|
|
}
|
|
// </Tasks handling>
|
|
|
|
if (unlocked == -1)
|
|
{
|
|
DeckStats * stats = DeckStats::GetInstance();
|
|
stats->load(p1->GetCurrentDeckStatsFile());
|
|
unlocked = isDifficultyUnlocked(stats);
|
|
if (unlocked)
|
|
{
|
|
unlockedTextureName = "unlocked.png";
|
|
goa = (GameOptionAward*) &options[Options::DIFFICULTY_MODE_UNLOCKED];
|
|
goa->giveAward();
|
|
}
|
|
else
|
|
{
|
|
for (map<string, Unlockable *>::iterator it = Unlockable::unlockables.begin(); it != Unlockable::unlockables.end(); ++it) {
|
|
Unlockable * award = it->second;
|
|
if (award->tryToUnlock(g))
|
|
{
|
|
unlocked = 1;
|
|
unlockedString = award->getValue("unlock_text");
|
|
unlockedTextureName = award->getValue("unlock_img");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!unlocked)
|
|
{
|
|
if ((unlocked = isEvilTwinUnlocked()))
|
|
{
|
|
unlockedTextureName = "eviltwin_unlocked.png";
|
|
goa = (GameOptionAward*) &options[Options::EVILTWIN_MODE_UNLOCKED];
|
|
goa->giveAward();
|
|
}
|
|
else if ((unlocked = isRandomDeckUnlocked()))
|
|
{
|
|
unlockedTextureName = "randomdeck_unlocked.png";
|
|
goa = (GameOptionAward*) &options[Options::RANDOMDECK_MODE_UNLOCKED];
|
|
goa->giveAward();
|
|
}
|
|
else if ((unlocked = unlockRandomSet()))
|
|
{
|
|
unlockedTextureName = "set_unlocked.png";
|
|
MTGSetInfo * si = setlist.getInfo(unlocked - 1);
|
|
if (si)
|
|
unlockedString = si->getName(); //Show the set's pretty name for unlocks.
|
|
}
|
|
else if ((unlocked = IsMoreAIDecksUnlocked(stats)))
|
|
{
|
|
options[Options::AIDECKS_UNLOCKED].number += 10;
|
|
options.save();
|
|
unlockedTextureName = "ai_unlocked.png";
|
|
}
|
|
}
|
|
|
|
if (unlocked && options[Options::SFXVOLUME].number > 0)
|
|
{
|
|
WResourceManager::Instance()->PlaySample("bonus.wav");
|
|
}
|
|
|
|
}
|
|
|
|
vector<CreditBonus *>::iterator it;
|
|
if (bonus.size())
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(value, _("Victory"));
|
|
bonus.insert(bonus.begin(), b);
|
|
for (it = bonus.begin() + 1; it < bonus.end(); ++it)
|
|
value += (*it)->value;
|
|
}
|
|
|
|
playerdata->credits += value;
|
|
PriceList::updateKey();
|
|
playerdata->taskList->passOneDay();
|
|
if (playerdata->taskList->getTaskCount() < 6)
|
|
{
|
|
playerdata->taskList->addRandomTask();
|
|
playerdata->taskList->addRandomTask();
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
unlocked = 0;
|
|
playerdata->taskList->passOneDay();
|
|
}
|
|
|
|
playerdata->save();
|
|
SAFE_DELETE(playerdata);
|
|
}
|
|
|
|
/////// Tournament Mod ///////////
|
|
void Credits::computeTournament(GameObserver* g, GameApp * _app,bool tournament,bool match,bool playerWin,int gamesWon,int gamesPlayed,int matchesWon,int matchesPlayed)
|
|
{
|
|
mTournament=tournament;
|
|
mMatch=match;
|
|
mPlayerWin=playerWin;
|
|
mGamesWon=gamesWon;
|
|
mGamesPlayed=gamesPlayed;
|
|
mMatchesWon=matchesWon;
|
|
mMatchesPlayed=matchesPlayed;
|
|
|
|
if (!g->turn)
|
|
return;
|
|
p1 = g->players[0];
|
|
p2 = g->players[1];
|
|
observer = g;
|
|
app = _app;
|
|
showMsg = (WRand() % 3);
|
|
|
|
//no credits when the AI plays :)
|
|
if (p1->isAI())
|
|
return;
|
|
|
|
PlayerData * playerdata = NEW PlayerData(MTGCollection());
|
|
if (p2->isAI() && mPlayerWin)
|
|
{
|
|
value = 400;
|
|
if (app->gameType != GAME_TYPE_CLASSIC)
|
|
value = 200;
|
|
int difficulty = options[Options::DIFFICULTY].number;
|
|
if (options[Options::DIFFICULTY_MODE_UNLOCKED].number && difficulty)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(100 * mGamesWon * difficulty, _("Difficulty Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
if (mGamesWon>1)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(mGamesWon * 200, _("Won Game Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
if (mMatchesWon>1)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(mMatchesWon * 200, _("Won Matches Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
if ((mGamesWon==mGamesPlayed && mGamesPlayed>0) || (matchesWon==mMatchesPlayed && mMatchesPlayed>0))
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(500, _("Perfect Bonus"));
|
|
bonus.push_back(b);
|
|
}
|
|
if (mGamesWon>mGamesPlayed*0.80 && mGamesWon<mGamesPlayed)
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(250, _("Won more than 80 percentage of games"));
|
|
bonus.push_back(b);
|
|
}
|
|
|
|
|
|
GameOptionAward * goa = NULL;
|
|
// <Tasks handling>
|
|
|
|
// </Tasks handling>
|
|
|
|
if (unlocked == -1)
|
|
{
|
|
DeckStats * stats = DeckStats::GetInstance();
|
|
stats->load(p1->GetCurrentDeckStatsFile());
|
|
unlocked = isDifficultyUnlocked(stats);
|
|
if (unlocked)
|
|
{
|
|
unlockedTextureName = "unlocked.png";
|
|
goa = (GameOptionAward*) &options[Options::DIFFICULTY_MODE_UNLOCKED];
|
|
goa->giveAward();
|
|
}
|
|
else
|
|
{
|
|
for (map<string, Unlockable *>::iterator it = Unlockable::unlockables.begin(); it != Unlockable::unlockables.end(); ++it) {
|
|
Unlockable * award = it->second;
|
|
if (award->tryToUnlock(g))
|
|
{
|
|
unlocked = 1;
|
|
unlockedString = award->getValue("unlock_text");
|
|
unlockedTextureName = award->getValue("unlock_img");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!unlocked)
|
|
{
|
|
// EvilTwin and RandomDeck cannot be unlocked in tournamentmode
|
|
// for each won game, one change to unlock a set
|
|
for (int i=0;i<mGamesWon;i++){
|
|
if (!unlocked)
|
|
unlocked = unlockRandomSet();
|
|
}
|
|
if (unlocked)
|
|
{
|
|
unlockedTextureName = "set_unlocked.png";
|
|
MTGSetInfo * si = setlist.getInfo(unlocked - 1);
|
|
if (si)
|
|
unlockedString = si->getName(); //Show the set's pretty name for unlocks.
|
|
}
|
|
}
|
|
if (!unlocked)
|
|
{
|
|
if ((unlocked = IsMoreAIDecksUnlocked(stats)))
|
|
{
|
|
options[Options::AIDECKS_UNLOCKED].number += 10;
|
|
options.save();
|
|
unlockedTextureName = "ai_unlocked.png";
|
|
}
|
|
}
|
|
|
|
if (unlocked && options[Options::SFXVOLUME].number > 0)
|
|
{
|
|
WResourceManager::Instance()->PlaySample("bonus.wav");
|
|
}
|
|
|
|
}
|
|
|
|
vector<CreditBonus *>::iterator it;
|
|
if (bonus.size())
|
|
{
|
|
CreditBonus * b = NEW CreditBonus(value, _("Victory"));
|
|
bonus.insert(bonus.begin(), b);
|
|
for (it = bonus.begin() + 1; it < bonus.end(); ++it)
|
|
value += (*it)->value;
|
|
}
|
|
|
|
playerdata->credits += value;
|
|
PriceList::updateKey();
|
|
playerdata->taskList->passOneDay();
|
|
if (playerdata->taskList->getTaskCount() < 6)
|
|
{
|
|
playerdata->taskList->addRandomTask();
|
|
playerdata->taskList->addRandomTask();
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
unlocked = 0;
|
|
playerdata->taskList->passOneDay();
|
|
}
|
|
|
|
playerdata->save();
|
|
SAFE_DELETE(playerdata);
|
|
}
|
|
/////// END Tournament Mod ///////////
|
|
|
|
JQuadPtr Credits::GetUnlockedQuad(string textureName)
|
|
{
|
|
if (!textureName.size()) return JQuadPtr();
|
|
|
|
JTexture * unlockedTex = WResourceManager::Instance()->RetrieveTexture(textureName);
|
|
if (!unlockedTex) return JQuadPtr();
|
|
|
|
return WResourceManager::Instance()->RetrieveQuad(
|
|
unlockedTextureName,
|
|
2.0f,
|
|
2.0f,
|
|
static_cast<float>(unlockedTex->mWidth - 4),
|
|
static_cast<float>(unlockedTex->mHeight - 4));
|
|
|
|
}
|
|
|
|
void Credits::Render()
|
|
{
|
|
if (!p1)
|
|
return;
|
|
JRenderer * r = JRenderer::GetInstance();
|
|
JTexture * wpTex = WResourceManager::Instance()->RetrieveTexture("bgdeckeditor.jpg");
|
|
if (wpTex)
|
|
{
|
|
JQuadPtr wpQuad = WResourceManager::Instance()->RetrieveTempQuad("bgdeckeditor.jpg");
|
|
JRenderer::GetInstance()->RenderQuad(wpQuad.get(), 0, 0, 0, SCREEN_WIDTH_F / wpQuad->mWidth, SCREEN_HEIGHT_F / wpQuad->mHeight);
|
|
}
|
|
WFont * f = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT);
|
|
WFont * f2 = WResourceManager::Instance()->GetWFont(Fonts::MENU_FONT);
|
|
WFont * f3 = WResourceManager::Instance()->GetWFont(Fonts::MAGIC_FONT);
|
|
f->SetScale(1);
|
|
f->SetColor(ARGB(255,255,255,255));
|
|
f2->SetScale(1);
|
|
f2->SetColor(ARGB(255,255,255,255));
|
|
f3->SetScale(1);
|
|
f3->SetColor(ARGB(255,255,255,255));
|
|
char buffer[512];
|
|
|
|
if (!observer->turn)
|
|
{
|
|
sprintf(buffer, "%s", _("Please check your deck (not enough cards?)").c_str());
|
|
}
|
|
else
|
|
{
|
|
if (!p1->isAI() && p2->isAI())
|
|
{
|
|
if (observer->didWin(p1) || mPlayerWin)
|
|
{
|
|
sprintf(buffer, _("Congratulations! You earn %i credits").c_str(), value);
|
|
JQuadPtr unlockedQuad = GetUnlockedQuad(unlockedTextureName);
|
|
if (unlockedQuad)
|
|
{
|
|
showMsg = 0;
|
|
unlockedQuad->SetHotSpot(unlockedQuad->mWidth/2,0);
|
|
r->RenderQuad(unlockedQuad.get(), SCREEN_WIDTH_F/2, 20, 0, 400.f / unlockedQuad->mWidth, 100.f / unlockedQuad->mHeight);
|
|
}
|
|
if (unlockedString.size())
|
|
{
|
|
f2->DrawString(unlockedString.c_str(), SCREEN_WIDTH / 2, 80, JGETEXT_CENTER);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(buffer, "%s", _("You have been defeated").c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int winner = 2;
|
|
if (observer->didWin(p1))
|
|
{
|
|
winner = 1;
|
|
}
|
|
int p0life = p1->life;
|
|
sprintf(buffer, _("Player %i wins (%i)").c_str(), winner, p0life);
|
|
}
|
|
}
|
|
|
|
float y = 130;
|
|
|
|
if (showMsg == 1)
|
|
y = 50;
|
|
vector<CreditBonus *>::iterator it;
|
|
for (it = bonus.begin(); it < bonus.end(); ++it)
|
|
{
|
|
(*it)->Render(10, y, f3);
|
|
y += 12;
|
|
}
|
|
f2->DrawString(buffer, 10, y);
|
|
y += 15;
|
|
|
|
//!!
|
|
|
|
if (mMatch){
|
|
if (mGamesPlayed>0){
|
|
sprintf(buffer, _("Games Won: %i of %i (%i %%)").c_str(), mGamesWon,mGamesPlayed, (int)(mGamesWon*100/mGamesPlayed));
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
}
|
|
if (value>0 && mGamesPlayed>0){
|
|
sprintf(buffer, _("Credits per game: %i").c_str(), (int) (value / mGamesPlayed));
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
}
|
|
showMsg = 0;
|
|
|
|
} else if (mTournament){
|
|
if (mGamesPlayed>0){
|
|
sprintf(buffer, _("Games Won: %i of %i (%i %%)").c_str(),mGamesWon, mGamesPlayed,(int)(mGamesWon*100/mGamesPlayed));
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
}
|
|
if (mMatchesPlayed>0){
|
|
sprintf(buffer, _("Matches Won: %i of %i (%i %%)").c_str(),mMatchesWon, mMatchesPlayed,(int)(mMatchesWon*100/mMatchesPlayed));
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
}
|
|
if (value>0 && mGamesPlayed>0){
|
|
sprintf(buffer, _("Credits per game: %i").c_str(), (int) (value / mGamesPlayed));
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
}
|
|
showMsg = 0;
|
|
}
|
|
else if (observer->didWin(p1) && this->gameLength != 0)
|
|
{
|
|
sprintf(buffer, _("Game length: %i turns (%i seconds)").c_str(), observer->turn, this->gameLength);
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
sprintf(buffer, _("Credits per minute: %i").c_str(), (int) (60 * value / this->gameLength));
|
|
f->DrawString(buffer, 10, y);
|
|
y += 10;
|
|
showMsg = 0;
|
|
}
|
|
|
|
if (showMsg == 1)
|
|
{
|
|
f2->DrawString(_("There's more!").c_str(), 10, y + 15);
|
|
f->DrawString(_("Mods, additional cards, updates and more at:").c_str(), 10, y + 30);
|
|
f2->DrawString("-> http://wololo.net/wagic", 10, y + 42);
|
|
}
|
|
|
|
}
|
|
|
|
int Credits::isDifficultyUnlocked(DeckStats * stats)
|
|
{
|
|
if (options[Options::DIFFICULTY_MODE_UNLOCKED].number)
|
|
return 0;
|
|
int nbAIDecks = AIPlayer::getTotalAIDecks();
|
|
|
|
int wins = 0;
|
|
|
|
for (int i = 0; i < nbAIDecks; ++i)
|
|
{
|
|
char aiSmallDeckName[512];
|
|
sprintf(aiSmallDeckName, "ai_baka_deck%i", i+1);
|
|
int percentVictories = stats->percentVictories(string(aiSmallDeckName));
|
|
if (percentVictories >= 67)
|
|
wins++;
|
|
if (wins >= 10)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Credits::isEvilTwinUnlocked()
|
|
{
|
|
if (options[Options::EVILTWIN_MODE_UNLOCKED].number)
|
|
return 0;
|
|
if (p1->game->inPlay->nb_cards && (p1->game->inPlay->nb_cards == p2->game->inPlay->nb_cards))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
int Credits::isRandomDeckUnlocked()
|
|
{
|
|
if (0 == options[Options::DIFFICULTY].number)
|
|
return 0;
|
|
if (options[Options::RANDOMDECK_MODE_UNLOCKED].number)
|
|
return 0;
|
|
if (p1->life >= 20)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
int Credits::addCreditBonus(int value)
|
|
{
|
|
PlayerData * playerdata = NEW PlayerData();
|
|
playerdata->credits += value;
|
|
playerdata->save();
|
|
SAFE_DELETE(playerdata);
|
|
return value;
|
|
}
|
|
/*
|
|
* adds a Card to a deck
|
|
* @param cardId id of the card
|
|
* @param collection deck representing player's collection
|
|
*/
|
|
int Credits::addCardToCollection(int cardId, MTGDeck * collection)
|
|
{
|
|
return collection->add(cardId);
|
|
}
|
|
|
|
/*
|
|
* adds a Card to player's collection
|
|
* prefer to call the above function if you want to add several cards, since saving is expensive
|
|
*/
|
|
int Credits::addCardToCollection(int cardId)
|
|
{
|
|
PlayerData * playerdata = NEW PlayerData(MTGCollection());
|
|
int result = addCardToCollection(cardId, playerdata->collection);
|
|
playerdata->collection->save();
|
|
return result;
|
|
}
|
|
|
|
int Credits::unlockSetByName(string name)
|
|
{
|
|
int setId = setlist.findSet(name);
|
|
if (setId < 0)
|
|
return 0;
|
|
|
|
GameOptionAward* goa = (GameOptionAward*) &options[Options::optionSet(setId)];
|
|
goa->giveAward();
|
|
options.save();
|
|
return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
|
|
|
|
}
|
|
|
|
int Credits::unlockRandomSet(bool force)
|
|
{
|
|
int setId = WRand() % setlist.size();
|
|
|
|
if (force)
|
|
{
|
|
int init = setId;
|
|
bool found = false;
|
|
do
|
|
{
|
|
if (1 != options[Options::optionSet(setId)].number)
|
|
found = true;
|
|
else
|
|
{
|
|
setId++;
|
|
if (setId == setlist.size())
|
|
setId = 0;
|
|
}
|
|
} while (setId != init && !found);
|
|
}
|
|
|
|
if (1 == options[Options::optionSet(setId)].number)
|
|
return 0;
|
|
|
|
GameOptionAward* goa = (GameOptionAward*) &options[Options::optionSet(setId)];
|
|
goa->giveAward();
|
|
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 1.2 times as much games as
|
|
// the number of currently unlocked decks in order to go through.
|
|
if (stats->nbGames() < currentlyUnlocked * 1.2) return 0;
|
|
|
|
if (AIPlayer::getTotalAIDecks() > currentlyUnlocked)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|