Removed LIMBO state, added new RESULT_DISPLAY_PHASE (but at this stage no

visible change to user).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5424 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-05-10 23:53:32 +00:00
parent 1d5fe00af8
commit 0a59455a82
10 changed files with 127 additions and 72 deletions

View File

@ -30,7 +30,6 @@
#include "modes/profile_world.hpp"
#include "modes/world.hpp"
#include "network/network_manager.hpp"
#include "race/history.hpp"
#include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp"
@ -109,11 +108,7 @@ void MainLoop::updateRace(float dt)
if(!World::getWorld()->isFinishPhase())
network_manager->receiveUpdates();
if ( World::getWorld()->getPhase() != WorldStatus::LIMBO_PHASE)
{
history->update(dt);
World::getWorld()->updateWorld(dt);
} // phase != limbo phase
World::getWorld()->updateWorld(dt);
} // updateRace
//-----------------------------------------------------------------------------
@ -122,7 +117,7 @@ void MainLoop::updateRace(float dt)
void MainLoop::run()
{
IrrlichtDevice* device = irr_driver->getDevice();
bool music_on = false;
m_curr_time = device->getTimer()->getRealTime();
while(!m_abort)

View File

@ -291,7 +291,6 @@ void World::terminateRace()
}
} // i<kart_amount
updateHighscores();
WorldStatus::pause();
unlock_manager->raceFinished();
RaceGUI* m = World::getWorld()->getRaceGUI();
@ -389,6 +388,11 @@ void World::resetAllKarts()
*/
void World::updateWorld(float dt)
{
// Don't update world if a menu is shown or the race is over.
if( m_phase == FINISH_PHASE ||
m_phase == RESULT_DISPLAY_PHASE ||
m_phase == IN_GAME_MENU_PHASE ) return;
update(dt);
if( (!isFinishPhase()) && isRaceOver())
{
@ -415,6 +419,7 @@ void World::update(float dt)
}
#endif
history->update(dt);
if(history->replayHistory()) dt=history->getNextDelta();
WorldStatus::update(dt);
// Clear race state so that new information can be stored
@ -650,11 +655,13 @@ void World::restartRace()
} // restartRace
//-----------------------------------------------------------------------------
void World::pause()
/** Pauses the music (and then pauses WorldStatus).
*/
void World::pause(Phase phase)
{
music_manager->pauseMusic();
sfx_manager->pauseAll();
WorldStatus::pause();
WorldStatus::pause(phase);
} // pause
//-----------------------------------------------------------------------------

View File

@ -208,8 +208,8 @@ public:
virtual bool useFastMusicNearEnd() const { return true; }
void pause();
void unpause();
virtual void pause(Phase phase);
virtual void unpause();
/**
* The code that draws the timer should call this first to know

View File

@ -20,6 +20,7 @@
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "config/stk_config.hpp"
#include "guiengine/modaldialog.hpp"
#include "network/network_manager.hpp"
#include "states_screens/dialogs/race_over_dialog.hpp"
@ -78,8 +79,8 @@ void WorldStatus::enterRaceOverState()
{
// Don't
if( m_phase == DELAY_FINISH_PHASE
|| m_phase == FINISH_PHASE
|| m_phase == LIMBO_PHASE ) return;
|| m_phase == RESULT_DISPLAY_PHASE
|| m_phase == FINISH_PHASE ) return;
m_phase = DELAY_FINISH_PHASE;
m_auxiliary_timer = 0.0f;
@ -92,6 +93,7 @@ void WorldStatus::enterRaceOverState()
*/
void WorldStatus::terminateRace()
{
pause(RESULT_DISPLAY_PHASE);
if(network_manager->getMode()==NetworkManager::NW_SERVER)
network_manager->sendRaceResults();
} // terminateRace
@ -146,21 +148,33 @@ void WorldStatus::update(const float dt)
m_phase=RACE_PHASE;
m_auxiliary_timer += dt;
break;
case RACE_PHASE:
// Nothing to do for race phase, switch to delay finish phase
// happens when
break;
case DELAY_FINISH_PHASE :
{
m_auxiliary_timer += dt;
// Nothing more to do if delay time is not over yet
if(m_auxiliary_timer < stk_config->m_delay_finish_time) break;
m_phase = FINISH_PHASE;
// NOTE: no break, fall through to FINISH_PHASE handling!!
// Change to next phase if delay is over
if(m_auxiliary_timer > stk_config->m_delay_finish_time)
{
m_phase = RESULT_DISPLAY_PHASE;
new RaceOverDialog(0.6f, 0.9f);
}
break;
}
case RESULT_DISPLAY_PHASE :
if(((RaceOverDialog*)GUIEngine::ModalDialog::getCurrent())->menuIsFinished())
{
terminateRace();
m_phase = FINISH_PHASE;
}
break;
case FINISH_PHASE:
terminateRace();
new RaceOverDialog(0.6f, 0.9f);
return;
default: break; // default for RACE_PHASE, LIMBO_PHASE
// Nothing to do here.
break;
default: break;
}
switch(m_clock_mode)
@ -170,7 +184,7 @@ void WorldStatus::update(const float dt)
break;
case CLOCK_COUNTDOWN:
// stop countdown when race is over
if (m_phase == DELAY_FINISH_PHASE || m_phase == FINISH_PHASE || m_phase == LIMBO_PHASE)
if (m_phase == RESULT_DISPLAY_PHASE || m_phase == FINISH_PHASE)
{
m_time = 0.0f;
break;
@ -199,15 +213,23 @@ void WorldStatus::setTime(const float time)
} // setTime
//-----------------------------------------------------------------------------
void WorldStatus::pause()
/** Pauses the game and switches to the specified phase.
* \param phase Phase to switch to.
*/
void WorldStatus::pause(Phase phase)
{
assert(m_previous_phase==SETUP_PHASE);
m_previous_phase = m_phase;
m_phase = LIMBO_PHASE;
m_phase = phase;
} // pause
//-----------------------------------------------------------------------------
/** Switches back from a pause state to the previous state.
*/
void WorldStatus::unpause()
{
m_phase = m_previous_phase;
m_phase = m_previous_phase;
// Set m_previous_phase so that we can use an assert
// in pause to detect incorrect pause/unpause sequences.
m_previous_phase = SETUP_PHASE;
}

