/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD #include "game_menu.h" #include "event_handler.h" #include "state.h" #include "class_list.h" #include "util/loading/load_param.h" #include "util/loading/factory.h" #include "util/loading/resource_manager.h" #include "graphics_engine.h" #include "camera.h" #include "sound_engine.h" #include "sound_source.h" #include "glgui.h" #include "menu/glgui_imagebutton.h" #include "glgui_text.h" #include "network_manager.h" //! This creates a Factory to fabricate a GameMenu CREATE_FACTORY(GameMenu, CL_GAME_MENU); GameMenu::GameMenu(const TiXmlElement* root) : GameWorld() { this->setClassID(CL_GAME_MENU, "GameMenu"); this->setName("GameMenu uninitialized"); this->dataTank = new GameMenuData(); this->cameraVector = Vector(50.0, 0.0, 0.0); if (root != NULL) this->loadParams(root); State::setMenuID(this->getNextStoryID()); } /** * @brief remove the GameMenu from memory * * delete everything explicitly, that isn't contained in the parenting tree! * things contained in the tree are deleted automaticaly */ GameMenu::~GameMenu () { PRINTF(3)("GameMenu::~GameMenu() - deleting current world\n"); if( this->dataTank) delete this->dataTank; delete OrxGui::GLGuiHandler::getInstance( ); } /** * @brief loads the parameters of a GameMenu from an XML-element * @param root the XML-element to load from */ void GameMenu::loadParams(const TiXmlElement* root) { /* skip the GameWorld, since it does not define any useful loadParams for this class */ //static_cast(this)->loadParams(root); GameWorld::loadParams(root); PRINTF(4)("Loaded GameMenu specific stuff\n"); } /** * @brief this is executed just before load * * since the load function sometimes needs data, that has been initialized * before the load and after the proceeding storyentity has finished */ ErrorMessage GameMenu::init() { /* call underlying init funciton */ GameWorld::init(); this->subscribeEvent(ES_MENU, SDLK_UP); this->subscribeEvent(ES_MENU, SDLK_DOWN); this->subscribeEvent(ES_MENU, SDLK_RETURN); this->subscribeEvent(ES_MENU, SDLK_SPACE); this->subscribeEvent(ES_MENU, SDLK_ESCAPE); this->dataTank->localCamera->setRelCoor(this->cameraVector); GraphicsEngine::getInstance()->displayFPS(false); return ErrorMessage(); } /** * @brief load the data */ ErrorMessage GameMenu::loadData() { this->mainMenuBox = NULL; this->levelsBox = NULL; this->networkBox = NULL; this->clientNetworkBox = NULL; this->serverNetworkBox = NULL; this->optionsBox = NULL; this->generalBox = NULL; this->audioBox = NULL; this->videoBox = NULL; this->controlBox = NULL; this->levelsBox = NULL; this->currentlyOpened = NULL; return GameWorld::loadData(); } void GameMenu::showMainMenu() { if (mainMenuBox == NULL) { this->mainMenuBox = new OrxGui::GLGuiBox(); { OrxGui::GLGuiButton* startButton = new OrxGui::GLGuiPushButton("Play"); startButton->connect(SIGNAL(startButton, released), this, SLOT(GameMenu, showCampaigns)); this->mainMenuBox->pack(startButton); startButton->select(); OrxGui::GLGuiButton* networkButton = new OrxGui::GLGuiPushButton("MultiPlayer"); networkButton->connect(SIGNAL(networkButton, released), this, SLOT(GameMenu, showMultiPlayer)); this->mainMenuBox->pack(networkButton); OrxGui::GLGuiButton* optionsButton = new OrxGui::GLGuiPushButton("Options"); optionsButton->connect(SIGNAL(optionsButton, released), this, SLOT(GameMenu, showOptionsMenu)); this->mainMenuBox->pack(optionsButton); OrxGui::GLGuiButton* quitButton = new OrxGui::GLGuiPushButton("Quit"); this->mainMenuBox->pack(quitButton); quitButton->connect(SIGNAL(quitButton, released), this, SLOT(GameMenu, quitMenu)); } } this->mainMenuBox->showAll(); this->mainMenuBox->setRelCoor2D(200, 100); } void GameMenu::showCampaigns() { if (this->levelsBox == NULL) { this->levelsBox = new OrxGui::GLGuiBox(OrxGui::Horizontal); { OrxGui::GLGuiBox* labelBox = new OrxGui::GLGuiBox(); OrxGui::GLGuiImage* image = new OrxGui::GLGuiImage(); image->show(); image->setWidgetSize( 250, 200); image->setAbsCoor2D(400, 150); image->setForegroundColor(Color( 1,1,1,.6)); const std::list* storyEntities = ClassList::getList(CL_STORY_ENTITY); std::list::const_iterator it; bool first = true; for( it = storyEntities->begin(); it != storyEntities->end(); it++) { StoryEntity* se = dynamic_cast(*it); if( se->isContainedInMenu()) { printf("%s\n", se->getMenuScreenshoot().c_str()); OrxGui::GLGuiImageButton* button = new OrxGui::GLGuiImageButton(se->getName(), se->getStoryID(), se->getMenuScreenshoot(), image); button->connect(SIGNAL(button, startLevel), this, SLOT(GameMenu, startLevel)); labelBox->pack(button); if (first) { first = !first; button->select(); } // generating screenshoot item /* ImageEntity* ie = new ImageEntity(); ie->setVisibility(false); ie->setBindNode((const PNode*)NULL); ie->setTexture(se->getMenuScreenshoot()); ie->setRelCoor2D(State::getResX() / 2.0f + 250.0f, State::getResY() / 2.0f); ie->setSize2D(140.0f, 105.0f); this->menuLayers[1].screenshootList.push_back(ie); */ } } this->levelsBox->pack(labelBox); this->levelsBox->pack(image); } } this->showSecondLevelElement(this->levelsBox); } void GameMenu::showMultiPlayer() { if (this->networkBox == NULL) { this->networkBox = new OrxGui::GLGuiBox( OrxGui::Horizontal ); { OrxGui::GLGuiBox * box = new OrxGui::GLGuiBox(); OrxGui::GLGuiButton* clientButton = new OrxGui::GLGuiPushButton("Client"); box->pack(clientButton); clientButton->connect(SIGNAL(clientButton, released), this, SLOT(GameMenu, showClientMenu)); OrxGui::GLGuiButton* serverButton = new OrxGui::GLGuiPushButton("Server"); box->pack(serverButton); serverButton->connect(SIGNAL(serverButton, released), this, SLOT(GameMenu, showServerMenu)); networkBox->pack( box ); } } this->showSecondLevelElement(this->networkBox); } void GameMenu::showOptionsMenu() { if (this->optionsBox == NULL) { this->optionsBox = new OrxGui::GLGuiBox(); { OrxGui::GLGuiTextfield* WARNtext = new OrxGui::GLGuiTextfield(); WARNtext->setText("PLEASE USE THE EXTERNAL GUI\n FOR ORXONOX CONFIGURATION\n (start with './orxonox -g')"); optionsBox->pack(WARNtext); OrxGui::GLGuiButton* generalButton = new OrxGui::GLGuiPushButton("General"); optionsBox->pack(generalButton); OrxGui::GLGuiButton* audioButton = new OrxGui::GLGuiPushButton("Audio"); optionsBox->pack(audioButton); OrxGui::GLGuiButton* videoButton = new OrxGui::GLGuiPushButton("Video"); optionsBox->pack(videoButton); OrxGui::GLGuiButton* controlButton = new OrxGui::GLGuiPushButton("Control"); optionsBox->pack(controlButton); // for (unsigned int i = 0; i < //OrxGui::GLGuiButton* } } this->showSecondLevelElement(this->optionsBox); } void GameMenu::showSecondLevelElement(OrxGui::GLGuiBox* element) { if (this->currentlyOpened != NULL && this->currentlyOpened != element) this->currentlyOpened->hideAll(); element->showAll(); element->setRelCoor2D(200, 100); this->currentlyOpened = element; this->mainMenuBox->setRelCoorSoft2D(50, 100, 5); } void GameMenu::startLevel(int levelID) { this->setNextStoryID( levelID); this->stop(); } /** * @brief set the Sound to play when switching menu entry. * @param selectorSound the sound to load. */ void GameMenu::setSelectorSound(const std::string& selectorSound) { this->selectorSource = OrxSound::SoundEngine::getInstance()->createSource(selectorSound, NULL); } ErrorMessage GameMenu::unloadData() { this->unsubscribeEvents(ES_MENU); return GameWorld::unloadData(); } /** * @brief start the menu */ bool GameMenu::start() { EventHandler::getInstance()->pushState(ES_MENU); this->showMainMenu(); OrxGui::GLGuiHandler::getInstance()->activateCursor(); OrxGui::GLGuiHandler::getInstance()->activate(); OrxGui::GLGuiHandler::getInstance()->cursor()->loadTextureSequence(ResourceManager::getInstance()->getDataDir() + "/" + "maps/reap_mouse/reap_mouse_##.png", 1, 49); /* now call the underlying*/ return GameWorld::start(); } /** * stop the menu */ bool GameMenu::stop() { EventHandler::getInstance()->popState(); /* now call the underlying*/ return GameWorld::stop(); } /** * override the standard tick for more functionality */ void GameMenu::tick() { GameWorld::tick(); // Make the GLGui tick. OrxGui::GLGuiHandler::getInstance()->tick(this->dtS); this->animateScene(this->dtS); } /** * @brief no collision detection in the menu */ void GameMenu::collide() { // this->dataTank->localCamera-> } /** * @brief animate the scene */ void GameMenu::animateScene(float dt) { Quaternion q(/*0.00005*/ dt * .1, Vector(0.0, 1.0, 0.0)); this->cameraVector = q.apply(this->cameraVector); this->dataTank->localCamera->setRelCoor(this->cameraVector); this->dataTank->localCamera->getTarget()->setRelCoorSoft(0,0,0); } void GameMenu::quitMenu() { this->setNextStoryID(WORLD_ID_GAMEEND); this->stop(); } /** * @brief event dispatcher funciton * @param event the incoming event */ void GameMenu::process(const Event &event) { if( event.type == SDLK_ESCAPE && event.bPressed == true) { this->setNextStoryID(WORLD_ID_GAMEEND); this->stop(); } } /********************************************************************************************** GameMenuData **********************************************************************************************/ /** * GameMenuData constructor */ GameMenuData::GameMenuData() {} /** * GameMenuData decontructor */ GameMenuData::~GameMenuData() {} /** * initialize the GameWorldDataData */ ErrorMessage GameMenuData::init() { /* call underlying function */ return GameWorldData::init(); } /** * loads the GUI data * @param root reference to the xml root element */ ErrorMessage GameMenuData::loadGUI(const TiXmlElement* root) { /* call underlying function */ return GameWorldData::loadGUI(root); } /** * unloads the GUI data */ ErrorMessage GameMenuData::unloadGUI() { /* call underlying function */ return GameWorldData::unloadGUI(); } /** * overloads the GameWorld::loadWorldEntities(...) class since the menu WorldEntity loading is different (less loading stuff) * @param root reference to the xml root parameter */ ErrorMessage GameMenuData::loadWorldEntities(const TiXmlElement* root) { return GameWorldData::loadWorldEntities(root); } /** * unloads the world entities from the xml file */ ErrorMessage GameMenuData::unloadWorldEntities() { /* call underlying function */ return GameWorldData::unloadWorldEntities(); } /** * loads the scene data * @param root reference to the xml root element */ ErrorMessage GameMenuData::loadScene(const TiXmlElement* root) { /* call underlying function */ return GameWorldData::loadScene(root); } /** * unloads the scene data */ ErrorMessage GameMenuData::unloadScene() { /* call underlying function */ return GameWorldData::unloadScene(); } /** * show controls to join network game */ void GameMenu::showClientMenu( ) { if ( this->serverNetworkBox ) { this->networkBox->unpack( this->serverNetworkBox ); this->serverNetworkBox->hideAll(); //delete this->serverNetworkBox; //this->serverNetworkBox = NULL; } if ( !this->clientNetworkBox ) { this->clientNetworkBox = new OrxGui::GLGuiBox(); { OrxGui::GLGuiText * text = new OrxGui::GLGuiText(); text->setText( "Host:" ); this->clientNetworkBox->pack( text ); this->ipInputLine = new OrxGui::GLGuiInputLine( ); this->ipInputLine->setText( "tardis-d08" ); this->clientNetworkBox->pack( this->ipInputLine ); this->ipInputLine->connect(SIGNAL(ipInputLine, enterPushed), this, SLOT(GameMenu, connectToServer)); this->ipInputLine->select(); OrxGui::GLGuiButton* connectButton = new OrxGui::GLGuiPushButton("Connect"); clientNetworkBox->pack(connectButton); connectButton->connect(SIGNAL(connectButton, released), this, SLOT(GameMenu, connectToServer)); } } this->networkBox->pack( this->clientNetworkBox ); this->clientNetworkBox->showAll(); //this->clientNetworkBox->setAbsCoor2D( 300.0f, 100.0f ); } /** * show controls to create new network game */ void GameMenu::showServerMenu( ) { if ( this->clientNetworkBox ) { this->networkBox->unpack( this->clientNetworkBox ); this->clientNetworkBox->hideAll(); //delete this->clientNetworkBox; //this->clientNetworkBox = NULL; } if ( !this->serverNetworkBox ) { this->serverNetworkBox = new OrxGui::GLGuiBox(); { OrxGui::GLGuiText * text = new OrxGui::GLGuiText(); text->setText( "Map:" ); this->serverNetworkBox->pack( text ); OrxGui::GLGuiText * text2 = new OrxGui::GLGuiText(); text2->setText( "Multiplayer TeamDeathMatch Arena" ); this->serverNetworkBox->pack( text2 ); OrxGui::GLGuiButton* createButton = new OrxGui::GLGuiPushButton("Create Server"); serverNetworkBox->pack(createButton); createButton->connect(SIGNAL(createButton, released), this, SLOT(GameMenu, createServer)); } } this->networkBox->pack( this->serverNetworkBox ); this->serverNetworkBox->showAll(); //this->serverNetworkBox->setAbsCoor2D( 300.0f, 100.0f ); } /** * connect to host */ void GameMenu::connectToServer( ) { PRINTF(0)("Connecting to %s\n", this->ipInputLine->_getText().c_str() ); State::setOnline(true); NetworkManager::getInstance()->establishConnection( this->ipInputLine->_getText(), 9999 ); this->startLevel( 5 ); } void GameMenu::createServer( ) { PRINTF(0)("Create server\n" ); State::setOnline(true); NetworkManager::getInstance()->createServer( 9999 ); this->startLevel( 5 ); }