From 996c563f9c1af80723400edc0a52e1f1ebd33088 Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 14 Jan 2013 00:35:44 +0000 Subject: [PATCH] First version of tutorial. Far from finished but you can take a quick look if you wish; the text is currently at the bottom git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12350 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/gui/main.stkgui | 2 + sources.cmake | 32 ++- src/items/powerup_manager.cpp | 7 +- src/items/powerup_manager.hpp | 1 + src/modes/tutorial_race.cpp | 73 ------- src/modes/tutorial_race.hpp | 51 ----- src/modes/tutorial_world.cpp | 80 +++++++ src/modes/tutorial_world.hpp | 15 ++ src/race/race_manager.cpp | 3 + src/race/race_manager.hpp | 8 + src/states_screens/main_menu_screen.cpp | 46 +++- src/states_screens/tutorial_screen.cpp | 275 ------------------------ src/states_screens/tutorial_screen.hpp | 56 ----- src/tracks/track_object.cpp | 70 ++++++ 14 files changed, 239 insertions(+), 480 deletions(-) delete mode 100644 src/modes/tutorial_race.cpp delete mode 100644 src/modes/tutorial_race.hpp create mode 100644 src/modes/tutorial_world.cpp create mode 100644 src/modes/tutorial_world.hpp delete mode 100644 src/states_screens/tutorial_screen.cpp delete mode 100644 src/states_screens/tutorial_screen.hpp diff --git a/data/gui/main.stkgui b/data/gui/main.stkgui index 7b2e442ba..29f2aff45 100644 --- a/data/gui/main.stkgui +++ b/data/gui/main.stkgui @@ -37,6 +37,8 @@ I18N="Main menu button" text="Options" label_location="hover"/> + isBattleMode()) return POSITION_BATTLE_MODE; + if(race_manager->isTutorialMode()) return POSITION_TUTORIAL_MODE; if(position==1) return POSITION_FIRST; if(position==num_karts) return POSITION_LAST; @@ -350,8 +352,9 @@ PowerupManager::PowerupType PowerupManager::getRandomPowerup(unsigned int pos, { // Positions start with 1, while the index starts with 0 - so subtract 1 PositionClass pos_class = - race_manager->isBattleMode() ? POSITION_BATTLE_MODE - : m_position_to_class[pos-1]; + (race_manager->isBattleMode() ? POSITION_BATTLE_MODE : + (race_manager->isTutorialMode() ? POSITION_TUTORIAL_MODE : + m_position_to_class[pos-1])); int random = rand()%m_powerups_for_position[pos_class].size(); int i=m_powerups_for_position[pos_class][random]; diff --git a/src/items/powerup_manager.hpp b/src/items/powerup_manager.hpp index b50888e2e..431a8e386 100644 --- a/src/items/powerup_manager.hpp +++ b/src/items/powerup_manager.hpp @@ -96,6 +96,7 @@ public: POSITION_END33, POSITION_LAST, POSITION_BATTLE_MODE, + POSITION_TUTORIAL_MODE, POSITION_COUNT}; private: diff --git a/src/modes/tutorial_race.cpp b/src/modes/tutorial_race.cpp deleted file mode 100644 index 475b16d27..000000000 --- a/src/modes/tutorial_race.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010 Alejandro Santiago -// -// 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 3 -// 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 "modes/tutorial_race.hpp" - -#include "audio/music_manager.hpp" -#include "tutorial/tutorial_manager.hpp" -#include "config/user_config.hpp" -#include "karts/abstract_kart.hpp" -#include "items/powerup_manager.hpp" -#include "states_screens/race_gui_base.hpp" -#include "tracks/track.hpp" -#include "utils/translation.hpp" - - -//----------------------------------------------------------------------------- -TutorialRace::TutorialRace() : LinearWorld() -{ -} // TutorialRace - -//----------------------------------------------------------------------------- -TutorialRace::~TutorialRace() -{ -} - -//----------------------------------------------------------------------------- -/** The follow the leader race is over if there is only one kart left (plus - * the leader), or if all (human) players have been eliminated. - */ -bool TutorialRace::isRaceOver() -{ - // FIXME : add the logic to detect if the user have ended the tutorial. - return true; -} // isRaceOver - -//----------------------------------------------------------------------------- -void TutorialRace::restartRace() -{ - LinearWorld::restartRace(); -} // restartRace - -//----------------------------------------------------------------------------- -/** Returns the internal identifier for this kind of race. - */ -const std::string& TutorialRace::getIdent() const -{ - return IDENT_FTL; -} // getIdent - -//----------------------------------------------------------------------------- -/** Sets the title for all karts that is displayed in the icon list. In - * this mode the title for the first kart is set to 'leader'. - */ -void TutorialRace::getKartsDisplayInfo( - std::vector *info) -{ - LinearWorld::getKartsDisplayInfo(info); - (*info)[0].special_title = _("Leader"); -} // getKartsDisplayInfo diff --git a/src/modes/tutorial_race.hpp b/src/modes/tutorial_race.hpp deleted file mode 100644 index e37ce59b5..000000000 --- a/src/modes/tutorial_race.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010 Alejandro Santiago -// -// 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 3 -// 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. - -#ifndef HEADER_TUTORIAL_MODE_HPP -#define HEADER_TUTORIAL_MODE_HPP - -#include "modes/linear_world.hpp" -#include "states_screens/race_gui_base.hpp" - -/** - * \brief An implementation of World, based on LinearWorld, to provide the Follow-the-leader game mode - * \ingroup modes - */ -class TutorialRace : public LinearWorld -{ -private: - -public: - - TutorialRace(); - virtual ~TutorialRace(); - - // overriding World methods - virtual void restartRace(); - virtual const std::string& getIdent() const; - float getClockStartTime(); - virtual bool useFastMusicNearEnd() const { return false; } - virtual void getKartsDisplayInfo( - std::vector *info); - - virtual bool isRaceOver(); - virtual bool raceHasLaps(){ return false; } - -}; - - -#endif //HEADER_TUTORIAL_MODE_HPP diff --git a/src/modes/tutorial_world.cpp b/src/modes/tutorial_world.cpp new file mode 100644 index 000000000..e551223ed --- /dev/null +++ b/src/modes/tutorial_world.cpp @@ -0,0 +1,80 @@ +#include "modes/tutorial_world.hpp" + +#include "karts/kart.hpp" +#include "physics/physics.hpp" +#include "tracks/track.hpp" + +void TutorialWorld::moveKartAfterRescue(AbstractKart* kart) +{ + float angle = 0; + + // find closest point to drop kart on + World *world = World::getWorld(); + const int start_spots_amount = world->getTrack()->getNumberOfStartPositions(); + assert(start_spots_amount > 0); + + const float currentKart_x = kart->getXYZ().getX(); + const float currentKart_z = kart->getXYZ().getZ(); + + const btTransform& s = getClosestStartPoint(currentKart_x, currentKart_z); + const Vec3 &xyz = s.getOrigin(); + kart->setXYZ(xyz); + kart->setRotation(s.getRotation()); + + //position kart from same height as in World::resetAllKarts + btTransform pos; + pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f)); + pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), angle) ); + + kart->getBody()->setCenterOfMassTransform(pos); + + //project kart to surface of track + bool kart_over_ground = m_physics->projectKartDownwards(kart); + + if (kart_over_ground) + { + //add vertical offset so that the kart starts off above the track + float vertical_offset = kart->getKartProperties()->getVertRescueOffset() * + kart->getKartHeight(); + kart->getBody()->translate(btVector3(0, vertical_offset, 0)); + } + else + { + fprintf(stderr, "WARNING: invalid position after rescue for kart %s on track %s.\n", + (kart->getIdent().c_str()), m_track->getIdent().c_str()); + } +} // moveKartAfterRescue + +// ----------------------------------------------------------------------------- + +btTransform TutorialWorld::getClosestStartPoint(float currentKart_x, float currentKart_z) +{ + // find closest point to drop kart on + World *world = World::getWorld(); + const int start_spots_amount = world->getTrack()->getNumberOfStartPositions(); + assert(start_spots_amount > 0); + + + int closest_id = -1; + float closest_distance = 999999999.0f; + + for (int n=0; ngetTrack()->getStartTransform(n); + const Vec3 &v = s.getOrigin(); + + float absDistance = fabs(currentKart_x - v.getX()) + + fabs(currentKart_z - v.getZ()); + + if (absDistance < closest_distance) + { + closest_distance = absDistance; + closest_id = n; + } + } + + assert(closest_id != -1); + return world->getTrack()->getStartTransform(closest_id); +} diff --git a/src/modes/tutorial_world.hpp b/src/modes/tutorial_world.hpp new file mode 100644 index 000000000..7253e377d --- /dev/null +++ b/src/modes/tutorial_world.hpp @@ -0,0 +1,15 @@ +#ifndef HEADER_TUTORIAL_MODE_HPP +#define HEADER_TUTORIAL_MODE_HPP + +#include "modes/standard_race.hpp" +#include "LinearMath/btTransform.h" + +class TutorialWorld : public StandardRace +{ +private: + btTransform getClosestStartPoint(float currentKart_x, float currentKart_z); +public: + virtual void moveKartAfterRescue(AbstractKart* kart) OVERRIDE; +}; + +#endif diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 5b633f195..5e21c8385 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -37,6 +37,7 @@ #include "modes/overworld.hpp" #include "modes/profile_world.hpp" #include "modes/standard_race.hpp" +#include "modes/tutorial_world.hpp" #include "modes/world.hpp" #include "modes/three_strikes_battle.hpp" #include "network/network_manager.hpp" @@ -389,6 +390,8 @@ void RaceManager::startNextRace() else if(m_minor_mode==MINOR_MODE_NORMAL_RACE || m_minor_mode==MINOR_MODE_TIME_TRIAL) World::setWorld(new StandardRace()); + else if(m_minor_mode==MINOR_MODE_TUTORIAL) + World::setWorld(new TutorialWorld()); else if(m_minor_mode==MINOR_MODE_3_STRIKES) World::setWorld(new ThreeStrikesBattle()); else if(m_minor_mode==MINOR_MODE_OVERWORLD) diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 22f85d04d..da37eafb1 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -108,6 +108,7 @@ public: MINOR_MODE_TIME_TRIAL = LINEAR_RACE(1, true), MINOR_MODE_FOLLOW_LEADER = LINEAR_RACE(2, false), MINOR_MODE_OVERWORLD = LINEAR_RACE(3, false), + MINOR_MODE_TUTORIAL = LINEAR_RACE(4, false), MINOR_MODE_3_STRIKES = BATTLE_ARENA(0), MINOR_MODE_CUTSCENE = BATTLE_ARENA(1), @@ -576,6 +577,13 @@ public: else return false; } // isBattleMode + // ------------------------------------------------------------------------ + + bool isTutorialMode() + { + return m_minor_mode == MINOR_MODE_TUTORIAL; + } + // ------------------------------------------------------------------------ /** \brief Returns true if the current mode has laps. */ bool modeHasLaps() diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 0829792c4..df328557d 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -44,7 +44,6 @@ #include "states_screens/kart_selection.hpp" #include "states_screens/options_screen_video.hpp" #include "states_screens/state_manager.hpp" -#include "states_screens/tutorial_screen.hpp" #if DEBUG_MENU_ITEM #include "states_screens/feature_unlocked.hpp" @@ -125,6 +124,12 @@ void MainMenuScreen::init() r = getWidget("menu_toprow"); r->setFocusForPlayer(PLAYER_ID_GAME_MASTER); DemoWorld::resetIdleTime(); + +#if _IRR_MATERIAL_MAX_TEXTURES_ < 8 + getWidget("logo")->setImage("gui/logo_broken.png", + IconButtonWidget::ICON_PATH_TYPE_RELATIVE); +#endif + } // init // ---------------------------------------------------------------------------- @@ -178,7 +183,6 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, std::string selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER); - /* if (selection == "story") { @@ -296,6 +300,40 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, { StateManager::get()->pushScreen(HelpScreen1::getInstance()); } + else if (selection == "startTutorial") + { + race_manager->setNumLocalPlayers(1); + race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); + race_manager->setMinorMode (RaceManager::MINOR_MODE_TUTORIAL); + race_manager->setNumKarts( 1 ); + race_manager->setTrack( "tutorial" ); + race_manager->setDifficulty(RaceManager::DIFFICULTY_EASY); + + // Use keyboard 0 by default (FIXME: let player choose?) + InputDevice* device = input_manager->getDeviceList()->getKeyboard(0); + + // Create player and associate player with keyboard + StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(), + device); + + if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) + { + fprintf(stderr, "[MainMenuScreen] WARNING: cannot find kart '%s', will revert to default\n", + UserConfigParams::m_default_kart.c_str()); + UserConfigParams::m_default_kart.revertToDefaults(); + } + race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); + + // ASSIGN should make sure that only input from assigned devices + // is read. + input_manager->getDeviceList()->setAssignMode(ASSIGN); + input_manager->getDeviceList() + ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); + + StateManager::get()->enterGameState(); + network_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + } else if (selection == "story") { GameSlot* slot = unlock_manager->getCurrentSlot(); @@ -320,10 +358,6 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, OverWorld::enterOverWorld(); } } - else if (selection == "tutorial") - { - StateManager::get()->pushScreen(TutorialScreen::getInstance()); - } else if (selection == "addons") { StateManager::get()->pushScreen(AddonsScreen::getInstance()); diff --git a/src/states_screens/tutorial_screen.cpp b/src/states_screens/tutorial_screen.cpp deleted file mode 100644 index a62eb0858..000000000 --- a/src/states_screens/tutorial_screen.cpp +++ /dev/null @@ -1,275 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010 Alejandro Santiago -// -// 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 3 -// 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 "states_screens/tutorial_screen.hpp" - -#include "guiengine/widgets/list_widget.hpp" -#include "utils/string_utils.hpp" -#include "graphics/irr_driver.hpp" - -#include "tutorial/tutorial_manager.hpp" -#include "config/user_config.hpp" -#include "guiengine/engine.hpp" -#include "guiengine/widgets/dynamic_ribbon_widget.hpp" -#include "input/device_manager.hpp" -#include "input/input_manager.hpp" -#include "io/file_manager.hpp" -#include "karts/kart_properties_manager.hpp" -#include "network/network_manager.hpp" -#include "race/race_manager.hpp" -#include "states_screens/state_manager.hpp" -#include "utils/translation.hpp" - -#include - -#include "irrString.h" - -using irr::core::stringw; -using irr::core::stringc; - -using namespace GUIEngine; - -DEFINE_SCREEN_SINGLETON( TutorialScreen ); - -// ------------------------------------------------------------------------------------------------------ - -TutorialScreen::TutorialScreen() : Screen("tutorial.stkgui") -{ - m_tutorial_manager = new TutorialManager(); -} - -// ------------------------------------------------------------------------------------------------------ - -void TutorialScreen::loadedFromFile() -{ -} - -// ------------------------------------------------------------------------------------------------------ - -void TutorialScreen::onUpdate(float elapsed_time, irr::video::IVideoDriver*) -{ -} - -// ------------------------------------------------------------------------------------------------------ - -void TutorialScreen::init() -{ - Screen::init(); - - ListWidget* tutorials_list = this->getWidget("tutorials"); - assert( tutorials_list != NULL ); - - // FIXME different icons for each tutorial option & add then to - video::ITexture* tutorial_icon = irr_driver->getTexture( file_manager->getGUIDir() + "/keyboard.png" ); - - m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv() ); - m_icon_bank->addTextureAsSprite(tutorial_icon); - - // scale icons depending on screen resolution. the numbers below are a bit arbitrary - const int screen_width = irr_driver->getFrameSize().Width; - const float scale = 0.3f + 0.2f*std::max(0, screen_width - 640)/564.0f; - m_icon_bank->setScale(scale); - - // Add the icons to our list - tutorials_list->setIcons(m_icon_bank); - - // Re-build track list everytime (accounts for locking changes, etc.) - //tutorials_list->clearItems(); - - const std::vector& m_tutorials_list = m_tutorial_manager->getTutorialsList(); - - - for (int n=0; n<= (int)m_tutorials_list.size(); n++){ - tutorials_list->addItem(BASIC_DRIVING, " Basic Driving" , 0); - } - - // FIXME Hard coded tutorial options - /*tutorials_list->addItem(BASIC_DRIVING, " Basic Driving" , 0); - tutorials_list->addItem(SHARP_TURN, " Sharp Turn" , 0); - tutorials_list->addItem(NITRO, " Nitro" , 0 ); - tutorials_list->addItem(COLLECTIBLE_WEAPONS, " Collectible Weapons" , 0); - tutorials_list->addItem(SHOOTING_BACKWARDS, " Shooting Backwards" , 0);*/ - - /* for (int i=0;i<5;i++) - { - //KeyboardConfig *config = input_manager->getDeviceList()->getKeyboardConfig(i); - - std::ostringstream kbname; - kbname << "keyboard" << i; - const std::string internal_name = kbname.str(); - - //FIXME: I18N: since irrLicht's list widget has the nasty tendency to put the - // icons very close to the text, I'm adding spaces to compensate... - - } - // tutorials_list->updateItemDisplay(); - */ - - /* if (tutorials_list->getItems().empty()) - { - fprintf(stderr, "Error, no tutorial!\n"); - return; - }*/ - //tutorials_list->setSelection(0 /* whatever is first */, PLAYER_ID_GAME_MASTER, true /* focus it */); -} - -// ------------------------------------------------------------------------------------------------------ - -void TutorialScreen::eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) -{ - if (name == "back") - { - StateManager::get()->escapePressed(); - } - else if (name == "tutorials") - { - ListWidget* tutorials = this->getWidget("tutorials"); - const std::string& selection = tutorials->getSelectionInternalName(); - if (selection == BASIC_DRIVING) - { - // Verify the kart in the config exists - if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) - UserConfigParams::m_default_kart.revertToDefaults(); - - // Use latest used device - InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice(); - - // Create player and associate player with device (FIXME: ask for player ident) - StateManager::get()->createActivePlayer( UserConfigParams::m_all_players.get(0), device ); - - // Set up race manager appropriately - race_manager->setNumLocalPlayers(1); - race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); - - // ASSIGN should make sure that only input from assigned devices is read. - input_manager->getDeviceList()->setAssignMode(ASSIGN); - - // Go straight to the race - StateManager::get()->enterGameState(); - - // Initialise global data - necessary even in local games to avoid - // many if tests in other places (e.g. if network_game call - // network_manager else call race_manager). - network_manager->initCharacterDataStructures(); - - // Launch tutorial - m_tutorial_manager->getTutorial(selection)->setRace(); - - // FIXME this code have to be in Tutorial class (and loaded from file xD) - RaceManager::MajorRaceModeType m_major; - RaceManager::MinorRaceModeType m_minor; - RaceManager::Difficulty m_difficulty; - - m_minor = RaceManager::MINOR_MODE_NORMAL_RACE; - m_major = RaceManager::MAJOR_MODE_SINGLE; - m_difficulty = RaceManager::DIFFICULTY_EASY; - - race_manager->setMinorMode(m_minor); - race_manager->setMajorMode(m_major); - race_manager->setTrack((std::string)"canyon"); - - race_manager->setDifficulty(m_difficulty); - race_manager->setNumLaps(1); - race_manager->setNumKarts(1); - race_manager->setNumLocalPlayers(1); - //race_manager->setCoinTarget(m_energy);*/ - - // Sets up kart info, including random list of kart for AI - network_manager->setupPlayerKartInfo(); - race_manager->startNew(false); - } - else if (name == SHARP_TURN) - { - } - else if (name == NITRO) - { - } - else if (name == COLLECTIBLE_WEAPONS) - { - } - else if (name == SHOOTING_BACKWARDS) - { - } - } -} - /*int i = -1, read = 0; - read = sscanf( selection.c_str(), "gamepad%i", &i ); - if (read == 1 && i != -1) - { - OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceList()->getGamepadConfig(i) ); - StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance()); - //updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) ); - } - else - { - std::cerr << "Cannot read internal gamepad input device ID : " << selection.c_str() << std::endl; - }*/ - - - /* DynamicRibbonWidget* w = this->getWidget("tutorial"); - assert( w != NULL ); - - // only player 0 can start a challenge (i.e. we have no multiplayer tutorial) - std::string selection = w->getSelectionIDString( PLAYER_ID_GAME_MASTER ); -*/ - /*if (selection == "locked") - { - unlock_manager->playLockSound(); - } - else if (!selection.empty()) - { - //FIXME: simplify and centralize race start sequence!! - - // Verify the kart in the config exists - if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) - { - UserConfigParams::m_default_kart.revertToDefaults(); - } - - // Use latest used device - InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice(); - - // Create player and associate player with device (FIXME: ask for player ident) - StateManager::get()->createActivePlayer( UserConfigParams::m_all_players.get(0), device ); - - // Set up race manager appropriately - race_manager->setNumLocalPlayers(1); - race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); - - // ASSIGN should make sure that only input from assigned devices is read. - input_manager->getDeviceList()->setAssignMode(ASSIGN); - - // Go straight to the race - StateManager::get()->enterGameState(); - - // Initialise global data - necessary even in local games to avoid - // many if tests in other places (e.g. if network_game call - // network_manager else call race_manager). - network_manager->initCharacterDataStructures(); - - // Launch challenge - unlock_manager->getChallenge(selection)->setRace(); - - // Sets up kart info, including random list of kart for AI - network_manager->setupPlayerKartInfo(); - race_manager->startNew(); - //} - } -}*/ - -// ------------------------------------------------------------------------------------------------------ - diff --git a/src/states_screens/tutorial_screen.hpp b/src/states_screens/tutorial_screen.hpp deleted file mode 100644 index 52bb9a72d..000000000 --- a/src/states_screens/tutorial_screen.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010 Alejandro Santiago -// -// 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 3 -// 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. - -#ifndef TUTORIALSCREEN_H -#define TUTORIALSCREEN_H - -#include -#include "guiengine/screen.hpp" -#include "guiengine/CGUISpriteBank.h" - -using namespace irr::core; - -const std::string BASIC_DRIVING = "basicdriving"; -const std::string SHARP_TURN = "st"; -const std::string NITRO = "nt"; -const std::string COLLECTIBLE_WEAPONS = "cw"; -const std::string SHOOTING_BACKWARDS = "sb"; - -class TutorialScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton -{ - - friend class GUIEngine::ScreenSingleton; - TutorialScreen(); - - irr::gui::STKModifiedSpriteBank* m_icon_bank; - - - public: - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void loadedFromFile(); - - /** \brief implement optional callback from parent class GUIEngine::Screen */ - void onUpdate(float dt, irr::video::IVideoDriver*); - - /** \brief implement callback from parent class GUIEngine::Screen */ - void init(); - - /** \brief implement callback from parent class GUIEngine::Screen */ - void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID); -}; - -#endif // TUTORIALSCREEN_H diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 766ad1ce0..0e696f8bb 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -467,6 +467,76 @@ void TrackObject::onTriggerItemApproached(Item* who) new RacePausedDialog(0.8f, 0.6f); //dynamic_cast(World::getWorld())->scheduleSelectKart(); } + else if (m_action == "tutorial_drive") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + World::getWorld()->getRaceGUI()->addMessage(_("Drive with the arrow keys"), NULL, 5.0f, + video::SColor(255, 255,255,255), + false, true); + } + else if (m_action == "tutorial_bananas") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + World::getWorld()->getRaceGUI()->addMessage(_("Avoid bananas!"), NULL, 5.0f, + video::SColor(255, 255,255,255), + false, true); + } + else if (m_action == "tutorial_giftboxes") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + core::stringw msg = _("Collect gift boxes, and fire the weapon with to blow away these boxes!"); + std::vector parts = StringUtils::split(msg, '\n', false); + + for (unsigned int i = 0; i < parts.size(); i++) + { + World::getWorld()->getRaceGUI()->addMessage(parts[i], NULL, 7.0f, + video::SColor(255, 255,255,255), + false, false); + } + } + else if (m_action == "tutorial_nitro_collect") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + World::getWorld()->getRaceGUI()->addMessage(_("Collect nitro bottles (we will use them after the curve)"), NULL, 5.0f, + video::SColor(255, 255,255,255), + false, false); + } + else if (m_action == "tutorial_nitro_use") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + World::getWorld()->getRaceGUI()->addMessage(_("Use the nitro you collected by pressing the key!"), NULL, 5.0f, + video::SColor(255, 255,255,255), + false, false); + } + else if (m_action == "tutorial_rescue") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + World::getWorld()->getRaceGUI()->addMessage(_("Oops! When you're in trouble, press to be rescued"), NULL, 5.0f, + video::SColor(255, 255,255,255), + false, false); + } + else if (m_action == "tutorial_skidding") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + + World::getWorld()->getRaceGUI()->addMessage(_("Skidding for a short while can help you turn faster to take sharp turns"), NULL, 10.0f, + video::SColor(255, 255,255,255), + false, false); + World::getWorld()->getRaceGUI()->addMessage(_("Accelerate and press the key while turning to skid."), NULL, 10.0f, + video::SColor(255, 255,255,255), + false, false); + } + else if (m_action == "tutorial_skidding2") + { + World::getWorld()->getRaceGUI()->clearAllMessages(); + + World::getWorld()->getRaceGUI()->addMessage(_("you will receive a bonus speedup as a reward!"), NULL, 10.0f, + video::SColor(255, 255,255,255), + false, false); + World::getWorld()->getRaceGUI()->addMessage(_("If you manage to skid for several seconds,"), NULL, 10.0f, + video::SColor(255, 255,255,255), + false, false); + } else { fprintf(stderr, "[TrackObject] WARNING: unknown action <%s>\n",