View File

@ -39,26 +39,38 @@ public:
enum Phase {
// Game setup, e.g. track loading
SETUP_PHASE,
// 'Ready' is displayed
READY_PHASE,
// 'Set' is displayed
SET_PHASE,
// 'Go' is displayed, but this is already race phase
GO_PHASE,
// Race is started, 'go' is gone, but music name is still there
MUSIC_PHASE,
// the actual race has started, no ready/set/go is displayed anymore
RACE_PHASE,
// All players have finished, now wait a certain amount of time for AI
// karts to finish. If they do not finish in that time, finish the race
// and estimate their arrival time.
DELAY_FINISH_PHASE,
// Display the results, while world is still being updated to
// show the end animation
RESULT_DISPLAY_PHASE,
// The player crossed the finishing line and his and the time of
// the other players is displayed, controll is automatic
FINISH_PHASE,
// Phase while playing the end (win/lose) animation.
END_ANIMATION_PHASE,
// The state after finish where no calculations are done.
LIMBO_PHASE,
// Display the in-game menu, but no update of world or anything
IN_GAME_MENU_PHASE,
};
protected:
SFXBase *m_prestart_sound;
@ -76,48 +88,53 @@ protected:
* Remember previous phase e.g. on pause
*/
Phase m_previous_phase;
public:
WorldStatus();
virtual ~WorldStatus();
void reset();
// Note: GO_PHASE is both: start phase and race phase
bool isStartPhase() const { return m_phase<GO_PHASE; }
bool isRacePhase() const { return m_phase>=GO_PHASE &&
m_phase<FINISH_PHASE; }
/** While the race menu is being displayed, m_phase is limbo, and
* m_previous_phase is finish. So we have to test this case, too. */
bool isFinishPhase() const { return m_phase==FINISH_PHASE ||
(m_phase==LIMBO_PHASE &&
m_previous_phase==FINISH_PHASE);}
const Phase getPhase() const { return m_phase; }
/**
* Counts time during the initial 'ready/set/go' phase, or at the end of a race.
* This timer basically kicks in when we need to calculate non-race time like labels.
*/
float m_auxiliary_timer;
public:
WorldStatus();
virtual ~WorldStatus();
/**
* Call to specify what kind of clock you want. The second argument
* can be used to specify the initial time value (especially useful
* for countdowns)
*/
void reset();
// Note: GO_PHASE is both: start phase and race phase
bool isStartPhase() const { return m_phase<GO_PHASE; }
bool isRacePhase() const { return m_phase>=GO_PHASE &&
m_phase<FINISH_PHASE; }
/** While the race menu is being displayed, m_phase is limbo, and
* m_previous_phase is finish. So we have to test this case, too. */
bool isFinishPhase() const { return m_phase==FINISH_PHASE ||
(m_phase==IN_GAME_MENU_PHASE &&
m_previous_phase==FINISH_PHASE);}
const Phase getPhase() const { return m_phase; }
/** Call to specify what kind of clock you want. The second argument
* can be used to specify the initial time value (especially useful
* for countdowns). */
void setClockMode(const ClockType mode, const float initial_time=0.0f);
/** Returns the current clock mode. */
int getClockMode() const { return m_clock_mode; }
/** Returns the current race time. */
float getTime() const { return m_time; }
/** Returns the value of the auxiliary timer. */
float getAuxiliaryTimer() const {return m_auxiliary_timer; }
/**
* Call each frame, with the elapsed time as argument.
*/
void update(const float dt);
float getTime() const { return m_time; }
void setTime(const float time);
void pause();
void unpause();
virtual void pause(Phase phase);
virtual void unpause();
virtual void enterRaceOverState();
virtual void terminateRace();
/*

View File

@ -31,8 +31,6 @@
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/race_setup_screen.hpp"
#include "states_screens/state_manager.hpp"
//#include "tracks/track_manager.hpp"
//#include "tracks/track.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@ -81,6 +79,7 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
const float percentHeight)
: ModalDialog(percentWidth, percentHeight)
{
m_auxiliary_timer = 0;
// Switch to barrier mode: server waits for ack from each client
network_manager->beginRaceResultBarrier();
@ -437,13 +436,13 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
assert(false);
}
}
} // RaceOverDialog
// ------------------------------------------------------------------------------------------------------
void RaceOverDialog::onEnterPressedInternal()
{
}
} // onEnterPressedInternal
// ------------------------------------------------------------------------------------------------------
@ -513,7 +512,7 @@ GUIEngine::EventPropagation RaceOverDialog::processEvent(const std::string& even
}
return GUIEngine::EVENT_LET;
}
} // processEvent
//-----------------------------------------------------------------------------
@ -538,12 +537,14 @@ void RaceOverDialog::escapePressed()
{
assert(false);
}
}
} // escapePressed
//-----------------------------------------------------------------------------
void RaceOverDialog::onUpdate(float dt)
{
m_auxiliary_timer +=dt;
// Draw battle report (if relevant)
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES)
{
@ -695,4 +696,13 @@ void RaceOverDialog::renderThreeStrikesGraph(const int x, const int y, const int
GUIEngine::getSmallFont()->draw( _("Energy"), pos, video::SColor(255,0,0,0),
false /* hcenter */, true /* vcenter */ );
}
}
} // renderThreeStrikesGraph
// ----------------------------------------------------------------------------
/** Called by WorldStatus to see when the race results have been completely
* displayed, which means that the next phase can start.
*/
bool RaceOverDialog::menuIsFinished()
{
return m_auxiliary_timer>stk_config->m_delay_finish_time;
} // menuIsFinished

