/* * PlanetPenguin Racer * Copyright (C) 2004-2005 Volker Stroebel * * Copyright (C) 1999-2001 Jasmin F. Patry * * 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 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "event_race_select.h" #include "ppogl/font.h" #include "course_load.h" #include "joystick.h" #include "stuff.h" #include "game_mgr.h" #include "player.h" #include static std::list::iterator curElem; EventRaceSelect::EventRaceSelect() : m_titleLbl(_("Select a race"),"heading"), m_descTa(300,104), m_raceListBox(450,36), m_backBtn(_("Back")), m_startBtn(_("Race!")), m_previewImage(ppogl::Vec2d(128,96)), m_authorTitle(_("Contributed by:")), m_timeTitle(_("Time:")), m_herringTitle(_("Herring:")), m_scoreTitle(_("Score:")), m_statusLbl("","race_requirements_label") { ppogl::UIManager::getInstance().setBoxDimension(ppogl::Vec2d(640,480)); if ( GameMode::prevmode != GAME_OVER ) { curElem = GameMgr::getInstance().getCurrentCup().raceList.begin(); } else { if( GameMgr::getInstance().wasRaceWon() ){ if(curElem != --GameMgr::getInstance().getCurrentCup().raceList.end()){ curElem++; } } } { std::list &courses = GameMgr::getInstance().getCurrentCup().raceList; std::list::iterator it; for(it=courses.begin(); it!=courses.end();it++){ m_raceListBox.addElement((*it).getName(), it); } } m_titleLbl.setPosition(ppogl::Vec2d(320,400)); m_titleLbl.alignment.center(); m_backBtn.setPosition(ppogl::Vec2d(80,0)); m_backBtn.signalClicked.Connect(ppogl::CreateSlot(this,&EventRaceSelect::back)); m_startBtn.setPosition(ppogl::Vec2d(560,0)); m_startBtn.alignment.right(); m_startBtn.signalClicked.Connect(ppogl::CreateSlot(this,&EventRaceSelect::start)); m_raceListBox.setPosition(ppogl::Vec2d(320,320)); m_raceListBox.alignment.center(); m_raceListBox.setSelectedData(curElem); m_raceListBox.signalChanged.Connect(ppogl::CreateSlot(this,&EventRaceSelect::updateData)); // Create text area m_descTa.setPosition(ppogl::Vec2d(100,150)); m_descTa.setText((*curElem).getDescription()); for(int i=0; i<4; i++){ m_livesImg[i].setPosition(ppogl::Vec2d(416+i*36,260)); m_livesImg[i].setTexture("life_icon"); m_livesImg[i].addState(0,ppogl::Vec4f(0.0, 0.0, 1.0, 0.5)); m_livesImg[i].addState(1,ppogl::Vec4f(0.0, 0.5, 1.0, 1.0)); m_livesImg[i].setState(0); } // preview image m_previewImage.setPosition(ppogl::Vec2d(420,154)); m_previewImage.addState(0,ppogl::Vec4f(0.0, 0.0, 1.0, 1.0)); m_previewImage.setState(0); m_previewImage.setBorder(4); ppogl::FontRef titlefont = ppogl::FontMgr::getInstance().get("race_requirements_label"); ppogl::FontRef labelfont = ppogl::FontMgr::getInstance().get("race_requirements"); m_authorTitle.setPosition(ppogl::Vec2d(100,135)); m_authorTitle.setFont(titlefont); m_authorLbl.setPosition(ppogl::Vec2d( 105 + titlefont->advance(m_authorTitle.getText()), 135)); m_authorLbl.setFont(labelfont); m_timeTitle.setPosition(ppogl::Vec2d(100,260)); m_timeTitle.setFont(titlefont); m_timeLbl.setPosition(ppogl::Vec2d( 105 + titlefont->advance(m_timeTitle.getText()), 260)); m_timeLbl.setFont(labelfont); m_herringTitle.setPosition(ppogl::Vec2d(200,260)); m_herringTitle.setFont(titlefont); m_herringLbl.setPosition(ppogl::Vec2d( 205 + titlefont->advance(m_herringTitle.getText()), 260)); m_herringLbl.setFont(labelfont); m_scoreTitle.setPosition(ppogl::Vec2d(300,260)); m_scoreTitle.setFont(titlefont); m_scoreLbl.setPosition(ppogl::Vec2d( 305 + titlefont->advance(m_scoreTitle.getText()), 260)); m_scoreLbl.setFont(labelfont); // status message m_statusLbl.setPosition(ppogl::Vec2d(100,275)); updateStates(); updateData(); ppogl::AudioMgr::getInstance().playMusic("start_screen"); } void EventRaceSelect::loop(float timeStep) { set_gl_options( GUI ); drawSnow(timeStep, true); ppogl::UIManager::getInstance().draw(resolutionX, resolutionY); reshape(resolutionX, resolutionY); } void EventRaceSelect::updateStatusMsg() { std::string msg; char buff[BUFF_LEN]; switch(state){ case DEAD: msg = _("You don't have any lives left."); break; case RACEWON: msg = _("Race won! Your result:"); break; case PLAYABLE: msg = _("Needed to advance:"); break; case UNPLAYABLE: msg = _("You can't enter this race yet."); break; default: msg = ""; break; } m_statusLbl.setText(msg); int minutes; int seconds; int hundredths; getTimeComponents( m_data.time, minutes, seconds, hundredths ); sprintf( buff, "%02d:%02d.%02d",minutes, seconds, hundredths); m_timeLbl.setText(buff); sprintf( buff, "%03d", m_data.herring ); m_herringLbl.setText(buff);; sprintf( buff, "%06d", m_data.score ); m_scoreLbl.setText(buff); if(!(*curElem).author.empty()){ m_authorLbl.setText((*curElem).author); }else{ m_authorLbl.setText(_("Unknown")); } } void EventRaceSelect::updateStates() { if ( players[0].getLives() <= 0 ) { state=DEAD; m_startBtn.setInsensitive(true); } else { m_data.won=false; players[0].getCupCourseData( std::string(GameMgr::getInstance().getCurrentEvent().getName()), std::string(GameMgr::getInstance().getCurrentCup().getName()), std::string((*curElem).getName()), m_data); if(m_data.won){ state=RACEWON; m_startBtn.setInsensitive(true); }else{ DifficultyLevel d = GameMgr::getInstance().difficulty; m_data.time = (*curElem).time_req[d]; m_data.herring = (*curElem).herring_req[d]; m_data.score = int((*curElem).score_req[d]); if(curElem==GameMgr::getInstance().getCurrentCup().raceList.begin()){ state=PLAYABLE; m_startBtn.setInsensitive(false); }else{ PlayerCourseData prev; curElem--; players[0].getCupCourseData( std::string(GameMgr::getInstance().getCurrentEvent().getName()), std::string(GameMgr::getInstance().getCurrentCup().getName()), std::string((*curElem).getName()), prev); curElem++; if(prev.won){ state=PLAYABLE; m_startBtn.setInsensitive(false); } else { state=UNPLAYABLE; m_startBtn.setInsensitive(true); } } } } } void EventRaceSelect::back() { setMode( EVENT_SELECT ); } void EventRaceSelect::start() { loop( 0 ); GameMgr::getInstance().setCurrentRace(curElem); setMode( LOADING ); } void EventRaceSelect::updateData() { curElem = m_raceListBox.getSelectedData(); m_descTa.setText((*curElem).getDescription()); updateStates(); updateStatusMsg(); ppogl::TextureRef texture = ppogl::TextureMgr::getInstance().get((*curElem).course); if(!texture){ texture = ppogl::TextureMgr::getInstance().get("no_preview"); if(!texture){ PP_WARNING("Unable to get no_preview Image"); } } m_previewImage.setTexture(texture); // set life images PP_ASSERT(INIT_NUM_LIVES==4, "Assumption about number of lives invalid -- " "need to recode this part" ); for (int i=0; i<4; i++ ){ if(players[0].getLives() > i){ m_livesImg[i].setState(1); }else{ m_livesImg[i].setState(0); } } } bool EventRaceSelect::keyPressEvent(SDLKey key) { switch (key){ case SDLK_UP: case SDLK_LEFT: --m_raceListBox; updateData(); return true; case SDLK_RIGHT: case SDLK_DOWN: ++m_raceListBox; updateData(); return true; case SDLK_RETURN: if(!m_startBtn.isInsensitive()){ start(); } return true; case SDLK_ESCAPE: back(); return true; default: return false; } }