Scale the timer according to m_end_ticks told by server if necessary

This commit is contained in:
Benau 2018-08-20 11:39:31 +08:00
parent 1e0a4dc1aa
commit eca9ffb508
11 changed files with 93 additions and 55 deletions

View File

@ -406,7 +406,7 @@ bool Flyable::updateAndDelete(int ticks)
{ {
if (!RewindManager::get()->isRewinding()) if (!RewindManager::get()->isRewinding())
{ {
m_animation->update(stk_config->ticks2Time(ticks)); m_animation->update(ticks);
Moveable::update(ticks); Moveable::update(ticks);
} }
return false; return false;

View File

@ -153,7 +153,7 @@ void AbstractKartAnimation::
{ {
Log::warn("AbstractKartAnimation", Log::warn("AbstractKartAnimation",
"No animation has been created on server, remove locally."); "No animation has been created on server, remove locally.");
m_timer = -1.0f; m_timer = -1;
m_end_transform = fallback_trans; m_end_transform = fallback_trans;
m_ignore_undo = true; m_ignore_undo = true;
} }
@ -165,13 +165,40 @@ void AbstractKartAnimation::
* NOTE: calling this function must be the last thing done in any kart * NOTE: calling this function must be the last thing done in any kart
* animation class, since this object might be deleted, so accessing any * animation class, since this object might be deleted, so accessing any
* members might be invalid. * members might be invalid.
* \param dt Time step size. * \param ticks Number of time steps - should be 1.
*/ */
void AbstractKartAnimation::update(float dt) void AbstractKartAnimation::update(int ticks)
{ {
// Scale the timer according to m_end_ticks told by server if
// necessary
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient() &&
World::getWorld()->getPhase() == World::RACE_PHASE &&
usePredefinedEndTransform() && m_end_ticks != -1)
{
int cur_end_ticks = World::getWorld()->getTicksSinceStart() +
m_timer;
const int difference = cur_end_ticks - m_end_ticks;
if (World::getWorld()->getTicksSinceStart() > m_end_ticks)
{
// Stop right now
m_timer = -1;
}
else if (difference > 0)
{
// Speed up
m_timer -= ticks;
}
else if (difference < 0)
{
// Slow down
return;
}
}
// See if the timer expires, if so return the kart to normal game play // See if the timer expires, if so return the kart to normal game play
m_timer -= dt; m_timer -= ticks;
if(m_timer<0) if (m_timer < 0)
{ {
if(m_kart) m_kart->setKartAnimation(NULL); if(m_kart) m_kart->setKartAnimation(NULL);
delete this; delete this;

View File

@ -21,6 +21,7 @@
#include "LinearMath/btTransform.h" #include "LinearMath/btTransform.h"
#include "config/stk_config.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
@ -56,8 +57,8 @@ protected:
/** A pointer to the kart which is animated by this class. */ /** A pointer to the kart which is animated by this class. */
AbstractKart *m_kart; AbstractKart *m_kart;
/** Timer for the explosion. */ /** Timer for the animation. */
float m_timer; int m_timer;
btTransform m_end_transform; btTransform m_end_transform;
@ -69,22 +70,25 @@ public:
AbstractKartAnimation(AbstractKart *kart, AbstractKartAnimation(AbstractKart *kart,
const std::string &name); const std::string &name);
virtual ~AbstractKartAnimation(); virtual ~AbstractKartAnimation();
virtual void update(float dt); virtual void update(int ticks);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the current animation timer. */ /** Returns the current animation timer. */
virtual float getAnimationTimer() const { return m_timer; } virtual float getAnimationTimer() const
{ return stk_config->ticks2Time(m_timer); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** To easily allow printing the name of the animation being used atm. /** To easily allow printing the name of the animation being used atm.
* Used in AstractKart in case of an incorrect sequence of calls. */ * Used in AstractKart in case of an incorrect sequence of calls. */
virtual const std::string &getName() const { return m_name; } virtual const std::string &getName() const { return m_name; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual bool useEarlyEndTransform() const { return true; } /** If true, the end transform can be determined early, used in network for
* for client to synchronize with server. */
virtual bool usePredefinedEndTransform() const { return true; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
const btTransform& getEndTransform() const { return m_end_transform; } const btTransform& getEndTransform() const { return m_end_transform; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setEndTransformTicks(const btTransform& t, int ticks) void setEndTransformTicks(const btTransform& t, int ticks)
{ {
if (!useEarlyEndTransform()) if (!usePredefinedEndTransform() || m_confirmed_by_network)
return; return;
m_confirmed_by_network = true; m_confirmed_by_network = true;
m_end_transform = t; m_end_transform = t;

View File

@ -81,7 +81,7 @@ void CannonAnimation::init(Ipo *ipo, const Vec3 &start_left,
const Vec3 &end_right, float skid_rot) const Vec3 &end_right, float skid_rot)
{ {
m_curve = new AnimationBase(ipo); m_curve = new AnimationBase(ipo);
m_timer = ipo->getEndTime(); m_timer = stk_config->time2Ticks(ipo->getEndTime());
// First make sure that left and right points are indeed correct // First make sure that left and right points are indeed correct
// ------------------------------------------------------------- // -------------------------------------------------------------
@ -214,25 +214,25 @@ CannonAnimation::~CannonAnimation()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Updates the kart animation. /** Updates the kart animation.
* \param dt Time step size. * \param ticks Number of time steps - should be 1.
* \return True if the explosion is still shown, false if it has finished.
*/ */
void CannonAnimation::update(float dt) void CannonAnimation::update(int ticks)
{ {
if(m_timer < dt) float dt = stk_config->ticks2Time(ticks);
if (m_timer < ticks)
{ {
AbstractKartAnimation::update(dt); AbstractKartAnimation::update(ticks);
return; return;
} }
AbstractKartAnimation::update(dt); AbstractKartAnimation::update(ticks);
// First compute the current rotation // First compute the current rotation
// ================================== // ==================================
// Get the tangent = derivative at the current point to compute the // Get the tangent = derivative at the current point to compute the
// new orientation of the kart // new orientation of the kart
Vec3 tangent; Vec3 tangent;
m_curve->getDerivativeAt(m_curve->getAnimationDuration() - m_timer, m_curve->getDerivativeAt(m_curve->getAnimationDuration() -
&tangent); getAnimationTimer(), &tangent);
// Get the current kart orientation // Get the current kart orientation
const btTransform &trans = m_kart ? m_kart->getTrans() const btTransform &trans = m_kart ? m_kart->getTrans()
: m_flyable->getBody()->getWorldTransform(); : m_flyable->getBody()->getWorldTransform();
@ -275,7 +275,7 @@ void CannonAnimation::update(float dt)
// forward direction. // forward direction.
// The timer counts backwards, so the fraction goes from 1 to 0 // The timer counts backwards, so the fraction goes from 1 to 0
float f = m_timer / m_curve->getAnimationDuration(); float f = getAnimationTimer() / m_curve->getAnimationDuration();
float f_current_width = m_start_line_length * f float f_current_width = m_start_line_length * f
+ m_end_line_length * (1.0f - f); + m_end_line_length * (1.0f - f);

View File

@ -79,8 +79,8 @@ public:
const Vec3 &start_left, const Vec3 &start_right, const Vec3 &start_left, const Vec3 &start_right,
const Vec3 &end_left, const Vec3 &end_right); const Vec3 &end_left, const Vec3 &end_right);
virtual ~CannonAnimation(); virtual ~CannonAnimation();
virtual void update(float dt); virtual void update(int ticks);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual bool useEarlyEndTransform() const { return false; } virtual bool usePredefinedEndTransform() const { return false; }
}; // CannonAnimation }; // CannonAnimation
#endif #endif

View File

@ -80,16 +80,20 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
m_orig_xyz = m_xyz; m_orig_xyz = m_xyz;
m_normal = m_kart->getNormal(); m_normal = m_kart->getNormal();
m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE); m_kart->playCustomSFX(SFXManager::CUSTOM_EXPLODE);
m_timer = m_kart->getKartProperties()->getExplosionDuration(); float timer = m_kart->getKartProperties()->getExplosionDuration();
m_timer = stk_config->time2Ticks(timer);
// Non-direct hits will be only affected half as much. // Non-direct hits will be only affected half as much.
if(!direct_hit) m_timer*=0.5f; if (!direct_hit)
{
timer *= 0.5f;
m_timer /= 2;
}
if (NetworkConfig::get()->isNetworking() && if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isServer()) NetworkConfig::get()->isServer())
{ {
m_end_ticks = stk_config->time2Ticks(m_timer) + World::getWorld() m_end_ticks = m_timer + World::getWorld()->getTicksSinceStart() + 1;
->getTicksSinceStart();
} }
// Half of the overall time is spent in raising, so only use // Half of the overall time is spent in raising, so only use
// half of the explosion time here. // half of the explosion time here.
@ -98,7 +102,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
// Since v(explosion_time*0.5) = 0, the following forumla computes // Since v(explosion_time*0.5) = 0, the following forumla computes
// the right initial velocity for a kart to land back after // the right initial velocity for a kart to land back after
// the specified time. // the specified time.
m_velocity = 0.5f * m_timer * Track::getCurrentTrack()->getGravity(); m_velocity = 0.5f * timer * Track::getCurrentTrack()->getGravity();
m_curr_rotation.setHeading(m_kart->getHeading()); m_curr_rotation.setHeading(m_kart->getHeading());
m_curr_rotation.setPitch(m_kart->getPitch()); m_curr_rotation.setPitch(m_kart->getPitch());
@ -107,7 +111,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
const int max_rotation = direct_hit ? 2 : 1; const int max_rotation = direct_hit ? 2 : 1;
// To get rotations in both directions for each axis we determine a random // To get rotations in both directions for each axis we determine a random
// number between -(max_rotation-1) and +(max_rotation-1) // number between -(max_rotation-1) and +(max_rotation-1)
float f=2.0f*M_PI/m_timer; float f = 2.0f * M_PI / timer;
m_add_rotation.setHeading( (rand()%(2*max_rotation+1)-max_rotation)*f ); m_add_rotation.setHeading( (rand()%(2*max_rotation+1)-max_rotation)*f );
m_add_rotation.setPitch( (rand()%(2*max_rotation+1)-max_rotation)*f ); m_add_rotation.setPitch( (rand()%(2*max_rotation+1)-max_rotation)*f );
m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f ); m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f );
@ -143,11 +147,11 @@ ExplosionAnimation::~ExplosionAnimation()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Updates the kart animation. /** Updates the kart animation.
* \param dt Time step size. * \param ticks Number of time steps - should be 1.
* \return True if the explosion is still shown, false if it has finished.
*/ */
void ExplosionAnimation::update(float dt) void ExplosionAnimation::update(int ticks)
{ {
float dt = stk_config->ticks2Time(ticks);
m_velocity -= dt*Track::getCurrentTrack()->getGravity(); m_velocity -= dt*Track::getCurrentTrack()->getGravity();
m_xyz = m_xyz + dt*m_velocity*m_normal; m_xyz = m_xyz + dt*m_velocity*m_normal;
@ -155,8 +159,9 @@ void ExplosionAnimation::update(float dt)
if ((m_xyz - m_orig_xyz).dot(m_normal)<0) if ((m_xyz - m_orig_xyz).dot(m_normal)<0)
{ {
m_xyz = m_orig_xyz; m_xyz = m_orig_xyz;
// This will trigger the end of the animations // Don't end the animation if networking for predefined end transform
m_timer = -1; if (!NetworkConfig::get()->isNetworking())
m_timer = -1;
} }
m_kart->setXYZ(m_xyz); m_kart->setXYZ(m_xyz);
m_curr_rotation += dt*m_add_rotation; m_curr_rotation += dt*m_add_rotation;
@ -164,5 +169,5 @@ void ExplosionAnimation::update(float dt)
m_curr_rotation.getRoll()); m_curr_rotation.getRoll());
m_kart->setRotation(q); m_kart->setRotation(q);
AbstractKartAnimation::update(dt); AbstractKartAnimation::update(ticks);
} // update } // update

View File

@ -73,6 +73,6 @@ public:
static ExplosionAnimation *create(AbstractKart *kart); static ExplosionAnimation *create(AbstractKart *kart);
virtual ~ExplosionAnimation(); virtual ~ExplosionAnimation();
virtual void update(float dt); virtual void update(int ticks);
}; // ExplosionAnimation }; // ExplosionAnimation
#endif #endif

View File

@ -1302,12 +1302,12 @@ void Kart::update(int ticks)
// before updating the graphical position (which is done in // before updating the graphical position (which is done in
// Moveable::update() ), otherwise 'stuttering' can happen (caused by // Moveable::update() ), otherwise 'stuttering' can happen (caused by
// graphical and physical position not being the same). // graphical and physical position not being the same).
float dt = stk_config->ticks2Time(ticks);
if (has_animation_before && !RewindManager::get()->isRewinding()) if (has_animation_before && !RewindManager::get()->isRewinding())
{ {
m_kart_animation->update(dt); m_kart_animation->update(ticks);
} }
float dt = stk_config->ticks2Time(ticks);
if (!RewindManager::get()->isRewinding()) if (!RewindManager::get()->isRewinding())
{ {
m_time_previous_counter += dt; m_time_previous_counter += dt;

View File

@ -123,7 +123,7 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
buffer->addUInt16(m_view_blocked_by_plunger); buffer->addUInt16(m_view_blocked_by_plunger);
// m_invulnerable_ticks will not be negative // m_invulnerable_ticks will not be negative
AbstractKartAnimation* ka = getKartAnimation(); AbstractKartAnimation* ka = getKartAnimation();
bool has_animation = ka != NULL && ka->useEarlyEndTransform(); bool has_animation = ka != NULL && ka->usePredefinedEndTransform();
uint16_t fire_and_invulnerable = (m_fire_clicked ? 1 << 15 : 0) | uint16_t fire_and_invulnerable = (m_fire_clicked ? 1 << 15 : 0) |
(has_animation ? 1 << 14 : 0) | m_invulnerable_ticks; (has_animation ? 1 << 14 : 0) | m_invulnerable_ticks;
buffer->addUInt16(fire_and_invulnerable); buffer->addUInt16(fire_and_invulnerable);

View File

@ -57,7 +57,9 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
m_referee = new Referee(*m_kart); m_referee = new Referee(*m_kart);
m_kart->getNode()->addChild(m_referee->getSceneNode()); m_kart->getNode()->addChild(m_referee->getSceneNode());
m_timer = m_kart->getKartProperties()->getRescueDuration(); float timer = m_kart->getKartProperties()->getRescueDuration();
m_rescue_moment = stk_config->time2Ticks(timer * 0.6f);
m_timer = stk_config->time2Ticks(timer);
m_up_vector = m_kart->getTrans().getBasis().getColumn(1); m_up_vector = m_kart->getTrans().getBasis().getColumn(1);
m_xyz = m_kart->getXYZ(); m_xyz = m_kart->getXYZ();
m_orig_rotation = m_kart->getRotation(); m_orig_rotation = m_kart->getRotation();
@ -66,8 +68,7 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
if (NetworkConfig::get()->isNetworking() && if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isServer()) NetworkConfig::get()->isServer())
{ {
m_end_ticks = stk_config->time2Ticks(m_timer) + World::getWorld() m_end_ticks = m_timer + World::getWorld()->getTicksSinceStart() + 1;
->getTicksSinceStart();
} }
// Determine maximum rescue height with up-raycast // Determine maximum rescue height with up-raycast
@ -75,7 +76,7 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
float hit_dest = maximumHeight(); float hit_dest = maximumHeight();
max_height = std::min(hit_dest, max_height); max_height = std::min(hit_dest, max_height);
m_velocity = max_height / m_timer; m_velocity = max_height / timer;
// Determine the rotation that will rotate the kart from the current // Determine the rotation that will rotate the kart from the current
// up direction to the right up direction it should have according to // up direction to the right up direction it should have according to
@ -152,12 +153,12 @@ float RescueAnimation::maximumHeight()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Updates the kart animation. /** Updates the kart animation.
* \param dt Time step size. * \param ticks Number of time steps - should be 1.
* \return True if the explosion is still shown, false if it has finished.
*/ */
void RescueAnimation::update(float dt) void RescueAnimation::update(int ticks)
{ {
if (m_timer <= (m_kart->getKartProperties()->getRescueDuration() * rescue_moment)) float dt = stk_config->ticks2Time(ticks);
if (m_timer <= m_rescue_moment)
{ {
if (m_kart_on_track == false) if (m_kart_on_track == false)
{ {
@ -166,7 +167,8 @@ void RescueAnimation::update(float dt)
m_kart->setTrans(m_end_transform); m_kart->setTrans(m_end_transform);
for (unsigned int i = 0; i < Camera::getNumCameras(); i++) for (unsigned int i = 0; i < Camera::getNumCameras(); i++)
{ {
CameraNormal* camera = dynamic_cast<CameraNormal*>(Camera::getCamera(i)); CameraNormal* camera =
dynamic_cast<CameraNormal*>(Camera::getCamera(i));
if (camera && camera->getKart() == m_kart && if (camera && camera->getKart() == m_kart &&
dynamic_cast<CameraNormal*>(camera)) dynamic_cast<CameraNormal*>(camera))
{ {
@ -179,7 +181,8 @@ void RescueAnimation::update(float dt)
m_xyz = m_kart->getXYZ(); m_xyz = m_kart->getXYZ();
float hit_dest = maximumHeight(); float hit_dest = maximumHeight();
float max_height = std::min(hit_dest, m_kart->getKartProperties()->getRescueHeight()) * rescue_moment; float max_height = std::min(hit_dest,
m_kart->getKartProperties()->getRescueHeight()) * 0.6f;
m_xyz += max_height * m_up_vector; m_xyz += max_height * m_up_vector;
} }
@ -192,6 +195,6 @@ void RescueAnimation::update(float dt)
m_kart->setXYZ(m_xyz); m_kart->setXYZ(m_xyz);
} }
AbstractKartAnimation::update(dt); AbstractKartAnimation::update(ticks);
} // update } // update

View File

@ -46,9 +46,8 @@ protected:
/** The velocity with which the kart is moved. */ /** The velocity with which the kart is moved. */
float m_velocity; float m_velocity;
/* At what percent of the animation should the kart be on the track*/ int m_rescue_moment;
/*0.75 means that for 3 quaters of the animation it'll be on track*/
const float rescue_moment = 0.6F;
/* Has the kart been moved onto the track */ /* Has the kart been moved onto the track */
bool m_kart_on_track = false; bool m_kart_on_track = false;
@ -59,6 +58,6 @@ public:
RescueAnimation(AbstractKart *kart, bool is_auto_rescue=false); RescueAnimation(AbstractKart *kart, bool is_auto_rescue=false);
float maximumHeight(); float maximumHeight();
virtual ~RescueAnimation(); virtual ~RescueAnimation();
virtual void update(float dt); virtual void update(int ticks);
}; // RescueAnimation }; // RescueAnimation
#endif #endif