2008-09-21 21:52:28 -04:00
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
2015-03-29 20:31:42 -04:00
|
|
|
// Copyright (C) 2004-2015 SuperTuxKart-Team
|
2008-09-21 21:52:28 -04:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2010-02-08 07:59:03 -05:00
|
|
|
#include "modes/world_status.hpp"
|
2009-01-05 17:51:02 -05:00
|
|
|
|
2016-10-27 06:33:42 -04:00
|
|
|
#include "main_loop.hpp"
|
2010-07-06 19:10:47 -04:00
|
|
|
#include "audio/music_manager.hpp"
|
2008-09-21 21:52:28 -04:00
|
|
|
#include "audio/sfx_base.hpp"
|
2014-09-17 07:38:21 -04:00
|
|
|
#include "audio/sfx_manager.hpp"
|
2009-06-11 06:00:43 -04:00
|
|
|
#include "config/stk_config.hpp"
|
2014-02-25 20:52:16 -05:00
|
|
|
#include "config/user_config.hpp"
|
2012-05-08 03:07:15 -04:00
|
|
|
#include "graphics/irr_driver.hpp"
|
2020-02-15 01:00:48 -05:00
|
|
|
#include "guiengine/engine.hpp"
|
2010-05-10 19:53:32 -04:00
|
|
|
#include "guiengine/modaldialog.hpp"
|
2012-03-19 16:21:11 -04:00
|
|
|
#include "karts/abstract_kart.hpp"
|
2020-02-15 01:00:48 -05:00
|
|
|
#include "modes/world.hpp"
|
2016-03-31 17:51:39 -04:00
|
|
|
#include "network/network_config.hpp"
|
2016-11-25 06:17:24 -05:00
|
|
|
#include "network/protocols/client_lobby.hpp"
|
2017-01-23 16:05:46 -05:00
|
|
|
#include "network/rewind_manager.hpp"
|
2016-03-31 17:51:39 -04:00
|
|
|
#include "network/race_event_manager.hpp"
|
2010-07-06 19:10:47 -04:00
|
|
|
#include "tracks/track.hpp"
|
2020-02-27 20:43:25 -05:00
|
|
|
#include "utils/stk_process.hpp"
|
2008-09-21 21:52:28 -04:00
|
|
|
|
2012-05-08 03:07:15 -04:00
|
|
|
#include <irrlicht.h>
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2020-02-27 20:43:25 -05:00
|
|
|
WorldStatus::WorldStatus() : m_process_type(STKProcess::getType())
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_MAIN)
|
|
|
|
main_loop->setFrameBeforeLoadingWorld();
|
2010-07-06 19:10:47 -04:00
|
|
|
m_clock_mode = CLOCK_CHRONO;
|
2018-05-14 20:40:25 -04:00
|
|
|
m_phase = SETUP_PHASE;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2014-09-17 07:38:21 -04:00
|
|
|
m_prestart_sound = SFXManager::get()->createSoundSource("pre_start_race");
|
|
|
|
m_start_sound = SFXManager::get()->createSoundSource("start_race");
|
|
|
|
m_track_intro_sound = SFXManager::get()->createSoundSource("track_intro");
|
2019-02-26 22:07:08 -05:00
|
|
|
m_time = 0.0f;
|
|
|
|
m_time_ticks = 0;
|
|
|
|
m_auxiliary_ticks = 0;
|
|
|
|
m_count_up_ticks = 0;
|
2010-07-06 19:10:47 -04:00
|
|
|
|
2016-05-02 05:32:04 -04:00
|
|
|
m_play_track_intro_sound = UserConfigParams::m_music;
|
|
|
|
m_play_ready_set_go_sounds = true;
|
2016-03-31 17:51:39 -04:00
|
|
|
m_play_racestart_sounds = true;
|
2018-12-31 12:01:49 -05:00
|
|
|
m_live_join_world = false;
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_MAIN)
|
|
|
|
{
|
|
|
|
IrrlichtDevice *device = irr_driver->getDevice();
|
|
|
|
|
|
|
|
if (device->getTimer()->isStopped())
|
|
|
|
device->getTimer()->start();
|
|
|
|
}
|
2010-02-08 07:59:03 -05:00
|
|
|
} // WorldStatus
|
2009-08-23 11:42:58 -04:00
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-02-09 04:24:45 -05:00
|
|
|
/** Resets all status information, used when starting a new race.
|
|
|
|
*/
|
2018-10-02 07:25:30 -04:00
|
|
|
void WorldStatus::reset(bool restart)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2010-02-09 04:24:45 -05:00
|
|
|
m_time = 0.0f;
|
2018-02-21 06:18:45 -05:00
|
|
|
m_time_ticks = 0;
|
|
|
|
m_auxiliary_ticks = 0;
|
|
|
|
m_count_up_ticks = 0;
|
2019-01-04 01:54:00 -05:00
|
|
|
m_start_music_ticks = -1;
|
2020-04-03 02:28:21 -04:00
|
|
|
// how long to display the 'music' message
|
|
|
|
m_race_ticks =
|
|
|
|
stk_config->time2Ticks(stk_config->m_music_credit_time);
|
2019-01-04 01:54:00 -05:00
|
|
|
m_live_join_ticks = -1;
|
2016-05-02 15:53:34 -04:00
|
|
|
m_engines_started = false;
|
|
|
|
|
2010-07-06 19:10:47 -04:00
|
|
|
// Using SETUP_PHASE will play the track into sfx first, and has no
|
|
|
|
// other side effects.
|
2015-02-08 19:15:48 -05:00
|
|
|
m_phase = UserConfigParams::m_race_now ? MUSIC_PHASE : SETUP_PHASE;
|
|
|
|
|
2015-02-08 19:56:56 -05:00
|
|
|
// Parts of the initialisation-phase are skipped so do it here
|
2015-02-08 19:15:48 -05:00
|
|
|
if (UserConfigParams::m_race_now)
|
|
|
|
{
|
|
|
|
// Setup music and sound
|
2016-12-13 01:14:29 -05:00
|
|
|
if (Weather::getInstance())
|
|
|
|
Weather::getInstance()->playSound();
|
2015-02-08 19:15:48 -05:00
|
|
|
|
|
|
|
// Start engines
|
|
|
|
for (unsigned int i = 0; i < World::getWorld()->getNumKarts(); i++)
|
|
|
|
World::getWorld()->getKart(i)->startEngineSFX();
|
|
|
|
}
|
|
|
|
|
2010-06-06 23:31:41 -04:00
|
|
|
m_previous_phase = UNDEFINED_PHASE;
|
2010-07-06 19:10:47 -04:00
|
|
|
// Just in case that the game is reset during the intro phase
|
|
|
|
m_track_intro_sound->stop();
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_MAIN)
|
|
|
|
{
|
|
|
|
IrrlichtDevice *device = irr_driver->getDevice();
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
if (device->getTimer()->isStopped())
|
|
|
|
device->getTimer()->start();
|
2015-02-08 19:56:56 -05:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
// Set the right music
|
|
|
|
Track::getCurrentTrack()->startMusic();
|
|
|
|
}
|
2009-08-23 11:42:58 -04:00
|
|
|
} // reset
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-02-09 04:24:45 -05:00
|
|
|
/** Destructor of WorldStatus.
|
|
|
|
*/
|
2010-02-08 07:59:03 -05:00
|
|
|
WorldStatus::~WorldStatus()
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2014-10-12 17:26:45 -04:00
|
|
|
m_prestart_sound->deleteSFX();
|
|
|
|
m_start_sound->deleteSFX();
|
|
|
|
m_track_intro_sound->deleteSFX();
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_MAIN)
|
|
|
|
{
|
|
|
|
IrrlichtDevice *device = irr_driver->getDevice();
|
|
|
|
|
|
|
|
if (device->getTimer()->isStopped())
|
|
|
|
device->getTimer()->start();
|
|
|
|
}
|
2010-02-08 07:59:03 -05:00
|
|
|
} // ~WorldStatus
|
2009-08-23 11:42:58 -04:00
|
|
|
|
2016-10-27 06:33:42 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Starts the kart engines.
|
|
|
|
*/
|
|
|
|
void WorldStatus::startEngines()
|
|
|
|
{
|
|
|
|
if (m_engines_started)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_engines_started = true;
|
|
|
|
for (unsigned int i = 0; i < World::getWorld()->getNumKarts(); i++)
|
|
|
|
{
|
2019-01-04 02:25:32 -05:00
|
|
|
if (!World::getWorld()->getKart(i)->isEliminated())
|
|
|
|
World::getWorld()->getKart(i)->startEngineSFX();
|
2016-10-27 06:33:42 -04:00
|
|
|
}
|
|
|
|
} // startEngines
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-02-09 04:24:45 -05:00
|
|
|
/** Sets the clock mode and the initial time of the world clock.
|
|
|
|
* \param mode The new clock mode.
|
|
|
|
* \param initial_time The new initial time for the world clock.
|
|
|
|
*/
|
2010-02-08 07:59:03 -05:00
|
|
|
void WorldStatus::setClockMode(const ClockType mode, const float initial_time)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2010-02-26 14:09:05 -05:00
|
|
|
m_clock_mode = mode;
|
2018-02-23 07:22:49 -05:00
|
|
|
m_time_ticks = stk_config->time2Ticks(initial_time);
|
|
|
|
m_time = stk_config->ticks2Time(m_time_ticks);
|
2009-08-23 11:42:58 -04:00
|
|
|
} // setClockMode
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-02-17 06:59:51 -05:00
|
|
|
/** Called when the race is finished, but it still leaves some time
|
|
|
|
* for an end of race animation, and potentially let some more AI karts
|
|
|
|
* finish the race.
|
2010-02-09 04:24:45 -05:00
|
|
|
*/
|
2010-02-17 06:59:51 -05:00
|
|
|
void WorldStatus::enterRaceOverState()
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2018-04-18 03:18:55 -04:00
|
|
|
// Waiting for server result info
|
|
|
|
auto cl = LobbyProtocol::get<ClientLobby>();
|
|
|
|
if (cl && !cl->receivedServerResult())
|
|
|
|
return;
|
|
|
|
|
2010-07-22 18:49:56 -04:00
|
|
|
// Don't enter race over if it's already race over
|
2014-08-30 12:34:44 -04:00
|
|
|
if (m_phase == DELAY_FINISH_PHASE || m_phase == RESULT_DISPLAY_PHASE ||
|
|
|
|
m_phase == FINISH_PHASE)
|
2010-07-22 18:49:56 -04:00
|
|
|
return;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-17 06:59:51 -05:00
|
|
|
m_phase = DELAY_FINISH_PHASE;
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks = 0;
|
2010-02-17 06:59:51 -05:00
|
|
|
} // enterRaceOverState
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Called when it's really over (delay over if any). This function must be
|
|
|
|
* called after all stats were updated from the different modes!
|
|
|
|
*/
|
|
|
|
void WorldStatus::terminateRace()
|
|
|
|
{
|
|
|
|
} // terminateRace
|
2009-08-23 11:42:58 -04:00
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2016-08-31 02:31:59 -04:00
|
|
|
/** Update, called once per frame. Called early on before physics are
|
|
|
|
* updated.
|
|
|
|
* \param dt Time step.
|
|
|
|
*/
|
2018-03-19 18:25:39 -04:00
|
|
|
void WorldStatus::update(int ticks)
|
2016-08-31 02:31:59 -04:00
|
|
|
{
|
|
|
|
} // update
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Updates the world time and clock (which might be running backwards), and
|
|
|
|
* all status information, called once per frame at the end of the main
|
|
|
|
* loop.
|
2018-03-19 18:25:39 -04:00
|
|
|
* \param ticks Number of ticks (physics time steps) - should be 1.
|
2010-02-09 04:24:45 -05:00
|
|
|
*/
|
2018-03-19 18:25:39 -04:00
|
|
|
void WorldStatus::updateTime(int ticks)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2018-11-03 04:31:51 -04:00
|
|
|
switch (m_phase.load())
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
|
|
|
// Note: setup phase must be a separate phase, since the race_manager
|
|
|
|
// checks the phase when updating the camera: in the very first time
|
|
|
|
// step dt is large (it includes loading time), so the camera might
|
|
|
|
// tilt way too much. A separate setup phase for the first frame
|
|
|
|
// simplifies this handling
|
|
|
|
case SETUP_PHASE:
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks= 0;
|
2010-07-06 19:10:47 -04:00
|
|
|
m_phase = TRACK_INTRO_PHASE;
|
2014-08-30 12:23:59 -04:00
|
|
|
|
2016-05-02 05:32:04 -04:00
|
|
|
if (m_play_track_intro_sound)
|
2012-06-16 15:41:21 -04:00
|
|
|
{
|
2011-02-28 11:19:43 -05:00
|
|
|
m_track_intro_sound->play();
|
2012-06-16 15:41:21 -04:00
|
|
|
}
|
2014-08-30 12:23:59 -04:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_MAIN && Weather::getInstance())
|
2014-08-30 12:23:59 -04:00
|
|
|
{
|
2016-12-13 01:14:29 -05:00
|
|
|
Weather::getInstance()->playSound();
|
2014-08-30 12:23:59 -04:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:51:39 -04:00
|
|
|
return; // Do not increase time
|
2010-07-06 19:10:47 -04:00
|
|
|
case TRACK_INTRO_PHASE:
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks++;
|
2014-07-28 19:16:32 -04:00
|
|
|
|
|
|
|
if (UserConfigParams::m_artist_debug_mode &&
|
2017-06-13 18:28:06 -04:00
|
|
|
!NetworkConfig::get()->isNetworking() &&
|
2020-02-27 20:42:44 -05:00
|
|
|
RaceManager::get()->getNumberOfKarts() -
|
|
|
|
RaceManager::get()->getNumSpareTireKarts() == 1 &&
|
|
|
|
RaceManager::get()->getTrackName() != "tutorial")
|
2014-08-30 12:34:44 -04:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks += 6;
|
2014-08-30 12:34:44 -04:00
|
|
|
}
|
2014-07-28 19:16:32 -04:00
|
|
|
|
2016-05-02 15:53:34 -04:00
|
|
|
if (!m_play_track_intro_sound)
|
|
|
|
{
|
|
|
|
startEngines();
|
|
|
|
}
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2019-02-10 11:28:28 -05:00
|
|
|
// Wait before ready phase
|
|
|
|
if (m_auxiliary_ticks < stk_config->time2Ticks(3.0f))
|
|
|
|
return;
|
|
|
|
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks = 0;
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2016-03-31 17:51:39 -04:00
|
|
|
// In a networked game the client needs to wait for a notification
|
2016-11-25 06:17:24 -05:00
|
|
|
// from the server that all clients and the server are ready to
|
|
|
|
// start the game. The server will actually wait for all clients
|
|
|
|
// to confirm that they have started the race before starting
|
|
|
|
// itself. In a normal race, this phase is skipped and the race
|
|
|
|
// starts immediately.
|
2018-04-23 13:01:47 -04:00
|
|
|
if (NetworkConfig::get()->isNetworking())
|
|
|
|
{
|
|
|
|
m_phase = WAIT_FOR_SERVER_PHASE;
|
|
|
|
// In networked races, inform the start game protocol that
|
|
|
|
// the world has been setup
|
2018-12-31 12:01:49 -05:00
|
|
|
if (!m_live_join_world)
|
|
|
|
{
|
|
|
|
auto lobby = LobbyProtocol::get<LobbyProtocol>();
|
|
|
|
assert(lobby);
|
|
|
|
lobby->finishedLoadingWorld();
|
|
|
|
}
|
2018-04-23 13:01:47 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_play_ready_set_go_sounds)
|
|
|
|
m_prestart_sound->play();
|
|
|
|
m_phase = READY_PHASE;
|
|
|
|
}
|
2016-03-31 17:51:39 -04:00
|
|
|
return; // Don't increase time
|
|
|
|
case WAIT_FOR_SERVER_PHASE:
|
2018-11-03 04:31:51 -04:00
|
|
|
{
|
2018-12-31 12:01:49 -05:00
|
|
|
if (m_live_join_world)
|
|
|
|
{
|
|
|
|
m_auxiliary_ticks++;
|
|
|
|
// Add 3 seconds delay before telling server finish loading
|
|
|
|
// world, so previous (if any) disconnected player has left
|
|
|
|
// fully
|
2019-01-01 02:46:45 -05:00
|
|
|
if (m_auxiliary_ticks == stk_config->time2Ticks(3.0f))
|
2018-12-31 12:01:49 -05:00
|
|
|
{
|
2019-02-03 02:27:01 -05:00
|
|
|
auto cl = LobbyProtocol::get<ClientLobby>();
|
|
|
|
assert(cl);
|
|
|
|
cl->finishedLoadingWorld();
|
2019-07-16 01:48:25 -04:00
|
|
|
#ifndef MOBILE_STK
|
2019-02-03 02:27:01 -05:00
|
|
|
static bool helper_msg_shown = false;
|
|
|
|
if (!helper_msg_shown && cl->isSpectator())
|
|
|
|
{
|
|
|
|
helper_msg_shown = true;
|
|
|
|
cl->addSpectateHelperMessage();
|
|
|
|
}
|
|
|
|
#endif
|
2018-12-31 12:01:49 -05:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2018-11-03 04:31:51 -04:00
|
|
|
return; // Don't increase time
|
|
|
|
}
|
|
|
|
case SERVER_READY_PHASE:
|
2016-11-25 06:17:24 -05:00
|
|
|
{
|
2018-04-23 13:01:47 -04:00
|
|
|
auto lobby = LobbyProtocol::get<LobbyProtocol>();
|
2018-08-26 21:16:35 -04:00
|
|
|
if (lobby && lobby->isRacing())
|
|
|
|
{
|
|
|
|
if (m_play_ready_set_go_sounds)
|
|
|
|
m_prestart_sound->play();
|
|
|
|
m_phase = READY_PHASE;
|
|
|
|
}
|
2016-03-31 17:51:39 -04:00
|
|
|
return; // Don't increase time
|
2016-11-25 06:17:24 -05:00
|
|
|
}
|
2008-09-21 21:52:28 -04:00
|
|
|
case READY_PHASE:
|
2016-11-22 01:57:15 -05:00
|
|
|
startEngines();
|
2018-02-23 07:22:49 -05:00
|
|
|
// One second
|
|
|
|
if (m_auxiliary_ticks > stk_config->getPhysicsFPS())
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2016-05-02 05:32:04 -04:00
|
|
|
if (m_play_ready_set_go_sounds)
|
2014-08-30 12:34:44 -04:00
|
|
|
{
|
|
|
|
m_prestart_sound->play();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_phase = SET_PHASE;
|
2008-09-21 21:52:28 -04:00
|
|
|
}
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks++;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2016-03-31 17:51:39 -04:00
|
|
|
// In artist debug mode, when without opponents, skip the
|
|
|
|
// ready/set/go counter faster
|
2017-01-03 16:18:41 -05:00
|
|
|
if (UserConfigParams::m_artist_debug_mode &&
|
|
|
|
!NetworkConfig::get()->isNetworking() &&
|
2020-02-27 20:42:44 -05:00
|
|
|
RaceManager::get()->getNumberOfKarts() -
|
|
|
|
RaceManager::get()->getNumSpareTireKarts() == 1 &&
|
|
|
|
RaceManager::get()->getTrackName() != "tutorial")
|
2014-08-30 12:34:44 -04:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks += 6;
|
2014-08-30 12:34:44 -04:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:51:39 -04:00
|
|
|
return; // Do not increase time
|
2014-08-30 12:34:44 -04:00
|
|
|
case SET_PHASE:
|
2018-02-23 07:22:49 -05:00
|
|
|
if (m_auxiliary_ticks > 2*stk_config->getPhysicsFPS())
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
|
|
|
// set phase is over, go to the next one
|
2014-08-30 12:34:44 -04:00
|
|
|
m_phase = GO_PHASE;
|
2016-05-02 05:32:04 -04:00
|
|
|
if (m_play_ready_set_go_sounds)
|
2014-08-30 12:34:44 -04:00
|
|
|
{
|
|
|
|
m_start_sound->play();
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2008-10-04 13:32:40 -04:00
|
|
|
// event
|
|
|
|
onGo();
|
2019-01-04 01:54:00 -05:00
|
|
|
// In artist debug mode, when without opponents,
|
|
|
|
// skip the ready/set/go counter faster
|
|
|
|
m_start_music_ticks =
|
|
|
|
UserConfigParams::m_artist_debug_mode &&
|
|
|
|
!NetworkConfig::get()->isNetworking() &&
|
2020-02-27 20:42:44 -05:00
|
|
|
RaceManager::get()->getNumberOfKarts() -
|
|
|
|
RaceManager::get()->getNumSpareTireKarts() == 1 &&
|
|
|
|
RaceManager::get()->getTrackName() != "tutorial" ?
|
2019-01-04 01:54:00 -05:00
|
|
|
stk_config->time2Ticks(0.2f) :
|
|
|
|
stk_config->time2Ticks(1.0f);
|
2008-09-21 21:52:28 -04:00
|
|
|
}
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks++;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2016-03-31 17:51:39 -04:00
|
|
|
// In artist debug mode, when without opponents,
|
|
|
|
// skip the ready/set/go counter faster
|
2013-01-16 21:20:12 -05:00
|
|
|
if (UserConfigParams::m_artist_debug_mode &&
|
2018-03-07 17:47:42 -05:00
|
|
|
!NetworkConfig::get()->isNetworking() &&
|
2020-02-27 20:42:44 -05:00
|
|
|
RaceManager::get()->getNumberOfKarts() -
|
|
|
|
RaceManager::get()->getNumSpareTireKarts() == 1 &&
|
|
|
|
RaceManager::get()->getTrackName() != "tutorial")
|
2014-08-30 12:34:44 -04:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks += 6;
|
2014-08-30 12:34:44 -04:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:51:39 -04:00
|
|
|
return; // Do not increase time
|
2019-01-04 01:54:00 -05:00
|
|
|
case GO_PHASE:
|
|
|
|
{
|
|
|
|
if (m_start_music_ticks != -1 &&
|
|
|
|
m_count_up_ticks >= m_start_music_ticks)
|
2011-09-13 20:48:49 -04:00
|
|
|
{
|
2019-01-04 01:54:00 -05:00
|
|
|
m_start_music_ticks = -1;
|
|
|
|
if (music_manager->getCurrentMusic() &&
|
|
|
|
!music_manager->getCurrentMusic()->isPlaying())
|
|
|
|
{
|
|
|
|
music_manager->startMusic();
|
|
|
|
}
|
2019-04-12 13:14:42 -04:00
|
|
|
// no graphics mode goes race phase now
|
2020-02-15 01:00:48 -05:00
|
|
|
if (GUIEngine::isNoGraphics())
|
2019-04-12 13:14:42 -04:00
|
|
|
{
|
|
|
|
m_race_ticks = -1;
|
|
|
|
m_phase = RACE_PHASE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_phase = MUSIC_PHASE;
|
2011-09-13 20:48:49 -04:00
|
|
|
}
|
2016-03-31 17:51:39 -04:00
|
|
|
break; // Now the world time starts
|
2019-01-04 01:54:00 -05:00
|
|
|
}
|
2008-10-04 14:50:45 -04:00
|
|
|
case MUSIC_PHASE:
|
2019-01-04 01:54:00 -05:00
|
|
|
{
|
2015-02-08 19:15:48 -05:00
|
|
|
// Start the music here when starting fast
|
|
|
|
if (UserConfigParams::m_race_now)
|
|
|
|
{
|
2015-02-10 01:07:46 -05:00
|
|
|
music_manager->startMusic();
|
2015-02-08 19:15:48 -05:00
|
|
|
UserConfigParams::m_race_now = false;
|
|
|
|
}
|
2019-01-04 01:54:00 -05:00
|
|
|
if (m_race_ticks != -1 && m_count_up_ticks >= m_race_ticks)
|
2014-08-30 12:34:44 -04:00
|
|
|
{
|
2019-01-04 01:54:00 -05:00
|
|
|
m_race_ticks = -1;
|
2014-08-30 12:34:44 -04:00
|
|
|
m_phase = RACE_PHASE;
|
|
|
|
}
|
2008-09-21 21:52:28 -04:00
|
|
|
break;
|
2019-01-04 01:54:00 -05:00
|
|
|
}
|
2010-05-10 19:53:32 -04:00
|
|
|
case RACE_PHASE:
|
|
|
|
// Nothing to do for race phase, switch to delay finish phase
|
2013-05-29 18:04:35 -04:00
|
|
|
// happens when
|
2010-05-10 19:53:32 -04:00
|
|
|
break;
|
2014-08-30 12:34:44 -04:00
|
|
|
case DELAY_FINISH_PHASE:
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_auxiliary_ticks++;
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-05-10 19:53:32 -04:00
|
|
|
// Change to next phase if delay is over
|
2018-02-23 07:22:49 -05:00
|
|
|
if (m_auxiliary_ticks >
|
|
|
|
stk_config->time2Ticks(stk_config->m_delay_finish_time))
|
2010-05-10 19:53:32 -04:00
|
|
|
{
|
2010-06-07 17:40:45 -04:00
|
|
|
m_phase = RESULT_DISPLAY_PHASE;
|
|
|
|
terminateRace();
|
2010-05-10 19:53:32 -04:00
|
|
|
}
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2010-05-10 19:53:32 -04:00
|
|
|
break;
|
2008-09-21 21:52:28 -04:00
|
|
|
}
|
2014-08-30 12:34:44 -04:00
|
|
|
case RESULT_DISPLAY_PHASE:
|
2013-02-03 17:31:24 -05:00
|
|
|
{
|
2010-05-10 19:53:32 -04:00
|
|
|
break;
|
2013-02-03 17:31:24 -05:00
|
|
|
}
|
2008-09-21 21:52:28 -04:00
|
|
|
case FINISH_PHASE:
|
2018-04-02 22:06:42 -04:00
|
|
|
case IN_GAME_MENU_PHASE:
|
2010-05-10 19:53:32 -04:00
|
|
|
// Nothing to do here.
|
|
|
|
break;
|
|
|
|
default: break;
|
2008-09-21 21:52:28 -04:00
|
|
|
}
|
2016-03-31 22:10:38 -04:00
|
|
|
|
2016-10-15 20:28:48 -04:00
|
|
|
IrrlichtDevice *device = irr_driver->getDevice();
|
2017-06-04 19:46:34 -04:00
|
|
|
|
2014-08-30 12:34:44 -04:00
|
|
|
switch (m_clock_mode)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2010-02-09 04:24:45 -05:00
|
|
|
case CLOCK_CHRONO:
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_CHILD || !device->getTimer()->isStopped())
|
2016-10-15 20:28:48 -04:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_time_ticks++;
|
2018-02-23 07:22:49 -05:00
|
|
|
m_time = stk_config->ticks2Time(m_time_ticks);
|
2018-02-21 06:18:45 -05:00
|
|
|
m_count_up_ticks++;
|
2016-10-15 20:28:48 -04:00
|
|
|
}
|
2008-09-21 21:52:28 -04:00
|
|
|
break;
|
2010-02-09 04:24:45 -05:00
|
|
|
case CLOCK_COUNTDOWN:
|
2010-02-26 14:09:05 -05:00
|
|
|
// stop countdown when race is over
|
2010-05-10 19:53:32 -04:00
|
|
|
if (m_phase == RESULT_DISPLAY_PHASE || m_phase == FINISH_PHASE)
|
2010-02-26 14:09:05 -05:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_time_ticks = 0;
|
2010-02-26 14:09:05 -05:00
|
|
|
m_time = 0.0f;
|
2019-11-23 23:14:29 -05:00
|
|
|
// For rescue animation playing (if any) in result screen
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_CHILD || !device->getTimer()->isStopped())
|
2019-11-23 23:14:29 -05:00
|
|
|
m_count_up_ticks++;
|
2010-02-26 14:09:05 -05:00
|
|
|
break;
|
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2020-02-27 20:43:25 -05:00
|
|
|
if (m_process_type == PT_CHILD || !device->getTimer()->isStopped())
|
2016-10-15 20:28:48 -04:00
|
|
|
{
|
2018-02-21 06:18:45 -05:00
|
|
|
m_time_ticks--;
|
2018-02-23 07:22:49 -05:00
|
|
|
m_time = stk_config->ticks2Time(m_time_ticks);
|
2018-02-21 06:18:45 -05:00
|
|
|
m_count_up_ticks++;
|
2016-10-15 20:28:48 -04:00
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2018-07-18 13:17:52 -04:00
|
|
|
if (m_time_ticks <= 0)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2008-10-04 13:32:40 -04:00
|
|
|
// event
|
|
|
|
countdownReachedZero();
|
2008-09-21 21:52:28 -04:00
|
|
|
}
|
2013-05-29 18:04:35 -04:00
|
|
|
|
2010-02-26 14:09:05 -05:00
|
|
|
break;
|
2008-09-21 21:52:28 -04:00
|
|
|
default: break;
|
2016-03-31 17:51:39 -04:00
|
|
|
} // switch m_phase
|
2019-01-04 01:54:00 -05:00
|
|
|
|
2010-02-09 04:24:45 -05:00
|
|
|
} // update
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-02-09 04:24:45 -05:00
|
|
|
/** Sets the time for the clock.
|
|
|
|
* \param time New time to set.
|
|
|
|
*/
|
2010-02-08 07:59:03 -05:00
|
|
|
void WorldStatus::setTime(const float time)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2018-03-13 03:37:12 -04:00
|
|
|
int new_time_ticks = stk_config->time2Ticks(time);
|
|
|
|
m_time_ticks = new_time_ticks;
|
|
|
|
m_time = stk_config->ticks2Time(new_time_ticks);
|
2010-02-09 04:24:45 -05:00
|
|
|
} // setTime
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2018-03-13 03:37:12 -04:00
|
|
|
/** Sets a new time for the world time, measured in ticks.
|
|
|
|
* \param ticks New time in ticks to set.
|
|
|
|
*/
|
|
|
|
void WorldStatus::setTicks(int ticks)
|
|
|
|
{
|
|
|
|
m_time_ticks = ticks;
|
|
|
|
m_time = stk_config->ticks2Time(ticks);
|
|
|
|
} // setTicks
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2018-07-13 11:34:50 -04:00
|
|
|
/** Sets a new time for the world time (used by rewind), measured in ticks.
|
|
|
|
* \param ticks New time in ticks to set (always count upwards).
|
|
|
|
*/
|
|
|
|
void WorldStatus::setTicksForRewind(int ticks)
|
|
|
|
{
|
|
|
|
m_count_up_ticks = ticks;
|
2020-02-27 20:42:44 -05:00
|
|
|
if (RaceManager::get()->hasTimeTarget())
|
2018-07-13 11:34:50 -04:00
|
|
|
{
|
2020-02-27 20:42:44 -05:00
|
|
|
m_time_ticks = stk_config->time2Ticks(RaceManager::get()->getTimeTarget()) -
|
2018-07-13 11:34:50 -04:00
|
|
|
m_count_up_ticks;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_time_ticks = ticks;
|
|
|
|
m_time = stk_config->ticks2Time(m_time_ticks);
|
|
|
|
} // setTicksForRewind
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2010-05-10 19:53:32 -04:00
|
|
|
/** Pauses the game and switches to the specified phase.
|
|
|
|
* \param phase Phase to switch to.
|
|
|
|
*/
|
|
|
|
void WorldStatus::pause(Phase phase)
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2014-08-30 12:34:44 -04:00
|
|
|
assert(m_previous_phase == UNDEFINED_PHASE);
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
m_previous_phase = m_phase;
|
2010-05-10 19:53:32 -04:00
|
|
|
m_phase = phase;
|
2020-02-27 20:43:25 -05:00
|
|
|
|
|
|
|
if (m_process_type != PT_MAIN)
|
|
|
|
return;
|
|
|
|
|
2011-09-05 00:14:50 -04:00
|
|
|
IrrlichtDevice *device = irr_driver->getDevice();
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2018-02-17 02:21:26 -05:00
|
|
|
if (!device->getTimer()->isStopped() &&
|
|
|
|
!NetworkConfig::get()->isNetworking())
|
2014-08-30 12:34:44 -04:00
|
|
|
device->getTimer()->stop();
|
2010-02-09 04:24:45 -05:00
|
|
|
} // pause
|
|
|
|
|
2008-09-21 21:52:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-05-10 19:53:32 -04:00
|
|
|
/** Switches back from a pause state to the previous state.
|
|
|
|
*/
|
2010-02-08 07:59:03 -05:00
|
|
|
void WorldStatus::unpause()
|
2008-09-21 21:52:28 -04:00
|
|
|
{
|
2010-05-10 19:53:32 -04:00
|
|
|
m_phase = m_previous_phase;
|
|
|
|
// Set m_previous_phase so that we can use an assert
|
|
|
|
// in pause to detect incorrect pause/unpause sequences.
|
2010-06-06 23:31:41 -04:00
|
|
|
m_previous_phase = UNDEFINED_PHASE;
|
2020-02-27 20:43:25 -05:00
|
|
|
|
|
|
|
if (m_process_type != PT_MAIN)
|
|
|
|
return;
|
|
|
|
|
2011-09-05 00:14:50 -04:00
|
|
|
IrrlichtDevice *device = irr_driver->getDevice();
|
2014-08-30 12:34:44 -04:00
|
|
|
|
2018-02-17 02:21:26 -05:00
|
|
|
if (device->getTimer()->isStopped() &&
|
|
|
|
!NetworkConfig::get()->isNetworking())
|
2014-08-30 12:34:44 -04:00
|
|
|
device->getTimer()->start();
|
2010-06-06 23:31:41 -04:00
|
|
|
} // unpause
|
2018-12-31 12:01:49 -05:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2019-01-01 12:50:47 -05:00
|
|
|
/** Base on the network timer set current world count up ticks to tick_now.
|
|
|
|
*/
|
2018-12-31 12:01:49 -05:00
|
|
|
void WorldStatus::endLiveJoinWorld(int ticks_now)
|
|
|
|
{
|
2019-01-04 01:54:00 -05:00
|
|
|
m_live_join_ticks = ticks_now;
|
2018-12-31 12:01:49 -05:00
|
|
|
m_live_join_world = false;
|
|
|
|
m_auxiliary_ticks = 0;
|
2019-01-04 01:54:00 -05:00
|
|
|
m_phase = MUSIC_PHASE;
|
|
|
|
m_race_ticks = m_live_join_ticks + stk_config->time2Ticks(
|
|
|
|
stk_config->m_music_credit_time);
|
2019-01-01 12:50:47 -05:00
|
|
|
onGo();
|
2019-01-01 02:46:45 -05:00
|
|
|
startEngines();
|
|
|
|
music_manager->startMusic();
|
2019-01-04 01:54:00 -05:00
|
|
|
setTicksForRewind(m_live_join_ticks);
|
2018-12-31 12:01:49 -05:00
|
|
|
} // endLiveJoinWorld
|