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())
{
m_animation->update(stk_config->ticks2Time(ticks));
m_animation->update(ticks);
Moveable::update(ticks);
}
return false;

View File

@ -153,7 +153,7 @@ void AbstractKartAnimation::
{
Log::warn("AbstractKartAnimation",
"No animation has been created on server, remove locally.");
m_timer = -1.0f;
m_timer = -1;
m_end_transform = fallback_trans;
m_ignore_undo = true;
}
@ -165,13 +165,40 @@ void AbstractKartAnimation::
* NOTE: calling this function must be the last thing done in any kart
* animation class, since this object might be deleted, so accessing any
* 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
m_timer -= dt;
if(m_timer<0)
m_timer -= ticks;
if (m_timer < 0)
{
if(m_kart) m_kart->setKartAnimation(NULL);
delete this;

View File

@ -21,6 +21,7 @@
#include "LinearMath/btTransform.h"
#include "config/stk_config.hpp"
#include "utils/no_copy.hpp"
#include "utils/vec3.hpp"
@ -56,8 +57,8 @@ protected:
/** A pointer to the kart which is animated by this class. */
AbstractKart *m_kart;
/** Timer for the explosion. */
float m_timer;
/** Timer for the animation. */
int m_timer;
btTransform m_end_transform;
@ -69,22 +70,25 @@ public:
AbstractKartAnimation(AbstractKart *kart,
const std::string &name);
virtual ~AbstractKartAnimation();
virtual void update(float dt);
virtual void update(int ticks);
// ------------------------------------------------------------------------
/** 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.
* Used in AstractKart in case of an incorrect sequence of calls. */
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; }
// ------------------------------------------------------------------------
void setEndTransformTicks(const btTransform& t, int ticks)
{
if (!useEarlyEndTransform())
if (!usePredefinedEndTransform() || m_confirmed_by_network)
return;
m_confirmed_by_network = true;
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)
{
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
// -------------------------------------------------------------
@ -214,25 +214,25 @@ CannonAnimation::~CannonAnimation()
// ----------------------------------------------------------------------------
/** Updates the kart animation.
* \param dt Time step size.
* \return True if the explosion is still shown, false if it has finished.
* \param ticks Number of time steps - should be 1.
*/
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;
}
AbstractKartAnimation::update(dt);
AbstractKartAnimation::update(ticks);
// First compute the current rotation
// ==================================
// Get the tangent = derivative at the current point to compute the
// new orientation of the kart
Vec3 tangent;
m_curve->getDerivativeAt(m_curve->getAnimationDuration() - m_timer,
&tangent);
m_curve->getDerivativeAt(m_curve->getAnimationDuration() -
getAnimationTimer(), &tangent);
// Get the current kart orientation
const btTransform &trans = m_kart ? m_kart->getTrans()
: m_flyable->getBody()->getWorldTransform();
@ -275,7 +275,7 @@ void CannonAnimation::update(float dt)
// forward direction.
// 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
+ m_end_line_length * (1.0f - f);

View File

@ -79,8 +79,8 @@ public:
const Vec3 &start_left, const Vec3 &start_right,
const Vec3 &end_left, const Vec3 &end_right);
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
#endif

View File

@ -80,16 +80,20 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
m_orig_xyz = m_xyz;
m_normal = m_kart->getNormal();
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.
if(!direct_hit) m_timer*=0.5f;
if (!direct_hit)
{
timer *= 0.5f;
m_timer /= 2;
}
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isServer())
{
m_end_ticks = stk_config->time2Ticks(m_timer) + World::getWorld()
->getTicksSinceStart();
m_end_ticks = m_timer + World::getWorld()->getTicksSinceStart() + 1;
}
// Half of the overall time is spent in raising, so only use
// 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
// the right initial velocity for a kart to land back after
// 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.setPitch(m_kart->getPitch());
@ -107,7 +111,7 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
const int max_rotation = direct_hit ? 2 : 1;
// To get rotations in both directions for each axis we determine a random
// 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.setPitch( (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.
* \param dt Time step size.
* \return True if the explosion is still shown, false if it has finished.
* \param ticks Number of time steps - should be 1.
*/
void ExplosionAnimation::update(float dt)
void ExplosionAnimation::update(int ticks)
{
float dt = stk_config->ticks2Time(ticks);
m_velocity -= dt*Track::getCurrentTrack()->getGravity();
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)
{
m_xyz = m_orig_xyz;
// This will trigger the end of the animations
m_timer = -1;
// Don't end the animation if networking for predefined end transform
if (!NetworkConfig::get()->isNetworking())
m_timer = -1;
}
m_kart->setXYZ(m_xyz);
m_curr_rotation += dt*m_add_rotation;
@ -164,5 +169,5 @@ void ExplosionAnimation::update(float dt)
m_curr_rotation.getRoll());
m_kart->setRotation(q);
AbstractKartAnimation::update(dt);
AbstractKartAnimation::update(ticks);
} // update

View File

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

View File

@ -1302,12 +1302,12 @@ void Kart::update(int ticks)
// before updating the graphical position (which is done in
// Moveable::update() ), otherwise 'stuttering' can happen (caused by
// graphical and physical position not being the same).
float dt = stk_config->ticks2Time(ticks);
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())
{
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);
// m_invulnerable_ticks will not be negative
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) |
(has_animation ? 1 << 14 : 0) | m_invulnerable_ticks;
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_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_xyz = m_kart->getXYZ();
m_orig_rotation = m_kart->getRotation();
@ -66,8 +68,7 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isServer())
{
m_end_ticks = stk_config->time2Ticks(m_timer) + World::getWorld()
->getTicksSinceStart();
m_end_ticks = m_timer + World::getWorld()->getTicksSinceStart() + 1;
}
// Determine maximum rescue height with up-raycast
@ -75,7 +76,7 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
float hit_dest = maximumHeight();
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
// up direction to the right up direction it should have according to
@ -152,12 +153,12 @@ float RescueAnimation::maximumHeight()
// ----------------------------------------------------------------------------
/** Updates the kart animation.
* \param dt Time step size.
* \return True if the explosion is still shown, false if it has finished.
* \param ticks Number of time steps - should be 1.
*/
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)
{
@ -166,7 +167,8 @@ void RescueAnimation::update(float dt)
m_kart->setTrans(m_end_transform);
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 &&
dynamic_cast<CameraNormal*>(camera))
{
@ -179,7 +181,8 @@ void RescueAnimation::update(float dt)
m_xyz = m_kart->getXYZ();
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;
}
@ -192,6 +195,6 @@ void RescueAnimation::update(float dt)
m_kart->setXYZ(m_xyz);
}
AbstractKartAnimation::update(dt);
AbstractKartAnimation::update(ticks);
} // update

View File

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