#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 "PlayerData.h"
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;
}
Credits::~Credits()
{
for (unsigned int i = 0; i < bonus.size(); ++i)
if (bonus[i])
delete bonus[i];
bonus.clear();
}
void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
{
p1 = _p1;
p2 = _p2;
app = _app;
showMsg = (WRand() % 3);
GameObserver * g = GameObserver::GetInstance();
if (!g->turn)
return;
PlayerData * playerdata = NEW PlayerData(MTGCollection());
if (!p1->isAI() && p2->isAI() && p1 != g->gameOver)
{
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 > 500)
diff = 500;
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;
//
vector finishedTasks;
playerdata->taskList->getDoneTasks(_p1, _p2, _app, &finishedTasks);
char buffer[512];
for (vector::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);
}
//
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();
options.save();
}
else if ((unlocked = isMomirUnlocked()))
{
unlockedTextureName = "momir_unlocked.png";
goa = (GameOptionAward*) &options[Options::MOMIR_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isStoneHewerUnlocked()))
{
//unlockedTextureName = "stonehewer_unlocked.png";//until we can find a nice free use font.
CreditBonus * b = NEW CreditBonus(0, _("Stone Hewer Basic Unlocked"));
bonus.push_back(b);
goa = (GameOptionAward*) &options[Options::STONEHEWER_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isHermitUnlocked()))
{
//unlockedTextureName = "hermit_unlocked.png";//until we can find a nice free use font.
CreditBonus * b = NEW CreditBonus(0, _("Hermit Druid Basic Unlocked"));
bonus.push_back(b);
goa = (GameOptionAward*) &options[Options::HERMIT_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isEvilTwinUnlocked()))
{
unlockedTextureName = "eviltwin_unlocked.png";
goa = (GameOptionAward*) &options[Options::EVILTWIN_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
else if ((unlocked = isRandomDeckUnlocked()))
{
unlockedTextureName = "randomdeck_unlocked.png";
goa = (GameOptionAward*) &options[Options::RANDOMDECK_MODE_UNLOCKED];
goa->giveAward();
options.save();
}
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)
{
JSample * sample = WResourceManager::Instance()->RetrieveSample("bonus.wav");
if (sample)
{
JSoundSystem::GetInstance()->PlaySample(sample);
}
}
}
vector::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);
}
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(unlockedTex->mWidth - 4),
static_cast(unlockedTex->mHeight - 4));
}
void Credits::Render()
{
if (!p1)
return;
GameObserver * g = GameObserver::GetInstance();
JRenderer * r = JRenderer::GetInstance();
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 (!g->turn)
{
sprintf(buffer, "%s", _("Please check your deck (not enough cards?)").c_str());
}
else
{
if (!p1->isAI() && p2->isAI())
{
if (g->gameOver != p1)
{
sprintf(buffer, _("Congratulations! You earn %i credits").c_str(), value);
JQuadPtr unlockedQuad = GetUnlockedQuad(unlockedTextureName);
if (unlockedQuad)
{
showMsg = 0;
r->RenderQuad(unlockedQuad.get(), 20, 20);
}
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 (g->gameOver != 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::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 (g->gameOver != p1)
{
sprintf(buffer, _("Game length: %i turns (%i seconds)").c_str(), g->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 = 0;
int found = 1;
int wins = 0;
while (found)
{
found = 0;
char buffer[512];
char aiSmallDeckName[512];
sprintf(buffer, JGE_GET_RES("ai/baka/deck%i.txt").c_str(), nbAIDecks + 1);
if (fileExists(buffer))
{
found = 1;
nbAIDecks++;
sprintf(aiSmallDeckName, "ai_baka_deck%i", nbAIDecks);
int percentVictories = stats->percentVictories(string(aiSmallDeckName));
if (percentVictories >= 67)
wins++;
if (wins >= 10)
return 1;
}
}
return 0;
}
int Credits::isMomirUnlocked()
{
if (options[Options::MOMIR_MODE_UNLOCKED].number)
return 0;
if (p1->game->inPlay->countByType("land") == 8)
return 1;
return 0;
}
int Credits::isStoneHewerUnlocked()
{
if (options[Options::STONEHEWER_MODE_UNLOCKED].number)
return 0;
if (int(p1->game->inPlay->countByType("equipment") + p1->opponent()->game->inPlay->countByType("equipment")) > 10)
return 1;
return 0;
}
int Credits::isHermitUnlocked()
{
if (options[Options::HERMIT_MODE_UNLOCKED].number)
return 0;
if (int(p1->game->inPlay->countByType("land")) < 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;
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);
wagic::ifstream file(buffer);
if (file)
{
found = 1;
file.close();
nbdecks++;
if (nbdecks > currentlyUnlocked)
return 1;
}
}
return 0;
}