Files
wagic/projects/mtg/src/GameStateDuel.cpp
T
wagic.the.homebrew cd07248df5 UPDATE YOUR rules FOLDER!!!
- This is some Work in progress to make Wagic less "game" dependent.
This change especially is an attempt at moving away from some dangerous patents owned by some company.
It introduces "modrules.xml", a global configuration file describing dynamic settings for any given Wagic mod. It is very basic for now, but allows to customize a bit. In particular, it allows to remove the concept of shop and deck editor from the game, dynamically generate the main menu, and represent card activation with a mask rather than a rotation.
I have a sample in progress which I hope to submit in the days to come, a proof of concept (nothing fancy yet) for another type of game using these ideas, as well as a few other things I introduced recently.
In the future, I am hoping to extend modrules.xml so that it entirely describes the rules of a given card game. the other files in rules.txt will describe "extensions" to the core rules, just like they do right now, so this new file does not make them obsolete.


- Also fixed minor bugs I stumbled upon while developing
2011-04-29 17:30:57 +00:00

845 lines
26 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 > 1)
{
decksneeded = 0;
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 = 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()));
}
//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);
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->players[0]->game->hand->nb_cards;
//almosthumane - mulligan
if ((game->turn < 1) && (cardsinhand != 0) && game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
&& game->players[0]->game->inPlay->nb_cards == 0 && game->players[0]->game->graveyard->nb_cards == 0
&& game->players[0]->game->exile->nb_cards == 0) //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
)
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
}
}
}