diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 1bd75b4be..1d868cced 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -449,7 +449,6 @@ void IrrDriver::initDevice() // so let's decide ourselves...) m_device->getCursorControl()->setVisible(true); m_pointer_shown = true; - } // initDevice //----------------------------------------------------------------------------- diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index 3201f240a..093f014a3 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -179,12 +179,20 @@ void OverWorld::onFirePressed(Controller* who) for (unsigned int n=0; nsetKartLastPositionOnOverworld(kart_xyz); - new SelectChallengeDialog(0.8f, 0.8f, challenges[n].m_challenge_id); + if (challenges[n].m_challenge_id == "tutorial") + { + scheduleTutorial(); + return; + } + else + { + race_manager->setKartLastPositionOnOverworld(kart_xyz); + new SelectChallengeDialog(0.8f, 0.8f, challenges[n].m_challenge_id); + } } // end if } // end for } diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 42010b6e6..b91695059 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -32,6 +32,7 @@ #include "graphics/camera.hpp" #include "graphics/hardware_skinning.hpp" #include "io/file_manager.hpp" +#include "input/device_manager.hpp" #include "items/projectile_manager.hpp" #include "karts/controller/player_controller.hpp" #include "karts/controller/end_controller.hpp" @@ -97,6 +98,7 @@ World::World() : WorldStatus(), m_clear_color(255,100,101,140) m_schedule_unpause = false; m_schedule_exit_race = false; m_self_destruct = false; + m_schedule_tutorial = false; m_stop_music_when_dialog_open = true; @@ -632,11 +634,50 @@ void World::updateWorld(float dt) { race_manager->exitRace(); race_manager->setAIKartOverride(""); + StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); - if (race_manager->raceWasStartedFromOverworld()) + if (m_schedule_tutorial) { - OverWorld::enterOverWorld(); + 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 (race_manager->raceWasStartedFromOverworld()) + { + OverWorld::enterOverWorld(); + } + } } } // updateWorld diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 6556b2c1b..a5202a400 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -138,6 +138,8 @@ protected: bool m_schedule_exit_race; + bool m_schedule_tutorial; + Phase m_scheduled_pause_phase; /** Set when the world needs to be deleted but you can't do it immediately @@ -250,6 +252,8 @@ public: void schedulePause(Phase phase); void scheduleUnpause(); void scheduleExitRace() { m_schedule_exit_race = true; } + void scheduleTutorial() { m_schedule_exit_race = true; + m_schedule_tutorial = true; } void updateWorld(float dt); void handleExplosion(const Vec3 &xyz, AbstractKart *kart_hit, PhysicalObject *object); diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index d036cdfa2..444582533 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -387,6 +387,8 @@ void RaceGUIOverworld::drawGlobalMiniMap() m_current_challenge = NULL; for (unsigned int n=0; nmapPoint2MiniMap(challenges[n].m_position, &draw_at); @@ -423,18 +425,28 @@ void RaceGUIOverworld::drawGlobalMiniMap() // ---- Draw nearby challenge if any + core::rect pos(15, + 10, + 15 + UserConfigParams::m_width/2, + 10 + GUIEngine::getTitleFontHeight()); + m_close_to_a_challenge = false; for (unsigned int n=0; n pos(15, - 10, - 15 + UserConfigParams::m_width/2, - 10 + GUIEngine::getTitleFontHeight()); + + if (challenges[n].m_challenge_id == "tutorial") + { + gui::ScalableFont* font = GUIEngine::getTitleFont(); + font->draw(_("Tutorial"), pos, video::SColor(255,255,255,255), + false, true /* vcenter */, NULL); + continue; + } const ChallengeData* challenge = unlock_manager->getChallenge(challenges[n].m_challenge_id); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 03be19d6d..9a5c9f962 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -885,6 +885,7 @@ bool Track::loadMainTrack(const XMLNode &root) GameSlot* slot = unlock_manager->getCurrentSlot(); for (unsigned int c=0; cgetChallenge(m_challenges[c].m_challenge_id) ->isSolvedAtAnyDifficulty()) { @@ -912,6 +913,7 @@ bool Track::loadMainTrack(const XMLNode &root) GameSlot* slot = unlock_manager->getCurrentSlot(); for (unsigned int c=0; cgetChallenge(m_challenges[c].m_challenge_id) ->isSolvedAtAnyDifficulty()) { @@ -1026,42 +1028,50 @@ bool Track::loadMainTrack(const XMLNode &root) // for challenge orbs, a bit more work to do if (challenge.size() > 0) { - const ChallengeData* c = unlock_manager->getChallenge(challenge); - if (c == NULL) + const ChallengeData* c = NULL; + + if (challenge != "tutorial") { - Log::error("track", "Cannot find challenge named <%s>\n", - challenge.c_str()); - scene_node->remove(); - continue; + c = unlock_manager->getChallenge(challenge); + if (c == NULL) + { + Log::error("track", "Cannot find challenge named <%s>\n", + challenge.c_str()); + scene_node->remove(); + continue; + } } m_challenges.push_back( OverworldChallenge(xyz, challenge) ); - if (c->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX) + if (c != NULL && c->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX) { } else { - Track* t = track_manager->getTrack(c->getTrackId()); - if (t == NULL) + if (challenge != "tutorial") { - Log::error("track", "Cannot find track named <%s>\n", - c->getTrackId().c_str()); - continue; + Track* t = track_manager->getTrack(c->getTrackId()); + if (t == NULL) + { + Log::error("track", "Cannot find track named <%s>\n", + c->getTrackId().c_str()); + continue; + } + + std::string sshot = t->getScreenshotFile(); + video::ITexture* screenshot = irr_driver->getTexture(sshot); + + if (screenshot == NULL) + { + Log::error("track", + "Cannot find track screenshot <%s>", + sshot.c_str()); + continue; + } + scene_node->getMaterial(0).setTexture(0, screenshot); } - - std::string sshot = t->getScreenshotFile(); - video::ITexture* screenshot = irr_driver->getTexture(sshot); - - if (screenshot == NULL) - { - Log::error("track", - "Cannot find track screenshot <%s>", - sshot.c_str()); - continue; - } - scene_node->getMaterial(0).setTexture(0, screenshot); } // make transparent diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 9b370dc2d..0291413e3 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -111,6 +111,7 @@ public: return m_force_field; } + bool isForceFieldSet() const { return m_force_field_set; } const OverworldForceField& getForceField() const {