Fix rewind issue of rubber ball
This commit is contained in:
@@ -638,6 +638,7 @@ void Flyable::restoreState(BareNetworkString *buffer, int count)
|
||||
m_body->setAngularVelocity(av);
|
||||
m_body->setInterpolationLinearVelocity(lv);
|
||||
m_body->setInterpolationAngularVelocity(av);
|
||||
setTrans(t);
|
||||
}
|
||||
uint16_t hit_and_ticks = buffer->getUInt16();
|
||||
m_has_hit_something = (hit_and_ticks >> 15) == 1;
|
||||
|
||||
@@ -106,6 +106,7 @@ void RubberBall::additionalPhysicsProperties()
|
||||
// FIXME: what does the rubber ball do in case of battle mode??
|
||||
if(!world) return;
|
||||
|
||||
m_restoring_state = true;
|
||||
computeTarget();
|
||||
|
||||
// initialises the current graph node
|
||||
@@ -197,6 +198,14 @@ void RubberBall::computeTarget()
|
||||
{
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
|
||||
if (m_restoring_state)
|
||||
{
|
||||
// Update kart position from rewind data 1st time
|
||||
world->updateTrackSectors();
|
||||
world->updateRacePosition();
|
||||
m_restoring_state = false;
|
||||
}
|
||||
|
||||
for(unsigned int p = race_manager->getFinishedKarts()+1;
|
||||
p < world->getNumKarts()+1; p++)
|
||||
{
|
||||
@@ -374,6 +383,11 @@ bool RubberBall::updateAndDelete(int ticks)
|
||||
return Flyable::updateAndDelete(ticks);
|
||||
}
|
||||
|
||||
// Update normal from rewind first
|
||||
const Vec3& normal =
|
||||
DriveGraph::get()->getNode(getCurrentGraphNode())->getNormal();
|
||||
TerrainInfo::update(getXYZ(), -normal);
|
||||
|
||||
// Update the target in case that the first kart was overtaken (or has
|
||||
// finished the race).
|
||||
computeTarget();
|
||||
@@ -397,7 +411,7 @@ bool RubberBall::updateAndDelete(int ticks)
|
||||
bool close_to_ground = 2.0*m_previous_height < m_current_max_height;
|
||||
|
||||
float vertical_offset = close_to_ground ? 4.0f : 2.0f;
|
||||
|
||||
|
||||
// Update height of terrain (which isn't done as part of
|
||||
// Flyable::update for rubber balls.
|
||||
TerrainInfo::update(next_xyz + getNormal()*vertical_offset, -getNormal());
|
||||
@@ -482,7 +496,7 @@ void RubberBall::moveTowardsTarget(Vec3 *next_xyz, int ticks)
|
||||
}
|
||||
|
||||
// If ball is close to the target, then explode
|
||||
if (diff.length() < m_target->getKartLength())
|
||||
if (diff.length() < m_target->getKartLength())
|
||||
hit((AbstractKart*)m_target);
|
||||
|
||||
assert(!std::isnan((*next_xyz)[0]));
|
||||
@@ -691,6 +705,10 @@ void RubberBall::updateDistanceToTarget()
|
||||
{
|
||||
m_fast_ping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fast_ping = false;
|
||||
}
|
||||
if(m_distance_to_target < m_st_target_distance &&
|
||||
height_diff < m_st_max_height_difference)
|
||||
{
|
||||
@@ -785,13 +803,10 @@ BareNetworkString* RubberBall::saveState(std::vector<std::string>* ru)
|
||||
buffer->addFloat(m_t);
|
||||
buffer->addFloat(m_t_increase);
|
||||
buffer->addFloat(m_interval);
|
||||
buffer->addUInt8(m_fast_ping ? 1 : 0);
|
||||
buffer->addFloat(m_distance_to_target);
|
||||
buffer->addFloat(m_height_timer);
|
||||
buffer->addUInt32(m_delete_ticks);
|
||||
buffer->addFloat(m_current_max_height);
|
||||
buffer->addUInt8(m_aiming_at_target ? 1 : 0);
|
||||
buffer->addUInt32(m_tunnel_count);
|
||||
buffer->addUInt8(m_tunnel_count | (m_aiming_at_target ? (1 << 7) : 0));
|
||||
TrackSector::saveState(buffer);
|
||||
return buffer;
|
||||
} // saveState
|
||||
@@ -800,6 +815,7 @@ BareNetworkString* RubberBall::saveState(std::vector<std::string>* ru)
|
||||
void RubberBall::restoreState(BareNetworkString *buffer, int count)
|
||||
{
|
||||
Flyable::restoreState(buffer, count);
|
||||
m_restoring_state = true;
|
||||
m_last_aimed_graph_node = buffer->getUInt32();
|
||||
m_control_points[0] = buffer->getVec3();
|
||||
m_control_points[1] = buffer->getVec3();
|
||||
@@ -812,12 +828,11 @@ void RubberBall::restoreState(BareNetworkString *buffer, int count)
|
||||
m_t = buffer->getFloat();
|
||||
m_t_increase = buffer->getFloat();
|
||||
m_interval = buffer->getFloat();
|
||||
m_fast_ping = buffer->getUInt8() == 1;
|
||||
m_distance_to_target = buffer->getFloat();
|
||||
m_height_timer = buffer->getFloat();
|
||||
m_delete_ticks = buffer->getUInt32();
|
||||
m_current_max_height = buffer->getFloat();
|
||||
m_aiming_at_target = buffer->getUInt8() == 1;
|
||||
m_tunnel_count = buffer->getUInt32();
|
||||
uint8_t tunnel_and_aiming = buffer->getUInt8();
|
||||
m_tunnel_count = tunnel_and_aiming & 127;
|
||||
m_aiming_at_target = ((tunnel_and_aiming >> 7) & 1) == 1;
|
||||
TrackSector::rewindTo(buffer);
|
||||
} // restoreState
|
||||
|
||||
@@ -177,7 +177,7 @@ private:
|
||||
/** This variable counts how often a ball tunneled (in consecutive
|
||||
* frames). If a ball tunnels a certain number of times, it is
|
||||
* considered stuck and will be removed. */
|
||||
unsigned int m_tunnel_count;
|
||||
uint8_t m_tunnel_count;
|
||||
|
||||
/** A 'ping' sound effect to be played when the ball hits the ground. */
|
||||
SFXBase *m_ping_sfx;
|
||||
@@ -185,6 +185,8 @@ private:
|
||||
/* Used by undo and redo the firing when rewind */
|
||||
Vec3 m_owner_init_pos, m_init_pos;
|
||||
|
||||
bool m_restoring_state;
|
||||
|
||||
void computeTarget();
|
||||
void updateDistanceToTarget();
|
||||
unsigned int getSuccessorToHitTarget(unsigned int node_index,
|
||||
|
||||
@@ -169,34 +169,10 @@ void LinearWorld::update(int ticks)
|
||||
m_finish_timeout = std::numeric_limits<float>::max();
|
||||
}
|
||||
}
|
||||
const unsigned int kart_amount = getNumKarts();
|
||||
|
||||
// Do stuff specific to this subtype of race.
|
||||
// ------------------------------------------
|
||||
for(unsigned int n=0; n<kart_amount; n++)
|
||||
{
|
||||
KartInfo& kart_info = m_kart_info[n];
|
||||
AbstractKart* kart = m_karts[n].get();
|
||||
|
||||
// Nothing to do for karts that are currently being
|
||||
// rescued or eliminated
|
||||
if(kart->getKartAnimation()) continue;
|
||||
// If the kart is off road, and 'flying' over a reset plane
|
||||
// don't adjust the distance of the kart, to avoid a jump
|
||||
// in the position of the kart (e.g. while falling the kart
|
||||
// might get too close to another part of the track, shortly
|
||||
// jump to position one, then on reset fall back to last)
|
||||
if ((!getTrackSector(n)->isOnRoad() &&
|
||||
(!kart->getMaterial() ||
|
||||
kart->getMaterial()->isDriveReset())) &&
|
||||
!kart->isGhostKart())
|
||||
continue;
|
||||
getTrackSector(n)->update(kart->getFrontXYZ());
|
||||
kart_info.m_overall_distance = kart_info.m_finished_laps
|
||||
* Track::getCurrentTrack()->getTrackLength()
|
||||
+ getDistanceDownTrackForKart(kart->getWorldKartId(), true);
|
||||
} // for n
|
||||
|
||||
updateTrackSectors();
|
||||
// Run generic parent stuff that applies to all modes.
|
||||
// It especially updates the kart positions.
|
||||
// It MUST be done after the update of the distances
|
||||
@@ -209,6 +185,7 @@ void LinearWorld::update(int ticks)
|
||||
WorldWithRank::updateTrack(ticks);
|
||||
updateRacePosition();
|
||||
|
||||
const unsigned int kart_amount = getNumKarts();
|
||||
for (unsigned int i=0; i<kart_amount; i++)
|
||||
{
|
||||
// ---------- update rank ------
|
||||
@@ -251,6 +228,35 @@ void LinearWorld::update(int ticks)
|
||||
#endif
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void LinearWorld::updateTrackSectors()
|
||||
{
|
||||
const unsigned int kart_amount = getNumKarts();
|
||||
for(unsigned int n=0; n<kart_amount; n++)
|
||||
{
|
||||
KartInfo& kart_info = m_kart_info[n];
|
||||
AbstractKart* kart = m_karts[n].get();
|
||||
|
||||
// Nothing to do for karts that are currently being
|
||||
// rescued or eliminated
|
||||
if(kart->getKartAnimation()) continue;
|
||||
// If the kart is off road, and 'flying' over a reset plane
|
||||
// don't adjust the distance of the kart, to avoid a jump
|
||||
// in the position of the kart (e.g. while falling the kart
|
||||
// might get too close to another part of the track, shortly
|
||||
// jump to position one, then on reset fall back to last)
|
||||
if ((!getTrackSector(n)->isOnRoad() &&
|
||||
(!kart->getMaterial() ||
|
||||
kart->getMaterial()->isDriveReset())) &&
|
||||
!kart->isGhostKart())
|
||||
continue;
|
||||
getTrackSector(n)->update(kart->getFrontXYZ());
|
||||
kart_info.m_overall_distance = kart_info.m_finished_laps
|
||||
* Track::getCurrentTrack()->getTrackLength()
|
||||
+ getDistanceDownTrackForKart(kart->getWorldKartId(), true);
|
||||
} // for n
|
||||
} // updateTrackSectors
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This updates all only graphical elements.It is only called once per
|
||||
* rendered frame, not once per time step.
|
||||
|
||||
@@ -124,7 +124,6 @@ protected:
|
||||
AlignedArray<KartInfo> m_kart_info;
|
||||
|
||||
virtual void checkForWrongDirection(unsigned int i, float dt);
|
||||
void updateRacePosition();
|
||||
virtual float estimateFinishTimeForKart(AbstractKart* kart) OVERRIDE;
|
||||
|
||||
public:
|
||||
@@ -139,6 +138,8 @@ public:
|
||||
virtual void updateGraphics(float dt) OVERRIDE;
|
||||
float getDistanceDownTrackForKart(const int kart_id,
|
||||
bool account_for_checklines) const;
|
||||
void updateTrackSectors();
|
||||
void updateRacePosition();
|
||||
float getDistanceToCenterForKart(const int kart_id) const;
|
||||
float getEstimatedFinishTime(const int kart_id) const;
|
||||
int getLapForKart(const int kart_id) const;
|
||||
|
||||
Reference in New Issue
Block a user