diff --git a/data/gui/ghost_replay_info_dialog.stkgui b/data/gui/ghost_replay_info_dialog.stkgui index d55cfe711..0f6009f21 100644 --- a/data/gui/ghost_replay_info_dialog.stkgui +++ b/data/gui/ghost_replay_info_dialog.stkgui @@ -19,7 +19,7 @@
-
diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index a0c969a57..dd925d114 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -710,7 +710,8 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID, // ... when in-game if (StateManager::get()->getGameState() == GUIEngine::GAME && - !GUIEngine::ModalDialog::isADialogActive() ) + !GUIEngine::ModalDialog::isADialogActive() && + !race_manager->isWatchingReplay() ) { if (player == NULL) { diff --git a/src/karts/ghost_kart.cpp b/src/karts/ghost_kart.cpp index 1dfcadea1..c2892530b 100644 --- a/src/karts/ghost_kart.cpp +++ b/src/karts/ghost_kart.cpp @@ -83,14 +83,17 @@ void GhostKart::update(float dt) } const unsigned int idx = gc->getCurrentReplayIndex(); - if (idx == 0) + if (!race_manager->isWatchingReplay()) { - m_node->setVisible(false); - } - if (idx == 1) - { - // Start showing the ghost when it start racing - m_node->setVisible(true); + if (idx == 0) + { + m_node->setVisible(false); + } + if (idx == 1) + { + // Start showing the ghost when it start racing + m_node->setVisible(true); + } } const float rd = gc->getReplayDelta(); diff --git a/src/modes/standard_race.cpp b/src/modes/standard_race.cpp index 1a8640edc..47560706b 100644 --- a/src/modes/standard_race.cpp +++ b/src/modes/standard_race.cpp @@ -21,6 +21,7 @@ #include "items/powerup_manager.hpp" #include "karts/abstract_kart.hpp" #include "karts/controller/controller.hpp" +#include "karts/controller/ghost_controller.hpp" #include "network/network_config.hpp" //----------------------------------------------------------------------------- @@ -34,6 +35,11 @@ StandardRace::StandardRace() : LinearWorld() */ bool StandardRace::isRaceOver() { + if (race_manager->isWatchingReplay()) + { + return dynamic_cast + (m_karts[0]->getController())->isReplayEnd(); + } // The race is over if all players have finished the race. Remaining // times for AI opponents will be estimated in enterRaceOverState return race_manager->allPlayerFinished(); diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 2bbc9f996..47b2a13ff 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -285,10 +285,11 @@ void World::reset() Log::info("World", "Start Recording race."); ReplayRecorder::get()->init(); } - if(NetworkConfig::get()->isServer() && !ProfileWorld::isNoGraphics()) + if((NetworkConfig::get()->isServer() && !ProfileWorld::isNoGraphics()) || + race_manager->isWatchingReplay()) { - // In case that the server is running with gui, create a camera and - // attach it to the first kart. + // In case that the server is running with gui or watching replay, + // create a camera and attach it to the first kart. Camera::createCamera(World::getWorld()->getKart(0)); } @@ -448,6 +449,7 @@ World::~World() ReplayRecorder::get()->reset(); race_manager->setRaceGhostKarts(false); race_manager->setRecordRace(false); + race_manager->setWatchingReplay(false); Camera::removeAllCameras(); diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 683049cfe..141d55573 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -78,6 +78,7 @@ RaceManager::RaceManager() setReverseTrack(false); setRecordRace(false); setRaceGhostKarts(false); + setWatchingReplay(false); setTrack("jungle"); m_default_ai_list.clear(); setNumPlayers(0); @@ -913,6 +914,7 @@ void RaceManager::startSingleRace(const std::string &track_ident, const int num_laps, bool from_overworld) { + assert(!m_watching_replay); StateManager::get()->enterGameState(); setTrack(track_ident); @@ -931,10 +933,44 @@ void RaceManager::startSingleRace(const std::string &track_ident, //----------------------------------------------------------------------------- /** Fills up the remaining kart slots with AI karts. -v*/ + */ void RaceManager::setupPlayerKartInfo() { computeRandomKartList(); } // setupPlayerKartInfo +//----------------------------------------------------------------------------- +/** \brief Function to start the race with only ghost kart(s) and watch. + * \param trackIdent Internal name of the track to race on + * \param num_laps Number of laps to race, or -1 if number of laps is + * not relevant in current mode + */ +void RaceManager::startWatchingReplay(const std::string &track_ident, + const int num_laps) +{ + assert(m_watching_replay && m_has_ghost_karts && !m_will_record_race); + StateManager::get()->enterGameState(); + setTrack(track_ident); + setMajorMode(RaceManager::MAJOR_MODE_SINGLE); + setCoinTarget(0); + m_num_karts = ReplayPlay::get()->getNumGhostKart(); + + Log::verbose("RaceManager", "%u ghost kart(s) for watching replay only\n", + (unsigned int)m_num_karts); + + int init_gp_rank = 0; + + for(int i = 0; i < m_num_karts; i++) + { + m_kart_status.push_back(KartStatus(ReplayPlay::get()->getGhostKartName(i), + i, -1, -1, init_gp_rank, KT_GHOST, PLAYER_DIFFICULTY_NORMAL)); + init_gp_rank ++; + } + + m_track_number = 0; + startNextRace(); +} // startSingleRace + +//----------------------------------------------------------------------------- + /* EOF */ diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 34701ea9c..e5a564814 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -354,6 +354,8 @@ private: bool m_will_record_race; bool m_has_ghost_karts; + + bool m_watching_replay; public: RaceManager(); ~RaceManager(); @@ -407,6 +409,7 @@ public: void saveGP(); void startSingleRace(const std::string &track_ident, const int num_laps, bool from_overworld); + void startWatchingReplay(const std::string &track_ident, const int num_laps); void setupPlayerKartInfo(); void kartFinishedRace(const AbstractKart* kart, float time); void setNumPlayers(int players, int local_players=-1); @@ -727,6 +730,11 @@ public: m_has_ghost_karts = ghost; } // setRaceGhostKarts // ------------------------------------------------------------------------ + void setWatchingReplay(bool watch) + { + m_watching_replay = watch; + } // setWatchingReplay + // ------------------------------------------------------------------------ bool willRecordRace() const { return m_will_record_race; @@ -736,6 +744,11 @@ public: { return m_has_ghost_karts; } // hasGhostKarts + // ------------------------------------------------------------------------ + bool isWatchingReplay() const + { + return m_watching_replay; + } // isWatchingReplay }; // RaceManager diff --git a/src/states_screens/dialogs/ghost_replay_info_dialog.cpp b/src/states_screens/dialogs/ghost_replay_info_dialog.cpp index 649c2eba8..0bab44f40 100644 --- a/src/states_screens/dialogs/ghost_replay_info_dialog.cpp +++ b/src/states_screens/dialogs/ghost_replay_info_dialog.cpp @@ -73,19 +73,26 @@ GUIEngine::EventPropagation std::string track_name = m_rd.m_track_name; int laps = m_rd.m_laps; int replay_id = m_replay_id; - bool record = m_record_race; + + race_manager->setRecordRace(m_record_race); + race_manager->setWatchingReplay(m_watch_only); ModalDialog::dismiss(); ReplayPlay::get()->setReplayFile(replay_id); race_manager->setRaceGhostKarts(true); - race_manager->setRecordRace(record); + race_manager->setNumKarts(race_manager->getNumLocalPlayers()); // Disable accidentally unlocking of a challenge PlayerManager::getCurrentPlayer()->setCurrentChallenge(""); race_manager->setReverseTrack(reverse); - race_manager->startSingleRace(track_name, laps, false); + + if (race_manager->isWatchingReplay()) + race_manager->startWatchingReplay(track_name, laps); + else + race_manager->startSingleRace(track_name, laps, false); + return GUIEngine::EVENT_BLOCK; } else if(selection == "remove") diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 49db63595..9502685b3 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -497,7 +497,7 @@ void RaceResultGUI::backToLobby() const int rm_id = kart->getWorldKartId() - (race_manager->getNumberOfKarts() - race_manager->getNumPlayers()); - if (rm_id >= 0) + if (rm_id >= 0 && !race_manager->isWatchingReplay()) ri->m_kart_name = race_manager->getKartInfo(rm_id).getPlayerName(); else ri->m_kart_name = translations->fribidize(kart->getName()); @@ -869,7 +869,7 @@ void RaceResultGUI::backToLobby() const int rm_id = kart_id - (race_manager->getNumberOfKarts() - race_manager->getNumPlayers()); - if (rm_id >= 0) + if (rm_id >= 0 && !race_manager->isWatchingReplay()) ri->m_kart_name = race_manager->getKartInfo(rm_id).getPlayerName(); else ri->m_kart_name = translations->fribidize(kart->getName());