Use ticks (at the physics frame rate) for time measurement, which
avoids potential floating point errors (in networking).
This commit is contained in:
parent
208c5eb6d8
commit
27b5409487
@ -179,6 +179,7 @@ public:
|
||||
void load (const std::string &filename);
|
||||
const std::string &getMainMenuPicture(int n);
|
||||
const std::string &getBackgroundPicture(int n);
|
||||
|
||||
void getAllScores(std::vector<int> *all_scores, int num_karts);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the default kart properties for each kart. */
|
||||
|
@ -167,8 +167,8 @@ void Camera::setupCamera()
|
||||
m_aspect = (float)((float)(m_viewport.getWidth()) / (float)(m_viewport.getHeight()));
|
||||
|
||||
m_scaling = core::vector2df(
|
||||
irr_driver->getActualScreenSize().Width / m_viewport.getWidth() ,
|
||||
irr_driver->getActualScreenSize().Height / m_viewport.getHeight());
|
||||
float(irr_driver->getActualScreenSize().Width) / m_viewport.getWidth() ,
|
||||
float(irr_driver->getActualScreenSize().Height) / m_viewport.getHeight());
|
||||
|
||||
m_fov = DEGREE_TO_RAD * stk_config->m_camera_fov
|
||||
[race_manager->getNumLocalPlayers() > 0 ?
|
||||
|
@ -464,7 +464,7 @@ void Powerup::hitBonusBox(const Item &item, int add_info)
|
||||
// Check if rubber ball is the current power up held by the kart. If so,
|
||||
// reset the bBallCollectTime to 0 before giving new powerup.
|
||||
if(m_type == PowerupManager::POWERUP_RUBBERBALL)
|
||||
powerup_manager->setBallCollectTime(0);
|
||||
powerup_manager->setBallCollectTicks(0);
|
||||
|
||||
// Check if two bouncing balls are collected less than getRubberBallTimer()
|
||||
//seconds apart. If yes, then call getRandomPowerup again. If no, then break.
|
||||
@ -474,8 +474,8 @@ void Powerup::hitBonusBox(const Item &item, int add_info)
|
||||
{
|
||||
new_powerup = powerup_manager->getRandomPowerup(position, &n);
|
||||
if(new_powerup != PowerupManager::POWERUP_RUBBERBALL ||
|
||||
( World::getWorld()->getTimeSinceStart() - powerup_manager->getBallCollectTime()) >
|
||||
RubberBall::getTimeBetweenRubberBalls() )
|
||||
( World::getWorld()->getTicksSinceStart() - powerup_manager->getBallCollectTicks()) >
|
||||
RubberBall::getTicksBetweenRubberBalls() )
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -486,7 +486,7 @@ void Powerup::hitBonusBox(const Item &item, int add_info)
|
||||
}
|
||||
|
||||
if(new_powerup == PowerupManager::POWERUP_RUBBERBALL)
|
||||
powerup_manager->setBallCollectTime(World::getWorld()->getTime());
|
||||
powerup_manager->setBallCollectTicks(World::getWorld()->getTimeTicks());
|
||||
|
||||
// Always add a new powerup in ITEM_MODE_NEW (or if the kart
|
||||
// doesn't have a powerup atm).
|
||||
|
@ -113,7 +113,7 @@ private:
|
||||
float m_all_max_turn_angle[POWERUP_MAX];
|
||||
|
||||
/** Last time the bouncing ball was collected */
|
||||
float m_rubber_ball_collect_time;
|
||||
int m_rubber_ball_collect_ticks;
|
||||
|
||||
public:
|
||||
/** The mesh for each model (if the powerup has a model), e.g. a switch
|
||||
@ -165,8 +165,8 @@ public:
|
||||
float getMaxTurnAngle (int type) const {return m_all_max_turn_angle[type];}
|
||||
const btVector3&
|
||||
getExtend (int type) const {return m_all_extends[type];}
|
||||
float getBallCollectTime() const {return m_rubber_ball_collect_time;}
|
||||
void setBallCollectTime(float time) {m_rubber_ball_collect_time=time;}
|
||||
int getBallCollectTicks() const {return m_rubber_ball_collect_ticks;}
|
||||
void setBallCollectTicks(int ticks) {m_rubber_ball_collect_ticks=ticks;}
|
||||
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ float RubberBall::m_st_max_height_difference;
|
||||
float RubberBall::m_st_fast_ping_distance;
|
||||
float RubberBall::m_st_early_target_factor;
|
||||
int RubberBall::m_next_id = 0;
|
||||
float RubberBall::m_time_between_balls;
|
||||
float RubberBall::m_ticks_between_balls;
|
||||
|
||||
|
||||
// Debug only, so that we can get a feel on how well balls are aiming etc.
|
||||
@ -272,7 +272,7 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
||||
m_st_max_height_difference = 10.0f;
|
||||
m_st_fast_ping_distance = 50.0f;
|
||||
m_st_early_target_factor = 1.0f;
|
||||
m_time_between_balls = 15;
|
||||
m_ticks_between_balls = 15 * stk_config->m_physics_fps;
|
||||
|
||||
if(!node.get("interval", &m_st_interval))
|
||||
Log::warn("powerup", "No interval specified for rubber ball.");
|
||||
@ -306,9 +306,10 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *rubberball)
|
||||
if(!node.get("early-target-factor", &m_st_early_target_factor))
|
||||
Log::warn("powerup",
|
||||
"No early-target-factor specified for rubber ball.");
|
||||
if(!node.get("time-between-balls", &m_time_between_balls))
|
||||
if(!node.get("time-between-balls", &m_ticks_between_balls))
|
||||
Log::warn("powerup",
|
||||
"No time-between-balls specified for rubber ball.");
|
||||
m_ticks_between_balls *= stk_config->m_physics_fps;
|
||||
Flyable::init(node, rubberball, PowerupManager::POWERUP_RUBBERBALL);
|
||||
} // init
|
||||
|
||||
|
@ -84,7 +84,7 @@ private:
|
||||
/** Timer before another rubber ball can be picked up. This is to ensure
|
||||
* that there are not too many rubber balls on the track in races with many
|
||||
* karts. */
|
||||
static float m_time_between_balls;
|
||||
static float m_ticks_between_balls;
|
||||
|
||||
/** This factor is used to influence how much the rubber ball should aim
|
||||
* at its target early. It used the 'distance to center of track' of its
|
||||
@ -205,7 +205,7 @@ public:
|
||||
virtual bool updateAndDelete(float dt);
|
||||
virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL);
|
||||
virtual void setAnimation(AbstractKartAnimation *animation);
|
||||
static float getTimeBetweenRubberBalls() {return m_time_between_balls;}
|
||||
static float getTicksBetweenRubberBalls() {return m_ticks_between_balls;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** This object does not create an explosion, all affects on
|
||||
* karts are handled by this hit() function. */
|
||||
|
@ -48,7 +48,7 @@ AIBaseController::AIBaseController(AbstractKart *kart)
|
||||
void AIBaseController::reset()
|
||||
{
|
||||
m_stuck = false;
|
||||
m_collision_times.clear();
|
||||
m_collision_ticks.clear();
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -237,12 +237,12 @@ void AIBaseController::crashed(const Material *m)
|
||||
// the track again if it is stuck (i.e. time for the push back plus
|
||||
// time for the AI to accelerate and hit the terrain again).
|
||||
const unsigned int NUM_COLLISION = 3;
|
||||
const float COLLISION_TIME = 1.5f;
|
||||
const int COLLISION_TICKS = 3*stk_config->m_physics_fps/2;
|
||||
|
||||
float time = World::getWorld()->getTimeSinceStart();
|
||||
if(m_collision_times.size()==0)
|
||||
int ticks = World::getWorld()->getTicksSinceStart();
|
||||
if(m_collision_ticks.size()==0)
|
||||
{
|
||||
m_collision_times.push_back(time);
|
||||
m_collision_ticks.push_back(ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -252,23 +252,24 @@ void AIBaseController::crashed(const Material *m)
|
||||
// collisions to happen). The time of 0.2 seconds was experimentally
|
||||
// found, typically it takes 0.5 seconds for a kart to be pushed back
|
||||
// from the terrain and accelerate to hit the same terrain again.
|
||||
if(time - m_collision_times.back() < 0.2f)
|
||||
if(5 * (ticks - m_collision_ticks.back()) < stk_config->m_physics_fps)
|
||||
return;
|
||||
|
||||
// Remove all outdated entries, i.e. entries that are older than the
|
||||
// collision time plus 1 second. Older entries must be deleted,
|
||||
// otherwise a collision that happened (say) 10 seconds ago could
|
||||
// contribute to a stuck condition.
|
||||
while(m_collision_times.size()>0 &&
|
||||
time - m_collision_times[0] > 1.0f+COLLISION_TIME)
|
||||
m_collision_times.erase(m_collision_times.begin());
|
||||
while(m_collision_ticks.size()>0 &&
|
||||
ticks - m_collision_ticks[0] > stk_config->m_physics_fps
|
||||
+COLLISION_TICKS )
|
||||
m_collision_ticks.erase(m_collision_ticks.begin());
|
||||
|
||||
m_collision_times.push_back(time);
|
||||
m_collision_ticks.push_back(ticks);
|
||||
|
||||
// Now detect if there are enough collision records in the
|
||||
// specified time interval.
|
||||
if(time - m_collision_times.front() > COLLISION_TIME
|
||||
&& m_collision_times.size()>=NUM_COLLISION)
|
||||
if(ticks - m_collision_ticks.front() > COLLISION_TICKS &&
|
||||
m_collision_ticks.size()>=NUM_COLLISION )
|
||||
{
|
||||
// We can't call m_kart->forceRescue here, since crased() is
|
||||
// called during physics processing, and forceRescue() removes the
|
||||
|
@ -35,7 +35,7 @@ private:
|
||||
/** Stores the last N times when a collision happened. This is used
|
||||
* to detect when the AI is stuck, i.e. N collisions happened in
|
||||
* a certain period of time. */
|
||||
std::vector<float> m_collision_times;
|
||||
std::vector<int> m_collision_ticks;
|
||||
|
||||
/** A flag that is set during the physics processing to indicate that
|
||||
* this kart is stuck and needs to be rescued. */
|
||||
|
@ -358,7 +358,7 @@ void Kart::reset()
|
||||
m_has_started = false;
|
||||
m_bounce_back_time = 0.0f;
|
||||
m_brake_time = 0.0f;
|
||||
m_time_last_crash = 0.0f;
|
||||
m_ticks_last_crash = 0;
|
||||
m_speed = 0.0f;
|
||||
m_smoothed_speed = 0.0f;
|
||||
m_current_lean = 0.0f;
|
||||
@ -1052,7 +1052,8 @@ void Kart::collectedItem(Item *item, int add_info)
|
||||
*/
|
||||
float Kart::getStartupBoost() const
|
||||
{
|
||||
float t = World::getWorld()->getTimeSinceStart();
|
||||
float t = float(World::getWorld()->getTicksSinceStart())
|
||||
/ stk_config->m_physics_fps;
|
||||
std::vector<float> startup_times = m_kart_properties->getStartupTime();
|
||||
for (unsigned int i = 0; i < startup_times.size(); i++)
|
||||
{
|
||||
@ -2175,9 +2176,10 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
|
||||
*/
|
||||
void Kart::playCrashSFX(const Material* m, AbstractKart *k)
|
||||
{
|
||||
if(World::getWorld()->getTimeSinceStart()-m_time_last_crash < 0.5f) return;
|
||||
int ticks_since_start = World::getWorld()->getTicksSinceStart();
|
||||
if(ticks_since_start-m_ticks_last_crash < 0.5f) return;
|
||||
|
||||
m_time_last_crash = World::getWorld()->getTimeSinceStart();
|
||||
m_ticks_last_crash = ticks_since_start;
|
||||
// After a collision disable the engine for a short time so that karts
|
||||
// can 'bounce back' a bit (without this the engine force will prevent
|
||||
// karts from bouncing back, they will instead stuck towards the obstable).
|
||||
|
@ -223,7 +223,7 @@ protected:
|
||||
SFXBuffer *m_crash_sounds[CRASH_SOUND_COUNT];
|
||||
SFXBuffer *m_goo_sound;
|
||||
SFXBuffer *m_boing_sound;
|
||||
float m_time_last_crash;
|
||||
int m_ticks_last_crash;
|
||||
RaceManager::KartType m_type;
|
||||
|
||||
/** To prevent using nitro in too short bursts */
|
||||
|
@ -625,26 +625,24 @@ void ThreeStrikesBattle::addKartLife(unsigned int id)
|
||||
void ThreeStrikesBattle::spawnSpareTireKarts()
|
||||
{
|
||||
if (m_spare_tire_karts.empty() ||
|
||||
getTimeSinceStart() < m_next_sta_spawn_time)
|
||||
getTicksSinceStart() < m_next_sta_spawn_time)
|
||||
return;
|
||||
|
||||
const float period =
|
||||
race_manager->getDifficulty() == RaceManager::DIFFICULTY_BEST ? 40.0f :
|
||||
race_manager->getDifficulty() == RaceManager::DIFFICULTY_HARD ? 30.0f :
|
||||
race_manager->getDifficulty() == RaceManager::DIFFICULTY_MEDIUM ?
|
||||
25.0f : 20.0f;
|
||||
const float inc_factor =
|
||||
race_manager->getDifficulty() == RaceManager::DIFFICULTY_BEST ? 0.7f :
|
||||
race_manager->getDifficulty() == RaceManager::DIFFICULTY_HARD ? 0.65f :
|
||||
race_manager->getDifficulty() == RaceManager::DIFFICULTY_MEDIUM ?
|
||||
0.6f : 0.55f;
|
||||
|
||||
// Spawn spare tire kart when necessary
|
||||
// The lifespan for sta: inc_factor / period * 1000 / 2
|
||||
// So in easier mode the sta lasts longer than spawn period
|
||||
const float lifespan = inc_factor / period * 1000;
|
||||
m_next_sta_spawn_time = lifespan + (getTimeSinceStart() * inc_factor) +
|
||||
getTimeSinceStart();
|
||||
float inc_factor, lifespan;
|
||||
switch (race_manager->getDifficulty())
|
||||
{
|
||||
case RaceManager::DIFFICULTY_BEST: inc_factor = 0.7f; lifespan = 17.5f; break;
|
||||
case RaceManager::DIFFICULTY_HARD: inc_factor = 0.65f; lifespan = 21.66f; break;
|
||||
case RaceManager::DIFFICULTY_EASY: inc_factor = 0.6f; lifespan = 24.0f; break;
|
||||
default: inc_factor = 0.55f; lifespan = 27.5f; break;
|
||||
}
|
||||
|
||||
// Spawn spare tire kart when necessary
|
||||
m_next_sta_spawn_time = lifespan*stk_config->m_physics_fps
|
||||
+ getTicksSinceStart() * inc_factor
|
||||
+ getTicksSinceStart();
|
||||
int kart_has_few_lives = 0;
|
||||
for (unsigned int i = 0; i < m_kart_info.size(); i++)
|
||||
{
|
||||
|
@ -307,7 +307,7 @@ void World::reset()
|
||||
irr_driver->reset();
|
||||
|
||||
//Reset the Rubber Ball Collect Time to some negative value.
|
||||
powerup_manager->setBallCollectTime(-100);
|
||||
powerup_manager->setBallCollectTicks(-100);
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -61,8 +61,9 @@ WorldStatus::WorldStatus()
|
||||
void WorldStatus::reset()
|
||||
{
|
||||
m_time = 0.0f;
|
||||
m_auxiliary_timer = 0.0f;
|
||||
m_count_up_timer = 0.0f;
|
||||
m_time_ticks = 0;
|
||||
m_auxiliary_ticks = 0;
|
||||
m_count_up_ticks = 0;
|
||||
|
||||
m_engines_started = false;
|
||||
|
||||
@ -136,6 +137,7 @@ void WorldStatus::startEngines()
|
||||
void WorldStatus::setClockMode(const ClockType mode, const float initial_time)
|
||||
{
|
||||
m_clock_mode = mode;
|
||||
m_time_ticks = initial_time * stk_config->m_physics_fps;
|
||||
m_time = initial_time;
|
||||
} // setClockMode
|
||||
|
||||
@ -152,7 +154,7 @@ void WorldStatus::enterRaceOverState()
|
||||
return;
|
||||
|
||||
m_phase = DELAY_FINISH_PHASE;
|
||||
m_auxiliary_timer = 0.0f;
|
||||
m_auxiliary_ticks = 0;
|
||||
} // enterRaceOverState
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -188,7 +190,7 @@ void WorldStatus::updateTime(const float dt)
|
||||
// tilt way too much. A separate setup phase for the first frame
|
||||
// simplifies this handling
|
||||
case SETUP_PHASE:
|
||||
m_auxiliary_timer = 0.0f;
|
||||
m_auxiliary_ticks= 0;
|
||||
m_phase = TRACK_INTRO_PHASE;
|
||||
|
||||
if (m_play_track_intro_sound)
|
||||
@ -203,14 +205,14 @@ void WorldStatus::updateTime(const float dt)
|
||||
|
||||
return; // Do not increase time
|
||||
case TRACK_INTRO_PHASE:
|
||||
m_auxiliary_timer += dt;
|
||||
m_auxiliary_ticks++;
|
||||
|
||||
if (UserConfigParams::m_artist_debug_mode &&
|
||||
race_manager->getNumberOfKarts() -
|
||||
race_manager->getNumSpareTireKarts() == 1 &&
|
||||
race_manager->getTrackName() != "tutorial")
|
||||
{
|
||||
m_auxiliary_timer += dt * 6;
|
||||
m_auxiliary_ticks += 6;
|
||||
}
|
||||
|
||||
// Work around a bug that occurred on linux once:
|
||||
@ -220,21 +222,22 @@ void WorldStatus::updateTime(const float dt)
|
||||
// long, we use the aux timer to force the next phase
|
||||
// after 3.5 seconds.
|
||||
if (m_track_intro_sound->getStatus() == SFXBase::SFX_PLAYING &&
|
||||
m_auxiliary_timer < 3.5f)
|
||||
2*m_auxiliary_ticks < 7*stk_config->m_physics_fps)
|
||||
return; // Do not increase time
|
||||
|
||||
// Wait before ready phase if sounds are disabled
|
||||
if (!UserConfigParams::m_sfx && m_auxiliary_timer < 3.0f)
|
||||
if (!UserConfigParams::m_sfx &&
|
||||
m_auxiliary_ticks < 3*stk_config->m_physics_fps )
|
||||
return;
|
||||
|
||||
if (!m_play_track_intro_sound)
|
||||
{
|
||||
startEngines();
|
||||
if (m_auxiliary_timer < 3.0f)
|
||||
if (m_auxiliary_ticks < 3*stk_config->m_physics_fps)
|
||||
return; // Do not increase time
|
||||
}
|
||||
|
||||
m_auxiliary_timer = 0.0f;
|
||||
m_auxiliary_ticks = 0;
|
||||
|
||||
if (m_play_ready_set_go_sounds)
|
||||
m_prestart_sound->play();
|
||||
@ -268,7 +271,7 @@ void WorldStatus::updateTime(const float dt)
|
||||
case READY_PHASE:
|
||||
startEngines();
|
||||
|
||||
if (m_auxiliary_timer > 1.0)
|
||||
if (m_auxiliary_ticks > stk_config->m_physics_fps)
|
||||
{
|
||||
if (m_play_ready_set_go_sounds)
|
||||
{
|
||||
@ -278,7 +281,7 @@ void WorldStatus::updateTime(const float dt)
|
||||
m_phase = SET_PHASE;
|
||||
}
|
||||
|
||||
m_auxiliary_timer += dt;
|
||||
m_auxiliary_ticks++;
|
||||
|
||||
// In artist debug mode, when without opponents, skip the
|
||||
// ready/set/go counter faster
|
||||
@ -287,12 +290,12 @@ void WorldStatus::updateTime(const float dt)
|
||||
race_manager->getNumSpareTireKarts() == 1 &&
|
||||
race_manager->getTrackName() != "tutorial")
|
||||
{
|
||||
m_auxiliary_timer += dt*6;
|
||||
m_auxiliary_ticks += 6;
|
||||
}
|
||||
|
||||
return; // Do not increase time
|
||||
case SET_PHASE:
|
||||
if (m_auxiliary_timer > 2.0)
|
||||
if (m_auxiliary_ticks > 2*stk_config->m_physics_fps)
|
||||
{
|
||||
// set phase is over, go to the next one
|
||||
m_phase = GO_PHASE;
|
||||
@ -305,7 +308,7 @@ void WorldStatus::updateTime(const float dt)
|
||||
onGo();
|
||||
}
|
||||
|
||||
m_auxiliary_timer += dt;
|
||||
m_auxiliary_ticks++;
|
||||
|
||||
// In artist debug mode, when without opponents,
|
||||
// skip the ready/set/go counter faster
|
||||
@ -314,24 +317,25 @@ void WorldStatus::updateTime(const float dt)
|
||||
race_manager->getNumSpareTireKarts() == 1 &&
|
||||
race_manager->getTrackName() != "tutorial")
|
||||
{
|
||||
m_auxiliary_timer += dt*6;
|
||||
m_auxiliary_ticks += 6;
|
||||
}
|
||||
|
||||
return; // Do not increase time
|
||||
case GO_PHASE :
|
||||
|
||||
if (m_auxiliary_timer>2.5f && music_manager->getCurrentMusic() &&
|
||||
// 2.5 seconds
|
||||
if (2*m_auxiliary_ticks>5*stk_config->m_physics_fps &&
|
||||
music_manager->getCurrentMusic() &&
|
||||
!music_manager->getCurrentMusic()->isPlaying())
|
||||
{
|
||||
music_manager->startMusic();
|
||||
}
|
||||
|
||||
if (m_auxiliary_timer > 3.0f) // how long to display the 'go' message
|
||||
// how long to display the 'go' message
|
||||
if (m_auxiliary_ticks > 3 * stk_config->m_physics_fps)
|
||||
{
|
||||
m_phase = MUSIC_PHASE;
|
||||
}
|
||||
|
||||
m_auxiliary_timer += dt;
|
||||
m_auxiliary_ticks++;
|
||||
|
||||
// In artist debug mode, when without opponents,
|
||||
// skip the ready/set/go counter faster
|
||||
@ -340,7 +344,7 @@ void WorldStatus::updateTime(const float dt)
|
||||
race_manager->getNumSpareTireKarts() == 1 &&
|
||||
race_manager->getTrackName() != "tutorial")
|
||||
{
|
||||
m_auxiliary_timer += dt*6;
|
||||
m_auxiliary_ticks += 6;
|
||||
}
|
||||
|
||||
break; // Now the world time starts
|
||||
@ -352,12 +356,13 @@ void WorldStatus::updateTime(const float dt)
|
||||
UserConfigParams::m_race_now = false;
|
||||
}
|
||||
// how long to display the 'music' message
|
||||
if (m_auxiliary_timer>stk_config->m_music_credit_time)
|
||||
if (m_auxiliary_ticks > stk_config->m_music_credit_time
|
||||
* stk_config->m_physics_fps )
|
||||
{
|
||||
m_phase = RACE_PHASE;
|
||||
}
|
||||
|
||||
m_auxiliary_timer += dt;
|
||||
m_auxiliary_ticks++;
|
||||
break;
|
||||
case RACE_PHASE:
|
||||
// Nothing to do for race phase, switch to delay finish phase
|
||||
@ -365,10 +370,11 @@ void WorldStatus::updateTime(const float dt)
|
||||
break;
|
||||
case DELAY_FINISH_PHASE:
|
||||
{
|
||||
m_auxiliary_timer += dt;
|
||||
m_auxiliary_ticks++;
|
||||
|
||||
// Change to next phase if delay is over
|
||||
if (m_auxiliary_timer > stk_config->m_delay_finish_time)
|
||||
if (m_auxiliary_ticks > stk_config->m_delay_finish_time
|
||||
* stk_config->m_physics_fps )
|
||||
{
|
||||
m_phase = RESULT_DISPLAY_PHASE;
|
||||
terminateRace();
|
||||
@ -396,26 +402,29 @@ void WorldStatus::updateTime(const float dt)
|
||||
case CLOCK_CHRONO:
|
||||
if (!device->getTimer()->isStopped())
|
||||
{
|
||||
m_time += dt;
|
||||
m_count_up_timer += dt;
|
||||
m_time_ticks++;
|
||||
m_time = float(m_time_ticks) / stk_config->m_physics_fps;
|
||||
m_count_up_ticks++;
|
||||
}
|
||||
break;
|
||||
case CLOCK_COUNTDOWN:
|
||||
// stop countdown when race is over
|
||||
if (m_phase == RESULT_DISPLAY_PHASE || m_phase == FINISH_PHASE)
|
||||
{
|
||||
m_time_ticks = 0;
|
||||
m_time = 0.0f;
|
||||
m_count_up_timer = 0.0f;
|
||||
m_count_up_ticks = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!device->getTimer()->isStopped())
|
||||
{
|
||||
m_time -= dt;
|
||||
m_count_up_timer += dt;
|
||||
m_time_ticks--;
|
||||
m_time = float(m_time_ticks) / stk_config->m_physics_fps;
|
||||
m_count_up_ticks++;
|
||||
}
|
||||
|
||||
if(m_time <= 0.0)
|
||||
if(m_time_ticks <= 0.0)
|
||||
{
|
||||
// event
|
||||
countdownReachedZero();
|
||||
@ -445,6 +454,7 @@ void WorldStatus::startReadySetGo()
|
||||
*/
|
||||
void WorldStatus::setTime(const float time)
|
||||
{
|
||||
m_time_ticks = time * stk_config->m_physics_fps;
|
||||
m_time = time;
|
||||
} // setTime
|
||||
|
||||
|
@ -91,6 +91,9 @@ protected:
|
||||
/** Elasped/remaining time in seconds. */
|
||||
double m_time;
|
||||
|
||||
/** Time in number of ticks (in terms of physics time steps). */
|
||||
int m_time_ticks;
|
||||
|
||||
/** If the start race should be played, disabled in cutscenes. */
|
||||
bool m_play_racestart_sounds;
|
||||
|
||||
@ -115,15 +118,17 @@ private:
|
||||
/**
|
||||
* Remember previous phase e.g. on pause
|
||||
*/
|
||||
Phase m_previous_phase;
|
||||
Phase m_previous_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;
|
||||
int m_auxiliary_ticks;
|
||||
|
||||
float m_count_up_timer;
|
||||
/** Special counter to count ticks since start (in terms of physics
|
||||
* timestep size). */
|
||||
int m_count_up_ticks;
|
||||
|
||||
bool m_engines_started;
|
||||
void startEngines();
|
||||
@ -180,7 +185,12 @@ public:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current race time. */
|
||||
float getTime() const { return (float)m_time; }
|
||||
float getTime() const { return (float)m_time; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current race time in time ticks (i.e. based on the physics
|
||||
* time step size). */
|
||||
int getTimeTicks() const { return m_time_ticks; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Will be called to notify your derived class that the clock,
|
||||
@ -192,8 +202,8 @@ public:
|
||||
virtual void onGo() {};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the time since start regardless of which way the clock counts */
|
||||
float getTimeSinceStart() const { return m_count_up_timer; }
|
||||
/** Get the ticks since start regardless of which way the clock counts */
|
||||
int getTicksSinceStart() const { return m_count_up_ticks; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setReadyToRace() { m_server_is_ready = true; }
|
||||
|
||||
|
@ -493,7 +493,8 @@ void RaceGUIBase::drawGlobalMusicDescription()
|
||||
|
||||
gui::IGUIFont* font = GUIEngine::getFont();
|
||||
|
||||
float race_time = World::getWorld()->getTimeSinceStart();
|
||||
float race_time = World::getWorld()->getTicksSinceStart()
|
||||
/ stk_config->m_physics_fps;
|
||||
|
||||
// ---- Manage pulsing effect
|
||||
// 3.0 is the duration of ready/set (TODO: don't hardcode)
|
||||
|
Loading…
Reference in New Issue
Block a user