Files
wagic/projects/mtg/src/GameStateDuel.cpp
wagic.the.homebrew c3ae216f62 - Fix issue 694
- Bump version number to 0.16.0 for upcoming release
2011-07-05 13:02:41 +00:00

868 lines
27 KiB
C++

#include "PrecompiledHeader.h"
#include "DeckMenu.h"
#include "GameStateDuel.h"
#include "utils.h"
#include "AIPlayer.h"
#include "AIMomirPlayer.h"
#include "PlayerData.h"
#include "DeckStats.h"
#include "DeckManager.h"
#include "DeckMetaData.h"
#include "MTGRules.h"
#include "Credits.h"
#include "Translate.h"
#include "Rules.h"
#include "ModRules.h"
#ifdef TESTSUITE
#include "TestSuiteAI.h"
#endif
#ifdef NETWORK_SUPPORT
#include "NetworkPlayer.h"
#endif
#if defined (WIN32) || defined (LINUX)
#include <time.h>
#endif
const float MENU_FONT_SCALE = 1.0f;
enum ENUM_DUEL_STATE
{
DUEL_STATE_START,
DUEL_STATE_END,
DUEL_STATE_CHOOSE_DECK1,
DUEL_STATE_DECK1_DETAILED_INFO,
DUEL_STATE_DECK2_DETAILED_INFO,
DUEL_STATE_CHOOSE_DECK1_TO_2,
DUEL_STATE_CHOOSE_DECK2,
DUEL_STATE_CHOOSE_DECK2_TO_PLAY,
DUEL_STATE_ERROR_NO_DECK,
DUEL_STATE_CANCEL,
DUEL_STATE_PLAY,
DUEL_STATE_BACK_TO_MAIN_MENU,
DUEL_STATE_MENU,
#ifdef NETWORK_SUPPORT
DUEL_STATE_OPPONENT_WAIT,
#endif //NETWORK_SUPPORT
DUEL_STATE_ERROR
};
enum ENUM_DUEL_MENUS
{
DUEL_MENU_GAME_MENU,
DUEL_MENU_CHOOSE_DECK,
DUEL_MENU_CHOOSE_OPPONENT,
DUEL_MENU_DETAILED_DECK1_INFO,
DUEL_MENU_DETAILED_DECK2_INFO
};
int GameStateDuel::selectedPlayerDeckId = 0;
int GameStateDuel::selectedAIDeckId = 0;
GameStateDuel::GameStateDuel(GameApp* parent) :
GameState(parent)
{
for (int i = 0; i < 2; i++)
{
mPlayers[i] = NULL;
}
premadeDeck = false;
game = NULL;
deckmenu = NULL;
opponentMenu = NULL;
menu = NULL;
popupScreen = NULL;
#ifdef TESTSUITE
testSuite = NULL;
#endif
credits = NULL;
#ifdef NETWORK_SUPPORT
RegisterNetworkPlayers();
#endif //NETWORK_SUPPORT
}
GameStateDuel::~GameStateDuel()
{
End();
}
void GameStateDuel::Start()
{
JRenderer * renderer = JRenderer::GetInstance();
renderer->EnableVSync(true);
OpponentsDeckid = 0;
#ifdef TESTSUITE
SAFE_DELETE(testSuite);
testSuite = NEW TestSuite(JGE_GET_RES("test/_tests.txt").c_str(),MTGCollection());
#endif
mGamePhase = DUEL_STATE_CHOOSE_DECK1;
credits = NEW Credits();
menu = NULL;
int decksneeded = 0;
for (int i = 0; i < 2; i++)
{
if (mParent->players[i] == PLAYER_TYPE_HUMAN)
{
//DeckManager::EndInstance();
decksneeded = 1;
deckmenu = NEW DeckMenu(DUEL_MENU_CHOOSE_DECK, this, Fonts::OPTION_FONT, "Choose a Deck",
GameStateDuel::selectedPlayerDeckId, true);
deckmenu->enableDisplayDetailsOverride();
DeckManager *deckManager = DeckManager::GetInstance();
vector<DeckMetaData *> playerDeckList = BuildDeckList(options.profileFile());
int nbDecks = playerDeckList.size();
if (nbDecks)
decksneeded = 0;
if (nbDecks > 1)
deckmenu->Add(MENUITEM_RANDOM_PLAYER, "Random", "Play with a random deck.");
renderDeckMenu(deckmenu, playerDeckList);
// save the changes to the player deck list maintained in DeckManager
deckManager->updateMetaDataList(&playerDeckList, false);
playerDeckList.clear();
break;
}
}
if (deckmenu)
{
if (decksneeded)
{
if (gModRules.general.hasDeckEditor())
{
//translate deck creating desc
Translator * t = Translator::GetInstance();
string desc = "Highly recommended to get\nthe full Wagic experience!";
map<string, string>::iterator it = t->deckValues.find("Create your Deck!");
if (it != t->deckValues.end())
desc = it->second;
deckmenu->Add(MENUITEM_NEW_DECK, "Create your Deck!", desc);
}
premadeDeck = true;
fillDeckMenu(deckmenu, JGE_GET_RES("player/premade"));
}
else if (gModRules.general.hasDeckEditor())
{
deckmenu->Add(MENUITEM_NEW_DECK, "New Deck...", "Create a new deck to play with.");
}
deckmenu->Add(MENUITEM_CANCEL, "Main Menu", "Return to Main Menu");
}
for (int i = 0; i < 2; ++i)
{
mPlayers[i] = NULL;
}
}
void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwork)
{
if (decknb)
{
if (!isAI)
{ //Human Player
if(playerId == 0)
{
char deckFile[255];
if (premadeDeck)
sprintf(deckFile, JGE_GET_RES("player/premade/deck%i.txt").c_str(), decknb);
else
sprintf(deckFile, "%s/deck%i.txt", options.profileFile().c_str(), decknb);
char deckFileSmall[255];
sprintf(deckFileSmall, "player_deck%i", decknb);
mPlayers[playerId] = NEW HumanPlayer(deckFile, deckFileSmall);
#ifdef NETWORK_SUPPORT
if(isNetwork)
{
ProxyPlayer* mProxy;
mProxy = NEW ProxyPlayer(mPlayers[playerId], mParent->mpNetwork);
}
}
else
{ //Remote player
mPlayers[playerId] = NEW RemotePlayer(mParent->mpNetwork);
#endif //NETWORK_SUPPORT
}
}
else
{ //AI Player, chooses deck
AIPlayerFactory playerCreator;
Player * opponent = NULL;
if (playerId == 1) opponent = mPlayers[0];
mPlayers[playerId] = playerCreator.createAIPlayer(MTGCollection(), opponent, decknb);
}
}
else
{ //Random deck
AIPlayerFactory playerCreator;
Player * opponent = NULL;
if (playerId == 1) opponent = mPlayers[0];
mPlayers[playerId] = playerCreator.createAIPlayer(MTGCollection(), opponent);
}
}
void GameStateDuel::initRand(unsigned int seed)
{
if (!seed)
seed = static_cast<unsigned int>(time(0));
srand(seed);
}
#ifdef TESTSUITE
void GameStateDuel::loadTestSuitePlayers()
{
if (!testSuite) return;
initRand(testSuite->seed);
SAFE_DELETE(game);
for (int i = 0; i < 2; i++)
{
mPlayers[i] = NEW TestSuiteAI(testSuite, i);
}
mParent->gameType = testSuite->gameType;
GameObserver::Init(mPlayers, 2);
game = GameObserver::GetInstance();
game->startGame(mParent->rules);
if (mParent->gameType == GAME_TYPE_MOMIR)
{
game->addObserver(NEW MTGMomirRule(-1, MTGCollection()));
}
}
#endif
void GameStateDuel::End()
{
DebugTrace("Ending GameStateDuel");
#ifdef TRACK_OBJECT_USAGE
ObjectAnalytics::DumpStatistics();
#endif
JRenderer::GetInstance()->EnableVSync(false);
if (!premadeDeck && mPlayers[0] && mPlayers[1])
{ // save the stats for the game
mPlayers[0]->End();
}
else if ( !mPlayers[1] && mPlayers[0] )
// clean up player object
SAFE_DELETE( mPlayers[0] );
GameObserver::EndInstance(); // this will delete both player objects if a game has been played
game = NULL;
premadeDeck = false;
for (int i = 0; i < 2; i++)
{
mPlayers[i] = NULL;
}
SAFE_DELETE(credits);
SAFE_DELETE(menu);
SAFE_DELETE(opponentMenu);
SAFE_DELETE(deckmenu);
SAFE_DELETE(popupScreen);
#ifdef TESTSUITE
SAFE_DELETE(testSuite);
#endif
}
//TODO Move This to utils or ResourceManager. Don't we have more generic functions that can do that?
bool GameStateDuel::MusicExist(string FileName)
{
string filepath = JGE_GET_RES(WResourceManager::Instance()->musicFile(FileName));
wagic::ifstream file(filepath.c_str());
if (file)
{
file.close();
return true;
}
else
return false;
}
void GameStateDuel::ConstructOpponentMenu()
{
if (opponentMenu == NULL)
{
opponentMenu = NEW DeckMenu(DUEL_MENU_CHOOSE_OPPONENT, this, Fonts::OPTION_FONT, "Choose Opponent",
GameStateDuel::selectedAIDeckId, true);
opponentMenu->Add(MENUITEM_RANDOM_AI, "Random");
if (options[Options::EVILTWIN_MODE_UNLOCKED].number) opponentMenu->Add(MENUITEM_EVIL_TWIN, "Evil Twin",
_("Can you defeat yourself?").c_str());
DeckManager * deckManager = DeckManager::GetInstance();
vector<DeckMetaData*> opponentDeckList;
int nbUnlockedDecks = options[Options::CHEATMODEAIDECK].number ? 1000 : options[Options::AIDECKS_UNLOCKED].number;
opponentDeckList = fillDeckMenu(opponentMenu, JGE_GET_RES("ai/baka"), "ai_baka", mPlayers[0], nbUnlockedDecks);
deckManager->updateMetaDataList(&opponentDeckList, true);
opponentMenu->Add(MENUITEM_CANCEL, "Cancel", _("Choose a different player deck").c_str());
opponentDeckList.clear();
}
}
void GameStateDuel::Update(float dt)
{
switch (mGamePhase)
{
case DUEL_STATE_ERROR_NO_DECK:
if (JGE_BTN_OK == mEngine->ReadButton()) mParent->SetNextState(GAME_STATE_DECK_VIEWER);
break;
case DUEL_STATE_DECK1_DETAILED_INFO:
case DUEL_STATE_DECK2_DETAILED_INFO:
popupScreen->Update(dt);
break;
case DUEL_STATE_CHOOSE_DECK1:
if (!mParent->rules->canChooseDeck())
{
mGamePhase = DUEL_STATE_PLAY;
}
#ifdef TESTSUITE
else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE)
{
if (testSuite && testSuite->loadNext())
{
loadTestSuitePlayers();
mGamePhase = DUEL_STATE_PLAY;
testSuite->pregameTests();
testSuite->initGame();
}
else
{
if (!game)
{
mGamePhase = DUEL_STATE_ERROR;
}
else
{
mGamePhase = DUEL_STATE_END;
}
}
}
#endif
else
{
if (mParent->players[0] == PLAYER_TYPE_HUMAN)
{
if (!popupScreen || popupScreen->isClosed()) deckmenu->Update(dt);
}
else
{
loadPlayer(0);
mGamePhase = DUEL_STATE_CHOOSE_DECK2;
}
}
break;
case DUEL_STATE_CHOOSE_DECK1_TO_2:
if (deckmenu->isClosed())
mGamePhase = DUEL_STATE_CHOOSE_DECK2;
else
deckmenu->Update(dt);
break;
case DUEL_STATE_CHOOSE_DECK2:
if (mParent->players[1] == PLAYER_TYPE_HUMAN)
deckmenu->Update(dt);
else
{
if (mParent->players[0] == PLAYER_TYPE_HUMAN)
{
ConstructOpponentMenu();
opponentMenu->Update(dt);
}
else
{
loadPlayer(1);
mGamePhase = DUEL_STATE_PLAY;
}
}
break;
case DUEL_STATE_CHOOSE_DECK2_TO_PLAY:
if (mParent->players[1] == PLAYER_TYPE_HUMAN)
{
if (deckmenu->isClosed())
mGamePhase = DUEL_STATE_PLAY;
else
deckmenu->Update(dt);
}
else
{
ConstructOpponentMenu();
if (opponentMenu->isClosed())
mGamePhase = DUEL_STATE_PLAY;
else
opponentMenu->Update(dt);
}
break;
case DUEL_STATE_PLAY:
if (!game)
{
GameObserver::Init(mPlayers, 2);
game = GameObserver::GetInstance();
game->startGame(mParent->rules);
if (mParent->gameType == GAME_TYPE_MOMIR)
{
game->addObserver(NEW MTGMomirRule(-1, MTGCollection()));
}
if (mParent->gameType == GAME_TYPE_STONEHEWER)
{
game->addObserver(NEW MTGStoneHewerRule(-1,MTGCollection()));
}
if (mParent->gameType == GAME_TYPE_HERMIT)
{
game->addObserver(NEW MTGHermitRule(-1));
}
//start of in game music code
musictrack = "";
//check opponent id and choose the music track based on it
if (OpponentsDeckid)
{
char temp[4096];
sprintf(temp, "ai_baka_music%i.mp3", OpponentsDeckid);
musictrack.assign(temp);
}
else if (mParent->gameType == GAME_TYPE_CLASSIC)
musictrack = "ai_baka_music.mp3";
else if (mParent->gameType == GAME_TYPE_MOMIR)
musictrack = "ai_baka_music_momir.mp3";
else if (mParent->gameType == GAME_TYPE_RANDOM1 || mParent->gameType == GAME_TYPE_RANDOM2) musictrack
= "ai_baka_music_random.mp3";
if (!MusicExist(musictrack)) musictrack = "ai_baka_music.mp3";
GameApp::playMusic(musictrack);
}
game->Update(dt);
//run a "post update" init call in the rules. This is for things such as Manapool, which gets emptied in the update
// That's mostly because of a legacy bug, where we use the update sequence for some things when we should use events (such as phase changes)
mParent->rules->postUpdateInit();
if (game->gameOver)
{
if (game->players[1]->playMode != Player::MODE_TEST_SUITE) credits->compute(game->players[0], game->players[1], mParent);
mGamePhase = DUEL_STATE_END;
#ifdef TESTSUITE
if (mParent->players[1] == PLAYER_TYPE_TESTSUITE)
{
if (testSuite->loadNext())
{
loadTestSuitePlayers();
mGamePhase = DUEL_STATE_PLAY;
testSuite->initGame();
}
else
mGamePhase = DUEL_STATE_END;
}
else
#endif
if (mParent->players[0] == PLAYER_TYPE_CPU && mParent->players[1] == PLAYER_TYPE_CPU)
{
End();
Start();
}
}
if (mEngine->GetButtonClick(JGE_BTN_MENU))
{
if (!menu)
{
menu = NEW SimpleMenu(DUEL_MENU_GAME_MENU, this, Fonts::MENU_FONT, SCREEN_WIDTH / 2 - 100, 25,
game->players[1]->deckName.c_str());
int cardsinhand = game->currentPlayer->game->hand->nb_cards;
//almosthumane - mulligan
if ((game->turn < 1) && (cardsinhand != 0) && game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
&& game->currentPlayer->game->inPlay->nb_cards == 0 && game->currentPlayer->game->graveyard->nb_cards == 0
&& game->currentPlayer->game->exile->nb_cards == 0 && game->currentlyActing() == (Player*)game->currentPlayer) //1st Play Check
//IF there was no play at the moment automatically mulligan
{
menu->Add(MENUITEM_MULLIGAN, "Mulligan");
}
//END almosthumane - mulligan
menu->Add(MENUITEM_MAIN_MENU, "Back to main menu");
menu->Add(MENUITEM_CANCEL, "Cancel");
}
mGamePhase = DUEL_STATE_MENU;
}
break;
#ifdef NETWORK_SUPPORT
case DUEL_STATE_OPPONENT_WAIT:
{
if(mPlayers[1] && mPlayers[1]->game)
{ // Player loaded
menu->Close();
SAFE_DELETE(menu);
mGamePhase = DUEL_STATE_PLAY;
} else if(menu == NULL)
{
loadPlayer(1, 42/* 0 not good*/, false, true);
menu = NEW SimpleMenu(DUEL_STATE_OPPONENT_WAIT, this, Fonts::MENU_FONT, 150, 60);
if (menu)
{
menu->Add(MENUITEM_MAIN_MENU, "Back to main menu");
}
} else
{
menu->Update(dt);
}
}
break;
#endif //NETWORK_SUPPORT
case DUEL_STATE_MENU:
menu->Update(dt);
break;
case DUEL_STATE_CANCEL:
menu->Update(dt);
if (menu->isClosed())
{
mGamePhase = DUEL_STATE_PLAY;
SAFE_DELETE(menu);
}
break;
case DUEL_STATE_BACK_TO_MAIN_MENU:
if (menu)
{
menu->Update(dt);
if (menu->isClosed())
{
PlayerData * playerdata = NEW PlayerData(MTGCollection());
playerdata->taskList->passOneDay();
playerdata->taskList->save();
SAFE_DELETE(playerdata);
SAFE_DELETE(menu);
}
}
mParent->DoTransition(TRANSITION_FADE, GAME_STATE_MENU);
break;
default:
if (JGE_BTN_OK == mEngine->ReadButton()) mParent->SetNextState(GAME_STATE_MENU);
}
}
void GameStateDuel::Render()
{
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT);
JRenderer * r = JRenderer::GetInstance();
r->ClearScreen(ARGB(0,0,0,0));
if (game) game->Render();
switch (mGamePhase)
{
case DUEL_STATE_END:
{
r->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(200,0,0,0));
credits->Render();
#ifdef TESTSUITE
if (mParent->players[1] == PLAYER_TYPE_TESTSUITE)
{
r->ClearScreen(ARGB(255,0,0,0));
char buf[4096];
int nbFailed = testSuite->nbFailed;
int nbTests = testSuite->nbTests;
if (!nbFailed)
{
sprintf(buf, "All %i tests successful!", nbTests);
}
else
{
sprintf(buf, "%i tests out of %i FAILED!", nbFailed, nbTests);
}
mFont->SetColor(ARGB(255,255,255,255));
mFont->DrawString(buf,0,SCREEN_HEIGHT/2);
nbFailed = testSuite->nbAIFailed;
nbTests = testSuite->nbAITests;
if (nbTests)
{
if (!nbFailed)
{
sprintf(buf, "AI Tests: All %i tests successful!", nbTests);
}
else
{
sprintf(buf, "AI Tests: %i tests out of %i FAILED!", nbFailed, nbTests);
}
mFont->DrawString(buf,0,SCREEN_HEIGHT/2+20);
}
}
#endif
break;
}
case DUEL_STATE_ERROR:
{
r->ClearScreen(ARGB(200,0,0,0));
mFont->DrawString(_("AN ERROR OCCURRED, CHECK FILE NAMES").c_str(), 0, SCREEN_HEIGHT / 2);
break;
}
case DUEL_STATE_CHOOSE_DECK1:
case DUEL_STATE_CHOOSE_DECK1_TO_2:
case DUEL_STATE_CHOOSE_DECK2:
case DUEL_STATE_CHOOSE_DECK2_TO_PLAY:
case DUEL_STATE_DECK1_DETAILED_INFO:
case DUEL_STATE_DECK2_DETAILED_INFO:
if (mParent->gameType != GAME_TYPE_CLASSIC
#ifdef NETWORK_SUPPORT
&& mParent->gameType != GAME_TYPE_SLAVE
#endif //NETWORK_SUPPORT
&& mParent->gameType != GAME_TYPE_STONEHEWER
&& mParent->gameType != GAME_TYPE_HERMIT)
mFont->DrawString(_("LOADING DECKS").c_str(), 0, SCREEN_HEIGHT / 2);
else
{
if (opponentMenu)
opponentMenu->Render();
else if (deckmenu && !deckmenu->isClosed()) deckmenu->Render();
if (menu) menu->Render();
if (popupScreen && !popupScreen->isClosed()) popupScreen->Render();
}
break;
case DUEL_STATE_ERROR_NO_DECK:
mFont->DrawString(_("NO DECK AVAILABLE,").c_str(), 0, SCREEN_HEIGHT / 2);
mFont->DrawString(_("PRESS CIRCLE TO GO TO THE DECK EDITOR!").c_str(), 0, SCREEN_HEIGHT / 2 + 20);
break;
#ifdef NETWORK_SUPPORT
case DUEL_STATE_OPPONENT_WAIT:
if (menu) menu->Render();
break;
#endif //NETWORK_SUPPORT
case DUEL_STATE_MENU:
case DUEL_STATE_CANCEL:
case DUEL_STATE_BACK_TO_MAIN_MENU:
if (game)
{
r->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(100,0,0,0));
char buffer[4096];
sprintf(buffer, _("Turn:%i").c_str(), game->turn);
mFont->SetColor(ARGB(255,255,255,255));
mFont->DrawString(buffer, SCREEN_WIDTH / 2, 0, JGETEXT_CENTER);
}
if (menu) menu->Render();
}
}
void GameStateDuel::ButtonPressed(int controllerId, int controlId)
{
int deckNumber = controlId;
DeckManager * deckManager = DeckManager::GetInstance();
int aiDeckSize = deckManager->getAIDeckOrderList()->size();
switch (controllerId)
{
case DUEL_MENU_DETAILED_DECK1_INFO:
if ((popupScreen || deckmenu->showDetailsScreen()))
{
DeckMetaData* selectedDeck = deckmenu->getSelectedDeck();
if (!popupScreen->isClosed())
{
popupScreen->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK1;
SAFE_DELETE( popupScreen );
}
else
{
popupScreen->Update(selectedDeck);
popupScreen->Render();
}
}
break;
case DUEL_MENU_DETAILED_DECK2_INFO:
if ((popupScreen || opponentMenu->showDetailsScreen()))
{
DeckMetaData* selectedDeck = opponentMenu->getSelectedDeck();
if (!popupScreen->isClosed())
{
popupScreen->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
SAFE_DELETE( popupScreen );
}
else
{
popupScreen->Update(selectedDeck);
popupScreen->Render();
}
}
break;
case DUEL_MENU_CHOOSE_OPPONENT:
switch (controlId)
{
case MENUITEM_RANDOM_AI:
loadPlayer(1);
opponentMenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
break;
default:
// cancel option. return to player deck selection
if (controlId == MENUITEM_CANCEL)
{
opponentMenu->Close();
deckmenu->Close();
mParent->SetNextState(DUEL_STATE_CHOOSE_DECK1);
mGamePhase = DUEL_STATE_CHOOSE_DECK1;
break;
}
else if (controlId == MENUITEM_MORE_INFO && opponentMenu->showDetailsScreen())
{
DeckMetaData* selectedDeck = opponentMenu->getSelectedDeck();
if (!popupScreen)
{
popupScreen = NEW SimplePopup(DUEL_MENU_DETAILED_DECK2_INFO, this, Fonts::MAIN_FONT, "Detailed Information",
selectedDeck, MTGCollection());
popupScreen->Render();
selectedAIDeckId = selectedDeck->getDeckId();
}
else
{
popupScreen->Update(selectedDeck);
}
mGamePhase = DUEL_STATE_DECK2_DETAILED_INFO;
break;
}
else if (controlId == MENUITEM_MORE_INFO && !opponentMenu->showDetailsScreen())
{
// do nothing, ignore all key requests until popup is dismissed.
break;
}
else if (controlId != MENUITEM_EVIL_TWIN && aiDeckSize > 0) // evil twin
deckNumber = deckManager->getAIDeckOrderList()->at(controlId - 1)->getDeckId();
loadPlayer(1, deckNumber, 1);
OpponentsDeckid = deckNumber;
opponentMenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
break;
}
break;
case DUEL_MENU_CHOOSE_DECK:
if (controlId == MENUITEM_RANDOM_PLAYER) // Random Player Deck Selection
{
vector<DeckMetaData *> * playerDeckList = deckManager->getPlayerDeckOrderList();
deckNumber = playerDeckList->at(WRand() % (playerDeckList->size()))->getDeckId();
loadPlayer(0, deckNumber);
deckmenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
break;
}
else if (controlId == MENUITEM_MAIN_MENU || controlId == MENUITEM_CANCEL) // user clicked on "Cancel"
{
if (deckmenu) deckmenu->Close();
mGamePhase = DUEL_STATE_BACK_TO_MAIN_MENU;
break;
}
else if (controlId == MENUITEM_MORE_INFO && deckmenu->showDetailsScreen())
{
DeckMetaData* selectedDeck = deckmenu->getSelectedDeck();
if (!popupScreen)
{
popupScreen = NEW SimplePopup(DUEL_MENU_DETAILED_DECK1_INFO, this, Fonts::MAIN_FONT, "Detailed Information",
selectedDeck, MTGCollection());
popupScreen->Render();
selectedPlayerDeckId = deckmenu->getSelectedDeckId();
}
else
{
popupScreen->Update(selectedDeck);
}
mGamePhase = DUEL_STATE_DECK1_DETAILED_INFO;
break;
}
else if (controlId == MENUITEM_MORE_INFO)
{
// do nothing
break;
}
if (controlId < 0)
{
mParent->SetNextState(GAME_STATE_DECK_VIEWER);
return;
}
if (mGamePhase == DUEL_STATE_CHOOSE_DECK1)
{
vector<DeckMetaData *> * playerDeck = deckManager->getPlayerDeckOrderList();
if (!premadeDeck && controlId > 0)
deckNumber = playerDeck->at(controlId - 1)->getDeckId();
loadPlayer(0, deckNumber, false
#ifdef NETWORK_SUPPORT
,(mParent->players[1] == PLAYER_TYPE_REMOTE)
#endif //NETWORK_SUPPORT
);
deckmenu->Close();
#ifdef NETWORK_SUPPORT
if(mParent->players[1] == PLAYER_TYPE_REMOTE)
{ // no need to choose an opponent deck in network mode
mGamePhase = DUEL_STATE_OPPONENT_WAIT;
}
else
#endif //NETWORK_SUPPORT
{
mGamePhase = DUEL_STATE_CHOOSE_DECK1_TO_2;
}
playerDeck = NULL;
}
else
{
loadPlayer(1, controlId);
deckmenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
}
break;
default:
switch (controlId)
{
case MENUITEM_MAIN_MENU:
menu->Close();
mGamePhase = DUEL_STATE_BACK_TO_MAIN_MENU;
break;
case MENUITEM_CANCEL:
menu->Close();
mGamePhase = DUEL_STATE_CANCEL;
break;
case MENUITEM_MULLIGAN:
//almosthumane - mulligan
game->currentPlayer->takeMulligan();
menu->Close();
mGamePhase = DUEL_STATE_CANCEL;
break;
//END almosthumane - mulligan
}
}
}
void GameStateDuel::OnScroll(int inXVelocity, int inYVelocity)
{
if (abs(inYVelocity) > 300)
{
bool flickUpwards = (inYVelocity < 0);
mEngine->HoldKey_NoRepeat(flickUpwards ? JGE_BTN_PREV : JGE_BTN_SEC);
}
}