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());