View File

@ -29,7 +29,9 @@ class RaceOverDialog : public GUIEngine::ModalDialog
int m_buttons_y_from;
int m_rankings_y_bottom;
/** A timer to make this display shown for a certain amount of time. */
float m_auxiliary_timer;
public:
/**
* Creates a modal dialog with given percentage of screen width and height
@ -42,6 +44,7 @@ public:
virtual void escapePressed();
virtual void onUpdate(float dt);
bool menuIsFinished();
};

View File

@ -41,7 +41,7 @@ using namespace irr::gui;
RacePausedDialog::RacePausedDialog(const float percentWidth, const float percentHeight) :
ModalDialog(percentWidth, percentHeight)
{
World::getWorld()->pause();
World::getWorld()->pause(WorldStatus::IN_GAME_MENU_PHASE);
IGUIFont* font = GUIEngine::getTitleFont();
const int text_height = GUIEngine::getFontHeight();

View File

@ -760,14 +760,14 @@ void RaceGUI::drawGlobalMusicDescription()
gui::IGUIFont* font = GUIEngine::getFont();
World *world = World::getWorld();
float race_time = World::getWorld()->getTime();
// ---- Manage pulsing effect
// 3.0 is the duration of ready/set (TODO: don't hardcode)
float timeProgression = (float)(world->m_auxiliary_timer - 2.0f) /
float timeProgression = (float)(race_time) /
(float)(stk_config->m_music_credit_time - 2.0f);
const int x_pulse = (int)(sin(world->m_auxiliary_timer*9.0f)*10.0f);
const int y_pulse = (int)(cos(world->m_auxiliary_timer*9.0f)*10.0f);
const int x_pulse = (int)(sin(race_time*9.0f)*10.0f);
const int y_pulse = (int)(cos(race_time*9.0f)*10.0f);
float resize = 1.0f;
if (timeProgression < 0.1)

View File

@ -203,7 +203,8 @@ void StateManager::onGameStateChange(GameState previousState, GameState newState
else if (newState == INGAME_MENU)
{
// pause game when an in-game menu is shown
if (World::getWorld() != NULL) World::getWorld()->pause();
if (World::getWorld() != NULL)
World::getWorld()->pause(WorldStatus::IN_GAME_MENU_PHASE);
}
}
}